C语言_表达式计算_中缀转后缀_多位数计算

  之前一个好兄弟问我表达式计算的一个程序,这个主要锻炼栈的使用。但是他向我提出了一个问题,如果多位数计算,好像常规的表达式转化就不灵了。即常规的程序只能计算10以下的数字,对于这个问题进行下探索。
  举个例子,常规的方法,生成的后缀表达式会是这样的:123-*,这样无法判断是1还是12。也就是对多位数失效。最终确定的思路是在中缀转后缀的过程中,对数字进行判断:如果是多位数,则通过空格隔开。同时在后缀计算中,时刻检查空格的存在,最后完成计算。源代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

#define SIZE 100

//字符栈目的是进行中缀转后缀
char stack[SIZE];
int top = -1;

//整数栈目的是进行后缀表达式的计算
int stack_int[SIZE];
int top_int = -1;

//字符栈操作
void push(char item)
{
	if(top >= SIZE-1)
	{
		printf("\nStack Overflow.");
	}
	else
	{
		top = top+1;
		stack[top] = item;
	}
}

//字符栈操作
char pop()
{
	char item ;

	if(top <0)
	{
		printf("stack under flow: invalid infix expression");
		getchar();
		exit(1);
	}
	else
	{
		item = stack[top];
		top = top-1;
		return(item);
	}
}

//整数栈操作
void push_int(int num)
{
	if(top_int >= SIZE-1)
	{
		printf("\nStack Overflow.");
	}
	else
	{
		top_int = top_int+1;
		stack_int[top_int] = num;
	}
}

//整数栈操作
int pop_int()
{
	int num ;

	if(top_int <0)
	{
		printf("stack under flow: invalid infix expression");
		getchar();
		exit(1);
	}
	else
	{
		num = stack_int[top_int];
		top_int = top_int-1;
		return(num);
	}
}

//funciton:判断是否为操作符
int is_operator(char symbol)
{
	if(symbol == '*' || symbol == '/' || symbol == '+' || symbol == '-')
	{
		return 1;
	}
	else
	{
	return 0;
	}
}

//function:确定优先级
int precedence(char symbol)
{
	if(symbol == '*' || symbol == '/')
	{
		return(2);
	}
	else if(symbol == '+' || symbol == '-')
	{
		return(1);
	}
	else
	{
		return(0);
	}
}

//function:中缀表达式转后缀表达式,结果存于postfix_exp形参中
void InfixToPostfix(char infix_exp[], char postfix_exp[])
{
	int i, j;
	char item;
	char x;

	push('(');
	strcat(infix_exp,")");

	i=0;
	j=0;
	int tag = 0;
	item=infix_exp[i];

	while(item != '\0')
	{
		if(item == '(')
		{
			push(item);
		}
		else if( isdigit(item) || isalpha(item))
		{
			//when meet a digit, judge if the number is bigger than 10
			//if so, add ' ' before it  and ' ' after it
			//use tag as a symbol to add the first ' '
			char next = infix_exp[i+1];
			while (isdigit(next))
			{
				if (tag == 0)
				{
					postfix_exp[j++] = ' '; 
					tag = 1;
					postfix_exp[j++] = item;
					i++;
					item = next;
					next = infix_exp[i+1];
				}
				else
				{
					postfix_exp[j++] = item;
					i++;
					item = next;
					next = infix_exp[i+1];
				}
			}
			//when tag equals to 1, it means a number bigger than 10 appears
			if (tag == 1)
			{
				tag = 0;
				postfix_exp[j++] = item;
				postfix_exp[j++] = ' ';
				item = next;
				i++;
				continue;
			}
			postfix_exp[j] = item;
			j++;
		}
		else if(is_operator(item) == 1)
		{
			x=pop();
			while(is_operator(x) == 1 && precedence(x)>= precedence(item))
			{
				postfix_exp[j] = x;
				j++;
				x = pop();
			}
			push(x);
			push(item);
		}
		else if(item == ')')
		{
			x = pop();
			while(x != '(')
			{
				postfix_exp[j] = x;
				j++;
				x = pop();
			}
		}
		else
		{
			printf("\nInvalid infix Expression.\n");
			getchar();
			exit(1);
		}
		i++;


		item = infix_exp[i];
	}
	if(top>0)
	{
		printf("\nInvalid infix Expression.\n");
		getchar();
		exit(1);
	}
	if(top>0)
	{
		printf("\nInvalid infix Expression.\n");
		getchar();
		exit(1);
	}


	postfix_exp[j] = '\0';
}

//function:后缀表达式计算
long int EvalPostfix(char postfix[])
{
	int i;
	char ch;
	int val; 
	int A, B;
	for ( i = 0; postfix[i] != '\0'; i++)
	{
		ch = postfix[i];
		if(isdigit(ch))
		{
			val = ch-'0';
			push_int(val);
		}
		else if (ch == ' ')
		{
			i++;
			val = 0;
			ch = postfix[i];
			while (ch != ' ')
			{
				val = val*10 + (postfix[i]-'0');
				i++;
				ch = postfix[i];
			}
			push_int(val);
		}
		else if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
		{
			A = pop_int();
			B = pop_int();
		switch(ch)
		{
			case '/':
			val = B / A;
			break;
			
			case '*':
			val = B * A;
			break;
			
			case '+':
			val = B + A;
			break;
			
			case '-':
			val = B - A; 
			break; 
		}
    	push_int(val);
		}
	}

	return pop_int();
}

int main()
{
	char infix[SIZE], postfix[SIZE];
    int value;
	printf("ASSUMPTION: The infix expression contains single letter variables and single digit constants only.\n");
	printf("\nEnter Infix expression : ");
	gets(infix);
	
	InfixToPostfix(infix,postfix);
	printf("Postfix Expression: ");
	puts(postfix);
	
	value = EvalPostfix(postfix);
    printf("Result of expression evaluation : %d", value);
    system("pause");

	return 0;
}

  计算结果如下:
  输入中缀表达式为:10-6*(12-8/4)+3
在这里插入图片描述

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中缀表达式计算结果需要先将中缀表达式换为后缀表达式,然后再对后缀表达式进行计算。下面是一个简单的C语言程序实现中缀表达式计算结果的过程: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 100 //定义栈的最大容量 //定义操作符栈 char op_stack[MAX_SIZE]; int top_op = -1; //定义数字栈 int num_stack[MAX_SIZE]; int top_num = -1; //获取操作符优先级 int get_priority(char op){ if(op == '*' || op == '/') return 2; else if(op == '+' || op == '-') return 1; else return 0; } //将中缀表达式换为后缀表达式 void infix_to_postfix(char *infix, char *postfix){ int i = 0, j = 0; while(infix[i] != '\0'){ if(infix[i] >= '0' && infix[i] <= '9'){ //如果是数字,直接输出到后缀表达式中 postfix[j++] = infix[i++]; while(infix[i] >= '0' && infix[i] <= '9') //处理多位数字 postfix[j++] = infix[i++]; postfix[j++] = ' '; //数字之间用空格隔开 } else{ //如果是操作符 if(infix[i] == '('){ //左括号直接入栈 op_stack[++top_op] = infix[i++]; } else if(infix[i] == ')'){ //右括号将栈中操作符输出到后缀表达式中,直到遇到左括号 while(op_stack[top_op] != '('){ postfix[j++] = op_stack[top_op--]; postfix[j++] = ' '; //操作符之间用空格隔开 } top_op--; //弹出左括号 i++; } else{ //其他操作符 if(top_op == -1 || op_stack[top_op] == '('){ //栈为空或栈顶是左括号,直接入栈 op_stack[++top_op] = infix[i++]; } else if(get_priority(infix[i]) > get_priority(op_stack[top_op])){ //当前操作符优先级高于栈顶操作符,直接入栈 op_stack[++top_op] = infix[i++]; } else{ //当前操作符优先级低于等于栈顶操作符,将栈中操作符输出到后缀表达式中,直到栈顶操作符优先级低于当前操作符 while(top_op != -1 && op_stack[top_op] != '(' && get_priority(infix[i]) <= get_priority(op_stack[top_op])){ postfix[j++] = op_stack[top_op--]; postfix[j++] = ' '; //操作符之间用空格隔开 } op_stack[++top_op] = infix[i++]; //将当前操作符入栈 } } } } while(top_op != -1){ //将栈中剩余操作符输出到后缀表达式中 postfix[j++] = op_stack[top_op--]; postfix[j++] = ' '; //操作符之间用空格隔开 } postfix[j] = '\0'; //后缀表达式以'\0'结尾 } //计算后缀表达式的值 int calculate(char *postfix){ int i = 0; char num_str[MAX_SIZE]; //用于处理多位数字 int num, num1, num2; while(postfix[i] != '\0'){ if(postfix[i] >= '0' && postfix[i] <= '9'){ //如果是数字,将其换为整数 int j = 0; while(postfix[i] >= '0' && postfix[i] <= '9'){ num_str[j++] = postfix[i++]; } num_str[j] = '\0'; num = atoi(num_str); num_stack[++top_num] = num; //将数字入栈 } else if(postfix[i] == ' '){ //遇到空格,跳过 i++; } else{ //如果是操作符,从数字栈中弹出两个数进行计算 num2 = num_stack[top_num--]; num1 = num_stack[top_num--]; switch(postfix[i]){ case '+': num = num1 + num2; break; case '-': num = num1 - num2; break; case '*': num = num1 * num2; break; case '/': num = num1 / num2; break; } num_stack[++top_num] = num; //将计算结果入栈 i++; } } return num_stack[top_num]; //返回最终计算结果 } int main(){ char infix[MAX_SIZE]; char postfix[MAX_SIZE]; int result; printf("请输入中缀表达式:"); scanf("%s", infix); infix_to_postfix(infix, postfix); printf("后缀表达式为:%s\n", postfix); result = calculate(postfix); printf("计算结果为:%d\n", result); return 0; } ``` 注意,上述代码中只考虑了整数的情况,如果表达式中包含小数或负数,需要对代码进行相应的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值