我试图重新排列我的计算器数组以逃避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;
}
答案 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)。即使你修正了错误并让i
和so.topop - k
过了,你仍然会得到错误的答案。
您可以根据需要重新安排priorizar()
中的代码,但我不相信您可以从此处到达。