gpt4 book ai didi

c - 重新排列计算器 BODMAS 的数组

转载 作者:行者123 更新时间:2023-11-30 16:56:24 26 4
gpt4 key购买 nike

我正在尝试重新排列我的计算器数组以逃避 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;
}

最佳答案

低级问题是 priorizar() 函数无法正确管理堆栈 - 它在错误的位置查找内容:

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

k = 0时,这是垃圾内存,它应该是:

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

这是堆栈顶部的项目。而且它没有正确地解释这样一个事实:与 so 堆栈相比,sn 堆栈的增长速度有所不同,有时快两倍,有时则相同。因此,您不能使用固定偏移量来索引两者:

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。但是由于对运算符堆栈的搜索一直持续下去,它再次遇到 '*' 并再次错误地转换它:

so: * +
sn: 3 garbage 3

给我们带来了 (3 + 垃圾) * 3)。即使您修正了错误并防止 iso.topop - k 交叉,您仍然会得到错误的答案。

您可以根据需要重新排列 priorizar() 中的代码,但我不相信您可以从这里到达那里。

关于c - 重新排列计算器 BODMAS 的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39925508/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com