重新排列计算器BODMAS的数组

时间:2016-10-07 20:43:04

标签: c arrays sorting for-loop struct

我试图重新排列我的计算器数组以逃避BODMAS条件。基本上,我读了一个字符串,我将数字和操作数添加到不同的数组中,然后我尝试重新排列每个数组以使具有优先级的操作(从数组中的右到左)。我对" priorizar"进行了此更改。功能。我想重新排列不起作用。我的代码有问题吗?提前致谢

#include <stdio.h>

#define MAX 100

struct stacknum{
    float nums[MAX];
    int topnum;
}sn;    //'stack' de numeros - nao prioritaria

struct stackops{
    char ops[MAX];
    int topop;
}so;    // 'stack' de operadores - nao prioritaria

struct stacknum1{
    float nums1[MAX];
    int topnum1;
}sn1;  // 'stack' de numeros - prioritaria

struct stackops1{
    char ops1[MAX];
    int topop1;
}so1;  // 'stack' de operadores - prioritaria

float calculo(float vlr, float vlr2, char op)  // funçao de operaçoes
{
    if ('+' == op)
        return vlr + vlr2;

    if ( '-' == op)
        return vlr2 - vlr;

    if ( '*' == op)
        return  vlr * vlr2;

    if ('/' == op)
        return vlr2 / vlr;
    else
        return 0;
}

void priorizar()
{
    int i, k = 0;
    char aux;
    float aux1, aux2;

    for (i = 0; i < MAX; i++)
    {
        if (so.ops[i] == '*' || so.ops[i] == '/')
        {
            aux = so.ops[so.topop - k];
            so.ops[so.topop - k] = so.ops[i];
            so.ops[i] = aux;
            aux1 = sn.nums[sn.topnum - (k + 1)];
            aux2 = sn.nums[sn.topnum - k];
            sn.nums[sn.topnum - (k + 1)] = sn.nums[i];
            sn.nums[sn.topnum - k] = sn.nums[i + 1];
            sn.nums[i] = aux2;
            sn.nums[i + 1] = aux1;
            k++;
        }
    }
}

float emptystack(int k)   // faz operaçoes a partir da stack , esvazia-a     fazendo todas as operaçoes dentro dela
{ // buffer size excedido quando 20+20*30 ????
    float v1, v2;
    char op;

    if (k == 0)
    {
        while (so.topop != 0)  // esvaziar stack  
        {
            v1 = sn.nums[--(sn.topnum)];
            v2 = sn.nums[--(sn.topnum)];
            op = so.ops[--(so.topop)];
            sn.nums[sn.topnum++] = calculo(v1, v2, op);
        }

        return sn.nums[sn.topnum - 1];
    }
    else
    {
        while(so1.topop1!=0)  // esvaziar stack prioritaria
        {
            v1 = sn1.nums1[--(sn1.topnum1)];
            v2 = sn1.nums1[--(sn1.topnum1)];
            op = so1.ops1[--(so1.topop1)];
            sn1.nums1[sn1.topnum1++] = calculo(v1, v2, op);
        }

        return 0;
    }
}

int IsDigit(char str[], int i)  // se é digito ou nao lel kek
{
    if(str[i] >= '0' && str[i] <= '9')
        return 1;
    else return 0;
}

float analisa(char str[])   // analise de string, BODMAS + parenteses
{
    int i;
    float valor;
    char op;

    for (i = 0; str[i] != '\0'; i++)   
    {
        if (IsDigit(str, i))   // Ñ PARENTESES
        {
            sscanf(str + i, "%f", &valor);  // le e passa para float
            sn.nums[sn.topnum++] = valor;  // empilha numero

            while (str[i + 1] == '.' || (str[i + 1] >= '0' && str[i + 1] <= '9'))
                i++;
        } else if (str[i] == '+' || str[i] == '-' || str[i]=='*' || str[i] == '/')     // empilha se for operaçao nao prioritaria
            so.ops[so.topop++] = str[i];
    }

    priorizar();
    return emptystack(0);   // esvazia stack nao prioritaria e retorna o resultado final
}

int main()
{
    char str[100] = "3*3+2";
    float resultado;
    //printf("Expressao: ");
    //scanf("%s",str);
    resultado = analisa(str);
    printf("%g\n",resultado);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

低级问题是priorizar()函数没有正确管理堆栈 - 它在错误的地方寻找东西:

aux = so.ops[so.topop - k];

k = 0,这是垃圾记忆时,它应该是:

aux = so.ops[so.topop - k - 1];

这是堆栈中的顶级项目。并且它没有正确地说明sn堆栈与so堆栈相比以不同的速率增长的事实,有时是同一速率的两倍,有时以相同的速率增长。因此,您无法使用固定偏移量对两者进行索引:

sn.nums[i] = aux2;
sn.nums[i + 1] = aux1;

有时这会是:

sn.nums[2 * i] = aux2;
sn.nums[2 * i + 1] = aux1;

而在其他人只有一个数字可以被操纵,因为方程的另一半是表达式。

高级问题是逻辑错误。如果我们可视化堆栈:

so: * +
sn: 3 3 2

那么priorizar()首先做的是什么:

so: + *
sn: 3 2 3

这给了我们9((2 * 3)+ 3)而不是所需的11.但是由于搜索运算符堆栈一直在继续,它会重新获得&#39; *&#39;再次错误地再次转换它:

so: * +
sn: 3 garbage 3

给我们(3 + 垃圾)* 3)。即使你修正了错误并让iso.topop - k过了,你仍然会得到错误的答案。

您可以根据需要重新安排priorizar()中的代码,但我不相信您可以从此处到达。