从文本字段中求解数学方程

时间:2011-03-25 19:46:00

标签: objective-c c

我正在尝试提高update()的性能;功能如下。 mathNumber变量中的数字将来自从文本字段创建的NSString。即使我使用五个数字,我希望它能够运行用户插入文本字段的任何数量。有什么方法可以加快update()中的代码;用C和/或Objective-C?我也希望它可以在Mac和iPhone上运行。

typedef struct {
    float *left;
    float *right;
    float *equals;
    int operation;
} MathVariable;

#define MULTIPLY 1
#define DIVIDE 2
#define ADD 3
#define SUBTRACT 4

MathVariable *mathVariable;
float *mathPointer;
float newNumber;

void init();
void update();
float solution(float *left, float *right, int *operation);

void init()
{
    float *mathNumber = (float *) malloc(sizeof(float) * 9);

    mathNumber[0] =-1.0;
    mathNumber[1] =-2.0;
    mathNumber[2] = 3.0;
    mathNumber[3] = 4.0;
    mathNumber[4] = 5.0;
    mathNumber[5] = 0.0;
    mathNumber[6] = 0.0;
    mathNumber[7] = 0.0;
    mathNumber[8] = 0.0;

    mathVariable = (MathVariable *) malloc(sizeof(MathVariable) * 4);

    mathVariable[0].equals = &mathPointer[5];
    mathVariable[0].left = &mathPointer[2];
    mathVariable[0].operation = MULTIPLY;
    mathVariable[0].right = &mathPointer[3];

    mathVariable[1].equals = &mathPointer[6];
    mathVariable[1].left = &mathPointer[1];
    mathVariable[1].operation = SUBTRACT;
    mathVariable[1].right = &mathPointer[5];

    mathVariable[2].equals = &mathPointer[7];
    mathVariable[2].left = &mathPointer[0];
    mathVariable[2].operation = ADD;
    mathVariable[2].right = &mathPointer[6];

    mathVariable[3].equals = &mathPointer[8];
    mathVariable[3].left = &mathPointer[7];
    mathVariable[3].operation = MULTIPLY;
    mathVariable[3].right = &mathPointer[4];

    return self;
}

// This is updated with a timer
void update()
{   
    int i;

    for (i = 0; i < 4; i++)
    {
        *mathVariable[i].equals = solution(mathVariable[i].left, mathVariable[i].right, &mathVariable[i].operation);
    }

    // Below is the equivalent of: newNumber = (-1.0 + (-2.0 - 3.0 * 4.0)) * 5.0;
    // newNumber should equal -75
    newNumber = mathPointer[8];
}

float solution(float *left, float *right, int *operation)
{
    if ((*operation) == MULTIPLY)
    {
        return (*left) * (*right);
    }
    else if ((*operation) == DIVIDE)
    {
        return (*left) / (*right);
    }
    else if ((*operation) == ADD)
    {
        return (*left) + (*right);
    }
    else if ((*operation) == SUBTRACT)
    {
        return (*left) - (*right);
    }
    else
    {
        return 0.0;
    }
}

编辑:

我首先要感谢你所有的帖子。这是我得到的第一个没有人告诉我我是一个完全白痴的人。抱歉回归自我;我没有意识到这也是一个客观的C论坛(因此我为什么匆匆使用C)。我有自己的解析器很慢,但我并不关心它的速度。我想要的只是加速update()函数,因为它减慢了一切,90%的对象使用它。此外,我试图让它与iOS设备更快地工作,因为我无法在文本框中编译任何东西。如果您对更新()的任何其他建议更快,我感谢您。

再次感谢, 乔纳森

编辑2:

嗯,我通过更改它来快速运行:

int i;

for (i = 0; i < 4; i++)
{
*mathVariable[i].equals = solution(*mathVariable[i].left, *mathVariable[i].right, mathVariable[i].operation);
}

要:

*mathVariable[0].equals = solution(*mathVariable[0].left, *mathVariable[0].right, mathVariable[0].operation);
*mathVariable[1].equals = solution(*mathVariable[1].left, *mathVariable[1].right, mathVariable[1].operation);
*mathVariable[2].equals = solution(*mathVariable[2].left, *mathVariable[2].right, mathVariable[2].operation);
*mathVariable[3].equals = solution(*mathVariable[3].left, *mathVariable[3].right, mathVariable[3].operation);

还有其他方法可以像上面的数组一样快速增加它吗?

1 个答案:

答案 0 :(得分:0)

您的代码是各种样式的混合,并且包含对指针的一些无根据的使用(例如,将operation传递给solution时)。目前还不清楚为什么你通过引用传递浮点数,但也许你打算改变这些变化并重新评估表达式?

以下是一些变化,无论是整洁还是偶然加快 - 其中任何一项成本都不高,您可能会对过早优化感到内疚。正如@Dave评论的那样,有些库可以为你解析,但如果你的目标是简单的数学表达式,那么基于运算符优先级的基于堆栈的解析器/求值器就很容易编码。

建议1:使用enum - 清洁:

typedef enum { MULTIPLY, DIVIDE, ADD, SUBTRACT } BinaryOp;

typedef struct
{
    float *left;
    float *right;
    float *equals;
    BinaryOp operation;
} MathVariable;

建议2:使用switch - 更清洁,也可能更快:

float solution(float left, float right, int operation)
{
    switch(operation)
    {
        case MULTIPLY:
            return left * right;
        case DIVIDE:
            return left / right;
        case ADD:
            return left + right;
        case SUBTRACT:
            return left - right;
        default:
            return 0.0;
    }
}

注意我也删除了传递指针,现在调用:

*mathVariable[i].equals = solution(*mathVariable[i].left,
                                   *mathVariable[i].right,
                                   mathVariable[i].operation);

现在一个OO人可能会对switch(或if / else)反对(:-)),并争辩每个节点(你的MathVariable)应该是一个知道如何执行自己的操作的实例。 C人可能会建议您在节点中使用函数指针,以便他们可以执行自己的操作。所有这些都是设计,你必须自己解决这个问题。