【发布时间】:2016-10-07 20:43:03
【问题描述】:
我试图重新排列我的计算器数组以逃避 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;
}
【问题讨论】:
-
如果它不起作用,那么是的,您的代码有问题。要知道什么,您需要提供一些示例,说明预期的、实际的和似乎错误的。
-
事后像这样重新排列是很困难的,你现在知道了。我建议您查找其他解析表达式的技术。例如基于operator precedence parsing 的一个(有几个非常简单的基于堆栈的变体)。
-
@EugeneSh。如果我执行 3*3+2,则返回 0。看起来 sn.nums[0] 始终为零,但它被认为是最终结果。虽然 sn.nums[1] 给出 9,但这是第一次操作的结果
-
@JoachimPileborg 我试图避免这种情况,因为我的目标是不使用它>.>
标签: c arrays sorting for-loop struct