【发布时间】:2017-01-04 22:12:51
【问题描述】:
我的数据结构类中有一个作业,我必须在其中编写一个计算器,用 4 个基本运算和括号来求解算术表达式,输入是通过标准输入缓冲区完成的,输出也是如此。
一开始很容易,老师为我们提供了算法(如何将表达式从中缀转换为后缀以及如何评估它),唯一的目标是让我们实现自己的堆栈并使用它,但是计算器本身并不能很好地工作,我认为是因为我的解析器。
This is the algorithm 和我的代码,用于解析数字、运算符和括号,同时将它们放入数组中,以便以后更容易评估的方式存储表达式。
// 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);
}
}
}
问题是,在这段代码中,我无法判断减号是表示减法运算符还是负数(我知道减号运算符是负数的和,但它并没有帮助我解决这个问题),我想到了以下,没有成功:
- 每次出现减号时,存储一个加号并让下一个数字本身为 * -1。如果下一个数字已经是负数,或者如果减号位于带括号的表达式之前,例如 1 + 2 - (3 * 4),则不起作用。
- 如果减号后面有空格,则为运算符,否则为负数。不起作用,因为输入中没有这些规则。
我在口译方面没有任何经验,我真的不知道如何进行。该代码可以完美地处理没有负数的有效表达式,但不能处理像 () + 3 - () 这样的奇怪表达式,但这是另一个问题。
感谢您的帮助。
【问题讨论】:
-
代替
for (i = 0; i < exp_size; i++)(每次迭代仅强制增加1)尝试char *p = expression; while (*p) { test/increment as needed },它允许您根据需要向前读取和使用表达式中的字符.例如if (*p == '-') while (isblank (*p)) p++;(或其他类似的测试,例如(、0-9等)让您在表达式中向前阅读以确定您正在处理什么? -
我从来没有想过这样遍历一个字符串,去试试,谢谢!
-
在解析任何字符串时,这增加了很大的灵活性。你知道你会在每个字符串的末尾有一个 nul-byte ,所以只需使用
while (*p)沿着字符串向下走并根据需要读取/检查就可以让你做各种各样的事情,比如@ 987654330@ 提前(或后面)阅读。您甚至可以使用多个指针将字符串中的 sub-expressions 括起来,例如char *sp, *ep;用于 start 和 end 指针,它允许您设置if (*p == '(') sp = p;并继续直到if (*p = ')') ep = p;然后处理sp和ep之间的内容。 -
这真的为我打开了新的视野,再次感谢你,会记住这一点!
标签: c string parsing calculator arithmetic-expressions