【问题标题】:How do I extract operators from a char array? [closed]如何从 char 数组中提取运算符? [关闭]
【发布时间】:2013-06-11 09:36:30
【问题描述】:

我有两个数组,其中一个有整数,另一个有运算符的字符。所以,假设我有以下数组:[12, 3] 和 ['+']。我想把它转换成表达式 12 + 3,它会立即被计算(给我 15)。它还应该保留操作顺序,所以如果我有 [12, 3, 4] 和 ['+', '*'],它应该给我 12 + 3 * 4,(即 24)。我保证 char 比 int 的数量少一个,所以总是有正确数量的运算符。可以在C中做到这一点吗?如果有,怎么做?

谢谢。

【问题讨论】:

  • 在 C 中是可能的。你试过任何代码吗?
  • 也许你正在寻找binary expression trees
  • @ M M 如何在不使用条件的情况下将运算符从字符中取出(因为这会影响运算顺序)?
  • @blacktrance:呃,什么?
  • @thejh:我知道可以使用条件 - 如果是 '+',则取数组的前两个元素并将它们相加,如果是 '',则取前两个元素数组并将它们相乘,依此类推。但这并不能保留操作顺序,因为如果我有一个类似 [1, 2, 3] 的数组和另一个类似 ['+', ''] 的数组,并且我使用条件对其进行评估,我当我想要 1+(2*3) 时得到 (1+2)*3。

标签: c arrays operators


【解决方案1】:

当然可以。基本算法:

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 很有趣! :)

【讨论】:

  • “具有最高优先级的操作员”是什么意思?例如,如果我有数组 ['+', '', ''],哪个乘法具有更高的优先级?如果我先做乘法,这个解决方案是否会保留加法符号以便在最后使用它?
  • @blacktrance:对于具有相同优先级的运算符,您希望首先处理左侧(较小索引)的运算符。是的,这会保留添加,直到你到达终点。
【解决方案2】:
#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;
}

【讨论】:

    【解决方案3】:

    这是一个解决方案;不是一个完美的(整数除法等),但它显示了算法。

    这很简单,只需从左到右消除运算符,并在每次消除后将数组左移一位。 '*' 和 '/' 的优先级高于 '+' 和 '-'。代码是多余的,只解决烧录的输入,把它分解成函数就是你的工作。

    这里是:

    #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

    【讨论】:

      猜你喜欢
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多