整数四则混合混算的表达式计算

本文实现整数的四则混合混算。比如:输入(5+8*4+7)*9-3*(13+2*6),返回计算结果为321

 

思路:正向扫描表达式,使用两个栈分别存储整数和符号,有括号的先计算括号中的值。遇到乘除法先计算。经过以上计算后得到最后的式子为只有加减法的无括号式子。再计算最后结果。

 

流程描述:

1.      扫描字符t

2.      若为’\0’,跳到4;若为’*/+)’,入符号栈;若为’-‘,转化为(-1)*,分别入数字栈和符号栈;若为数字’0-9’,向前找到不是’0-9’的符号,转化为整数,入数字栈;若为’)’,符号栈依次出栈计算数字栈顶两元素后入数字栈,直到遇到’(‘出栈,跳到3

3.      t++,跳回1

4.      符号栈依次出栈计算数字栈数据,直到符号栈为空。跳到5

5.      数字栈栈顶元素为结果。结束。

输入:符合四则运算的整数数字运算表达式,可以有括号,负数。表达式合法性不在此程序验证范围之内,如果需要验证请在外围加验证函数。

输出:运算表达式结果。

限制:表达式使用的数字栈和符号栈的大小会限制计算的表达式范围;大数加减乘除不在此程序处理;

 

使用例子:

	char expession[] = "(5+8*4+7)*9-3*(13+002*6)";
	int ret = calculate_expression(expession);

程序代码:说明,如果想更清楚的了解运算过程和栈的变化,请自行加上栈数据打印函数。

 

程序代码:说明,如果想更清楚的了解运算过程和栈的变化,请自行加上栈数据打印函数。

#define ERROR_VALUE 0xffffffff
#define MAX_STACK 0x10
//数字栈
int int_stack[MAX_STACK];
int is_top=-1;
//数字入栈
bool is_push(int i)
{
	if (is_top<(MAX_STACK-1))
	{
		int_stack[++is_top]=i;
		return true;
	}
	return false;
};
//数字出栈
int is_pop()
{
	if (is_top>=0)
	{
		int p = int_stack[is_top];
		is_top--;
		return p;
	}
	return ERROR_VALUE;
};
//符号栈
char char_stack[MAX_STACK];
int cs_top = -1;
//符号入栈
bool cs_push(char ch)
{
	if (cs_top<(MAX_STACK-1))
	{
		char_stack[++cs_top] = ch;
		return true;
	}
	return false;
};
//符号出栈
char cs_pop()
{
	if (cs_top>=0)
	{
		char p = char_stack[cs_top];
		cs_top--;
		return p;
	}
	return -1;
};

//二元表达式计算
int calculate(int left,int right,char exp)
{
	if (exp == '*')
	{
		return right*left;
	}
	if (exp == '/')
	{
		return left/right;
	}
	if (exp == '+')
	{
		return left+right;
	}
	if (exp == '-')
	{
		return left -right;
	}
	return ERROR_VALUE;
};
//四则混合运算式计算
int calculate_expression(char *expession)
{
	char *t = expession;
	char m;
	int n;
	while(*t!='\0')
	{
		switch (*t)
		{
		case '+':
		case '*':
		case '/':
		case '(':
			cs_push(*t);
			break;
		case '-':
			//使用"+(-1)*"来代替"-",可以避免*(-3),这样的负数带来的影响
			cs_push('+');
			cs_push('*');
			is_push(-1);
			break;
		case ')':
			//数据栈顶两个元素用运算符栈顶的元素计算后入数据栈,要直找到'('的位置才结束计算
			m = cs_pop();
			do 
			{
				int r = is_pop();
				int l = is_pop();
				n = calculate(l,r,m);
				is_push(n);
				m = cs_pop();
			} while (m!='(');

			//把括号左边的最近的乘除法先计算出来,注意,加减不能算,因为括号后面还有可能有乘除法。
			m = cs_pop();
			if ( m=='*' || m == '/')
			{
				int r = is_pop();
				int l = is_pop();
				n = calculate(l,r,m);
				is_push(n);
			}
			else if (m>0)
			{
				cs_push(m);
			}

			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			{
				//如果有连续-9数字则组合为一个数字进栈
				char str[8];
				int i = 0;
				while( *t>='0' && *t <= '9')
				{
					str[i] = *t;
					i++;
					t++;
				}
				str[i] = '\0';
				t--;

				n = atoi(str);
				is_push(n);

				//把数值左边的最近的乘除法先计算出来,注意,加减不能算,因为数值后面还有可能有乘除法。
				m = cs_pop();
				if ( m=='*' || m == '/')
				{
					int r = is_pop();
					int l = is_pop();
					n = calculate(l,r,m);
					is_push(n);
				}
				else if (m>0)
				{
					cs_push(m);
				}
			}
			break;

		default:
			printf("expression input error!");
			break;
		}
		t++;
	}

	//上面已经做完所有乘法和括号的运算,若还有加减法没做完,把剩下的工作做完
	while ((m = cs_pop())>0)
	{
		int r = is_pop();
		int l = is_pop();
		n = calculate(l,r,m);
		is_push(n);
	}
	printf("the result is %d",n);
	return n;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是C语言利用栈求表达式的值的代码,可以完成加减乘除及带括号的四则混合整数运算: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define STACK_INIT_SIZE 20 #define STACK_INCREMENT 10 typedef struct { int *base; int *top; int stacksize; } StackInt; void InitStackInt(StackInt *S) { S->base = (int *) malloc(STACK_INIT_SIZE * sizeof(int)); if (!S->base) { printf("InitStackInt: Memory allocation failed.\n"); exit(1); } S->top = S->base; S->stacksize = STACK_INIT_SIZE; } void DestroyStackInt(StackInt *S) { free(S->base); S->base = NULL; S->top = NULL; S->stacksize = 0; } void PushInt(StackInt *S, int e) { if (S->top - S->base >= S->stacksize) { S->base = (int *) realloc(S->base, (S->stacksize + STACK_INCREMENT) * sizeof(int)); if (!S->base) { printf("PushInt: Memory allocation failed.\n"); exit(1); } S->top = S->base + S->stacksize; S->stacksize += STACK_INCREMENT; } *(S->top++) = e; } void PopInt(StackInt *S, int *e) { if (S->top == S->base) { printf("PopInt: Stack is empty.\n"); exit(1); } *e = *(--S->top); } int GetTopInt(StackInt *S) { if (S->top == S->base) { printf("GetTopInt: Stack is empty.\n"); exit(1); } return *(S->top - 1); } int IsEmptyInt(StackInt *S) { if (S->top == S->base) return 1; else return 0; } int IsOperator(char c) { if (c == '+' || c == '-' || c == '*' || c == '/') return 1; else return 0; } int OperatorPriority(char c) { if (c == '+' || c == '-') return 1; else if (c == '*' || c == '/') return 2; else return 0; } int Calculate(int a, int b, char op) { int result; switch (op) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': result = a / b; break; } return result; } int EvaluateExpression(char *s) { StackInt numStack, opStack; InitStackInt(&numStack); InitStackInt(&opStack); char *p = s; while (*p != '\0') { if (isdigit(*p)) { int num = 0; while (isdigit(*p)) { num = num * 10 + (*p - '0'); p++; } PushInt(&numStack, num); } else if (IsOperator(*p)) { while (!IsEmptyInt(&opStack) && OperatorPriority(*p) <= OperatorPriority(GetTopInt(&opStack))) { int b, a, result; PopInt(&numStack, &b); PopInt(&numStack, &a); PopInt(&opStack, (int *) &result); PushInt(&numStack, Calculate(a, b, result)); } PushInt(&opStack, *p); p++; } else if (*p == '(') { PushInt(&opStack, *p); p++; } else if (*p == ')') { while (GetTopInt(&opStack) != '(') { int b, a, result; PopInt(&numStack, &b); PopInt(&numStack, &a); PopInt(&opStack, (int *) &result); PushInt(&numStack, Calculate(a, b, result)); } int temp; PopInt(&opStack, &temp); p++; } else { p++; } } while (!IsEmptyInt(&opStack)) { int b, a, result; PopInt(&numStack, &b); PopInt(&numStack, &a); PopInt(&opStack, (int *) &result); PushInt(&numStack, Calculate(a, b, result)); } int result; PopInt(&numStack, &result); DestroyStackInt(&numStack); DestroyStackInt(&opStack); return result; } int main() { char s[100]; printf("Enter an expression: "); scanf("%s", s); int result = EvaluateExpression(s); printf("Result: %d\n", result); return 0; } ``` 该代码使用两个栈,一个存储数字,一个存储运算符,通过扫描表达式字符串,将数字和运算符入栈,并在遇到右括号时,将栈中的数字和运算符出栈,计算结果并将结果入栈,直到遇到左括号为止。最后,将栈中的数字出栈得到表达式的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值