我有两个数组,其中一个有整数,另一个有运算符的字符。所以,假设我有以下数组:[12, 3] 和 ['+']。我想把它转换成表达式 12 + 3,它会立即被计算(给我 15)。它还应该保留操作顺序,所以如果我有 [12, 3, 4] 和 ['+', '*'],它应该给我 12 + 3 * 4,(即 24)。我保证 char 比 int 的数量少一个,所以总是有正确数量的运算符。可以在C中做到这一点吗?如果是这样,怎么做?
谢谢你。
当然有可能。基本算法:
while there are operators left:
// determine operation
i = the index of the operator with the highest priority
operator = operators[i]
shift operators[i+1..end] one to the left (in other words, remove the operator from the array)
operation_function = lookup operator
// execute operation
numbers[i] = operation_function(numbers[i], numbers[i+1])
shift numbers[i+2..end] one to the left
把它变成 C 玩得开心!:)
这是一个解决方案;不是一个完美的(整数除法等),但它显示了算法。
这很简单,只需从左到右消除运算符,并在每次消除后将数组左移一位。'*' 和 '/' 的优先级高于 '+' 和 '-'。代码是多余的,只解决烧录的输入,将其分解为函数将是您的工作。
这里是:
#include <stdio.h>
int main()
{
int nums[8]={1,5,8,2,5,3,4,7};
int cnums = 8;
char ops[7]={'+','-','/','*','+','-','*'};
int cops=7;
int flag =1;
int i,j;
while(flag)
{
flag=0;
for(i=0;i<cnums;i++)
if(ops[i]=='*' || ops[i]=='/')
{
if(ops[i]=='*')
nums[i]*=nums[i+1];
else
nums[i]/=nums[i+1];
flag=1;
for(j=i;j<cops;j++)
{
ops[j]=ops[j+1];
nums[j+1]=nums[j+2];
}
cnums--;
cops--;
break;
}
}
flag=1;
while(flag)
{
flag=0;
for(i=0;i<cnums;i++)
if(ops[i]=='+' || ops[i]=='-')
{
if(ops[i]=='+')
nums[i]+=nums[i+1];
else
nums[i]-=nums[i+1];
flag=1;
for(j=i;j<cops;j++)
{
ops[j]=ops[j+1];
nums[j+1]=nums[j+2];
}
cnums--;
cops--;
break;
}
}
return 0;
}
你可以看到它在这个LINK上工作。
如果您熟悉形式语言,我建议您在遇到与此类似的问题时尝试YACC 。
#include<stdio.h>
int calc(char op, int stack[], int *sp){
switch(op){
case '+':
stack[*sp-1] += stack[*sp];
--(*sp);
return 1;
case '-':
stack[*sp-1] -= stack[*sp];
--(*sp);
return 1;
case '*':
stack[*sp-1] *= stack[*sp];
--(*sp);
return 1;
case '/':
stack[*sp-1] /= stack[*sp];
--(*sp);
return 1;
default:
return 0;
}
}
int main(void){
int vals[] = {12, 3, 4}, vali=0, opi;
char ops[] = {'+', '*', 0}, op_hold = 0;
int stack[3], sp=-1;
int result = 0;
stack[++sp] = vals[vali++];
for(opi=0;ops[opi];++opi){
stack[++sp] = vals[vali++];
if(ops[opi] == '+' || ops[opi] == '-'){
if(ops[opi+1] == '*' || ops[opi+1] == '/'){
op_hold = ops[opi];
} else {
calc(ops[opi], stack, &sp);
}
} else if(ops[opi] == '*' || ops[opi] == '/'){
calc(ops[opi], stack, &sp);
if(ops[opi+1] != '*' && ops[opi+1] != '/' && op_hold){
calc(op_hold, stack, &sp);
op_hold = 0;
}
}
}
result = stack[sp--];
printf("%d\n", result);
return 0;
}