我正在尝试用C编写计算器,并希望制作一个可以计算多个输入的计算器,例如(5 * 9 + 1 -2)。这些输入可以是完全随机的,我仍然坚持如何做到这一点。
我知道如何初始化变量,并要求用户输入一个数字和所有这些,但如果用户想要添加50个随机数,那么该计算器就无法做到。
希望您能提供帮助或分享一些提示
谢谢!
答案 0 :(得分:1)
您需要实现一个将运算符优先级考虑在内的表达式解析器。对我来说,最简单的两种方法是实现一个递归的正确解析器或实现Shunting yard algorithm。
有关示例,请参阅this。
答案 1 :(得分:0)
当您找到{+,-,*,/}.
时,您可以在阅读并分割该字符串时使用字符串。您在它们之间找到的是您的数字。
尝试添加您的代码!
祝你好运!答案 2 :(得分:0)
为了做到这一点,你需要阅读整行(它不应该太难), 那么你需要解析它并将其存储到一些数据结构中。
我知道存储和使用它的两种方式:
第一个:它易于操作,易于使用,但不漂亮也不快: 一个双链表,每个链接包含一个运算符或一个数字和一个优先级如果它是一个运算符(如果你想要更干净的东西你可以使用一个enum + union):
struct list {
struct list *prev;
struct list *next;
char operator;
int number;
unsigned int priority;
}
通过字符串循环并应用一个简单的优先级算法(伪代码):
var priority = 0
var array = cut string // ["5", "+", "3", "*", "(", "6", "-", "2", ")"]
check string // verify the string is correct
for each element of array :
if (element is number)
store in list
else if (element is operator)
store in list
if (element is '*' or '/' or '%')
set his priority to priority + 1
else
set his priority to priority
else if (element is open parenthesis)
priority += 2
else if (element is close parenthesis)
priority -= 2
例如:
的字符串:
5 + 3 * (6 - 2) - 1
的优先级:
0 1 2 0
然后,进行计算:
while list isn't empty:
find operator with the highest priority // if there is more than one, take the first
calculate this operator // with the element prev and next
replace by result in list // operator, but also prev and next
再一次使用5 + 3 * (6 - 2) - 1
:
第一次迭代:
5 + 3 * 4 - 1
然后
5 + 12 - 1
然后
17 - 1
然后
16
另一个(更好的是,如果你不熟悉递归会更难一点)一:使用reverse polish notation的二叉树 (请参阅here和here)
这个更常见,所以我不会解释它。
答案 3 :(得分:0)
这不是一个完整的解决方案,但嘿... 尝试以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE (1000)
static char tempNumStr[50] = {0};
static double parsedDoubleArr[5] = {0};
static char parsedOperators[5] = {0};
void flushTempArr(char tmpArr[50]){
for(int i=0; i< 50; i++)
tmpArr[i] = 0 ;
}
int tempNumStrIterator=0;
int parsedDoubleArrIterator=0;
int parsedOperatorsIterator=0;
int main(void)
{
char operator;
char sourceStr[] = "(17.5 + 8)";
for(int i = 0; sourceStr[i] != '\0'; ++i) /*iterate over string till \0 */
{
if (IsDigit(sourceStr[i]))
{
while(sourceStr[i] != '\0' && IsDigit(sourceStr[i]))
{
tempNumStr[tempNumStrIterator++] = sourceStr[i];
++i;
}
sscanf(tempNumStr, "%lf", &parsedDoubleArr[parsedDoubleArrIterator++]);
flushTempArr(tempNumStr);
tempNumStrIterator = 0;
}
if (IsCalcOperator(sourceStr[i]))
{
parsedOperators[parsedOperatorsIterator++] = sourceStr[i];
}
else if (IsBracket(sourceStr[i]))
{
//do something
continue;
}
}
//do what you want with parsedDoubleArr and parsedOperators
return EXIT_SUCCESS;
}