C language_Expression calculation_Infix to suffix_Multi-digit calculation

  A good brother asked me a program for expression calculation, the main exercise stack. But he asked me a question, if you calculate with multiple digits, it seems that the regular expression conversion will not work. That is, the conventional program can only calculate numbers below 10, and explore this problem.
  For example, the conventional method, the generated suffix expression will be like this: 123-*, so it is impossible to judge whether it is 1 or 12. That is, it fails for multiple digits. FinalizedThe idea is to judge the number in the process of converting the infix to the suffix: if it is a multi-digit number, it is separated by a space. At the same time, in the suffix calculation, always check the existence of spaces, and finally complete the calculation. The source code is as follows:

#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;
}

  The calculation result is as follows:
  Enter the infix expression as: 10-6*(12-8/4)+3
Insert picture description here

Guess you like

Origin blog.csdn.net/gls_nuaa/article/details/111872805