Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何正确解析算术表达式中的数字,区分正数和负数?_C_String_Parsing_Calculator_Arithmetic Expressions - Fatal编程技术网

C 如何正确解析算术表达式中的数字,区分正数和负数?

C 如何正确解析算术表达式中的数字,区分正数和负数?,c,string,parsing,calculator,arithmetic-expressions,C,String,Parsing,Calculator,Arithmetic Expressions,我在我的数据结构课程中有一个作业,我必须编写一个计算器,用4个基本运算和括号求解算术表达式,输入通过标准输入缓冲区完成,输出也一样 一开始很容易,老师给我们提供了算法(如何将表达式从中缀转换为后缀,以及如何计算),唯一的目标是我们实现自己的堆栈并使用它,但计算器本身工作不太好,我想这是因为我的解析器 ,以及我的代码,用于解析数字、运算符和括号,同时将它们放入数组中,以便于以后计算的方式存储表达式 // saida is an array of pairs of integers, the fir

我在我的数据结构课程中有一个作业,我必须编写一个计算器,用4个基本运算和括号求解算术表达式,输入通过标准输入缓冲区完成,输出也一样

一开始很容易,老师给我们提供了算法(如何将表达式从中缀转换为后缀,以及如何计算),唯一的目标是我们实现自己的堆栈并使用它,但计算器本身工作不太好,我想这是因为我的解析器

,以及我的代码,用于解析数字、运算符和括号,同时将它们放入数组中,以便于以后计算的方式存储表达式

// saida is an array of pairs of integers, the first value of the pair is the value of the info (the number itself or the ASCII value of the operator)
// The second value is an indicator of whether it is a number or a operator
for (i = 0; i < exp_size; i++) {
    c = expression[i];

    // If the current char is a digit, store it into a helper string and keep going until a non-digit is found
    // Then atoi() is used to transform this string into an int and then store it.
    if (c >= '0' && c <= '9') {
        j = 1, k = i+1;
        tempInt[0] = c;
        while(expression[k] >= '0' && expression[k] <= '9') {
            tempInt[j++] = expression[k];
            k++;
        }
        tempInt[j] = '\0';
        saida[saidaIndex][0] = atoi(tempInt);
        saida[saidaIndex++][1] = 0;
        i = k-1;
    }

    // If the character is an operator, the algorithm is followed.
    else if (c == '+' || c == '-' || c == '*' || c == '/') {
        while(pilha->size > 0 && isOpBigger( stack_top(pilha), c )) {
            saida[saidaIndex][0] = stack_pop(pilha);
            saida[saidaIndex++][1] = 1;
        }
        stack_push(c, pilha);
    }
    else if (c == '(') stack_push(c, pilha);
    else if (c == ')') {
        j = stack_pop(pilha);
        while(j != '(') {
            saida[saidaIndex][0] = j;
            saida[saidaIndex++][1] = 1;
            j = stack_pop(pilha);
        }
    }
}
//saida是一个整数对数组,该对的第一个值是info的值(数字本身或运算符的ASCII值)
//第二个值是数字还是运算符的指示器
对于(i=0;i='0'&&c='0'&&expression[k]size>0&&i更大(堆栈顶部(pilha),c)){
saida[saidaIndex][0]=堆栈(pilha);
saida[saidaIndex++][1]=1;
}
堆栈推送(c,pilha);
}
else如果(c=='(')堆栈推送(c,pilha);
如果(c=='),则为else){
j=堆叠(pilha);
而(j!='('){
saida[saidaIndex][0]=j;
saida[saidaIndex++][1]=1;
j=堆叠(pilha);
}
}
}
问题是,在这段代码中,我不知道减号是表示减法运算符还是负数(我知道减号运算符是负数的和,但它没有帮助我解决这个问题),我想到了以下几点,但都没有成功:

  • 每次有负号时,存储一个加号,让下一个数字本身为*-1。如果下一个数字已经是负号,或者负号在带括号的表达式之前,如1+2-(3*4),则不起作用
  • 如果减号后面有空格,它就是一个运算符,如果没有,它就是一个负数。这不起作用,因为输入中没有这些规则
我在解释器方面没有任何经验,我真的不知道如何继续。代码可以完美地处理没有负数的有效表达式,但不能处理像()+3-()这样奇怪的表达式,但这是另一个问题


谢谢您的帮助。

这就是所谓的“一元负号”问题,在您的情况下(无变量)可以通过替换来解决

运算符
-
如果是一元负号,则为一元负号

  • 前面有一个左括号
  • 前面有另一个操作员
  • 输入的第一个字符
现在不再存储
-
,而是存储一个不同的字符,比如
m
,并为其分配比其他运算符更高的优先级(或者与求幂运算符相同,如果有)


另一个提示:不要使用空格表示任何内容,算术表达式必须在没有空格的情况下工作,否则它是不正确的。

而不是((i=0;i(每次迭代只强制增量
1
)尝试
char*p=expression;而(*p){根据需要测试/增量}
允许您根据需要向前读取和使用表达式中的字符。例如,
如果(*p='-'),而(isblank(*p))p++;
(或其他相关测试,例如,
0-9
等)这使您可以在表达式中向前读取以确定要处理的内容?我从未想过以这种方式遍历字符串,我会尝试一下,谢谢!解析任何字符串时,这会增加很大的灵活性。您知道每个字符串的末尾都有一个nul字节,因此只需在(*p)和根据需要进行读取/检查允许您执行各种操作,例如
*(p+x)
以进行前(或后)读取。您甚至可以使用多个指针将子表达式括在字符串中,例如
char*sp,*ep;
用于开始和结束指针,这允许您设置
if(*p=='('))sp=p;
并持续到
if(*p='))ep=p;
然后处理
sp
ep
之间的内容。这真的为我打开了新的视野,再次感谢你,我会记住这一点!谢谢,我要尝试一下。我应该用加号来实现它吗?不,通常不需要。@MikaelMello,因为你有一元负号操作符,你也有一元加号操作符它是不必要的,但是它可以作为
+3
输入(在表达式的开头)或重复,如在
++3
中。检查是否可以有
++-++-++-++-++-++++-++3++-++-++-+5
等输入,并且它们是有效的。一元运算符的优先级应高于二进制算术运算符,以允许使用
5*-3
-5*+3
等表达式(被解释为
5*-3
-5*-5]*(+3)
)或者至少超过了添加运算符
+
-
(在这种情况下,de second
-5*+3
是不正确的)您是对的,我添加了一个一元加号,以及对多个一元运算符的支持,如您的第二个和第三个示例。我使用了“布尔值”变量来指示一元运算符是否处于活动状态并且工作正常,但我选择将
++3
指示为无效表达式,因为它似乎不正确。因此,如果这些示例是有效表达式,我将回到我第一次实现的方法