在 C 中使用递归计算算术表达式
Evaluating Arithmetic Expression Using Recursion in C
这是一个使用递归计算算术表达式的算法:
- 查找操作数 1
- t1 = Eval(operand1)
- 查找操作数 2
- t2 = Eval(operand2)
- 在 t1 和 t2 上应用运算符
假设:
- 每个操作数都在两个运算符之间
只有二元运算
每个操作都有括号(包括最外层的括号)
输入:
表示算术表达式的标记数组
num_tokens是令牌数
令牌示例数组:{“(”、“9”、“+”、“(”、“50”、“-”、“25”、“)”、“)”}
我尝试实现该算法,但我的程序没有 运行(退出状态 -1 是我收到的唯一消息)。为什么会这样?
int apply(char op, int a, int b) {
if (op == '+'){
printf("%d %c %d\n", a,op,b);
return a + b;
}
else if (op == '-'){
printf("%d %c %d\n", a,op,b);
return a - b;
}
else if(op == '/'){
printf("%d %c %d\n", a,op,b);
return a / b;
}
else if(op == '*'){
printf("%d %c %d\n", a,op,b);
return a * b;
}
}
int eval_tokens(char** expression, int num_tokens)
{
// implement me
int index;
int opIndex = find_operator(expression, num_tokens); //find index of operator
int count1=0,count2=0,term1,term2,i,j;
if(*expression[0] == '(')
i = 1;
else
i = 0;
while(i <= opIndex){
i++;
count1++;
}
term1 = eval_tokens(expression+1,count1);
j = opIndex+1;
while(j < num_tokens){
count2++;
j++;
}
term2 = eval_tokens(expression+opIndex+1,count2); //expression+opIndex+1 points to index after opIndex
return apply(*expression[opIndex], term1, term2);
}
int main(void) {
char*expression[] = {"(", "(", "5", "+", "3", ")", "-", "(", "2", "+", "1", ")", ")"};
printf("result = %d\n", eval_tokens(expression, 13));
return 0;
}
要使用 str
(或 expression
)作为可以从中取出项目的堆栈,我会在递归函数中使用这些参数 "modifyable"。因此,您可以引入第二个函数 int eval_tokens_recursive(char*** expression, int *num_tokens)
,它具有更多的间接级别,实际上可以 "take items from the stack" 通过改变参数的值。
代码可能如下所示。希望对你有帮助。
int eval_tokens_recursive(char*** expression, int *num_tokens) {
char *token = **expression;
if (*num_tokens == 0) {
printf("expecting more tokens.\n");
exit(1);
}
if (*token == '(') { // begin of expression?
(*expression)++; // skip opening brace
(*num_tokens)--;
// lhs
int lhs = eval_tokens_recursive(expression, num_tokens);
// operand
char operand = ***expression;
(*expression)++;
(*num_tokens)--;
// rhs
int rhs = eval_tokens_recursive(expression, num_tokens);
(*expression)++; // skip closing brace
(*num_tokens)--;
switch (operand) {
case '+':
return lhs + rhs;
case '-':
return lhs - rhs;
case '*':
return lhs * rhs;
case '/':
return lhs / rhs;
default:
return 0;
}
} else { // not an expression; must be a numeric token
int operand;
if (sscanf(token, "%2d", &operand) != 1) {
printf("expecting numeric value; cannot parse %s.\n", token);
exit(1);
}
(*expression)++;
(*num_tokens)--;
return operand;
}
}
int eval_tokens(char** expression, int num_tokens) {
return eval_tokens_recursive(&expression, &num_tokens);
}
int main() {
char *expressions[] = {"(", "9", "+", "(", "50", "-", "25", ")", ")"};
int result = eval_tokens(expressions, 9);
printf("result: %d\n", result);
}
这是一个使用递归计算算术表达式的算法:
- 查找操作数 1
- t1 = Eval(operand1)
- 查找操作数 2
- t2 = Eval(operand2)
- 在 t1 和 t2 上应用运算符
假设:
- 每个操作数都在两个运算符之间
只有二元运算
每个操作都有括号(包括最外层的括号)
输入:
表示算术表达式的标记数组
num_tokens是令牌数
令牌示例数组:{“(”、“9”、“+”、“(”、“50”、“-”、“25”、“)”、“)”}
我尝试实现该算法,但我的程序没有 运行(退出状态 -1 是我收到的唯一消息)。为什么会这样?
int apply(char op, int a, int b) {
if (op == '+'){
printf("%d %c %d\n", a,op,b);
return a + b;
}
else if (op == '-'){
printf("%d %c %d\n", a,op,b);
return a - b;
}
else if(op == '/'){
printf("%d %c %d\n", a,op,b);
return a / b;
}
else if(op == '*'){
printf("%d %c %d\n", a,op,b);
return a * b;
}
}
int eval_tokens(char** expression, int num_tokens)
{
// implement me
int index;
int opIndex = find_operator(expression, num_tokens); //find index of operator
int count1=0,count2=0,term1,term2,i,j;
if(*expression[0] == '(')
i = 1;
else
i = 0;
while(i <= opIndex){
i++;
count1++;
}
term1 = eval_tokens(expression+1,count1);
j = opIndex+1;
while(j < num_tokens){
count2++;
j++;
}
term2 = eval_tokens(expression+opIndex+1,count2); //expression+opIndex+1 points to index after opIndex
return apply(*expression[opIndex], term1, term2);
}
int main(void) {
char*expression[] = {"(", "(", "5", "+", "3", ")", "-", "(", "2", "+", "1", ")", ")"};
printf("result = %d\n", eval_tokens(expression, 13));
return 0;
}
要使用 str
(或 expression
)作为可以从中取出项目的堆栈,我会在递归函数中使用这些参数 "modifyable"。因此,您可以引入第二个函数 int eval_tokens_recursive(char*** expression, int *num_tokens)
,它具有更多的间接级别,实际上可以 "take items from the stack" 通过改变参数的值。
代码可能如下所示。希望对你有帮助。
int eval_tokens_recursive(char*** expression, int *num_tokens) {
char *token = **expression;
if (*num_tokens == 0) {
printf("expecting more tokens.\n");
exit(1);
}
if (*token == '(') { // begin of expression?
(*expression)++; // skip opening brace
(*num_tokens)--;
// lhs
int lhs = eval_tokens_recursive(expression, num_tokens);
// operand
char operand = ***expression;
(*expression)++;
(*num_tokens)--;
// rhs
int rhs = eval_tokens_recursive(expression, num_tokens);
(*expression)++; // skip closing brace
(*num_tokens)--;
switch (operand) {
case '+':
return lhs + rhs;
case '-':
return lhs - rhs;
case '*':
return lhs * rhs;
case '/':
return lhs / rhs;
default:
return 0;
}
} else { // not an expression; must be a numeric token
int operand;
if (sscanf(token, "%2d", &operand) != 1) {
printf("expecting numeric value; cannot parse %s.\n", token);
exit(1);
}
(*expression)++;
(*num_tokens)--;
return operand;
}
}
int eval_tokens(char** expression, int num_tokens) {
return eval_tokens_recursive(&expression, &num_tokens);
}
int main() {
char *expressions[] = {"(", "9", "+", "(", "50", "-", "25", ")", ")"};
int result = eval_tokens(expressions, 9);
printf("result: %d\n", result);
}