The realization of a simple calculator in the course design of data structure

1, Problem statement

Input an arithmetic expression (infix white master) from the keyboard, including parentheses, to calculate the value of the expression.
requirement:

  1. The program makes a simple judgment on the input expression, and gives a prompt in case of any error;
  2. Four arithmetic operations (+, -, *, /) and square (^) are implemented, which can handle binocular operators: + and -;
  3. Can convert infix arithmetic expression to suffix expression and output, and output operation result.

2, Outline design

2.1 overview

Infix expression is converted into suffix expression, and each number and symbol of infix expression is traversed from left to right. If the number is output, it becomes a part of suffix expression; if the symbol is, it is judged that the priority of infix expression and stack top symbol is right bracket or the priority is lower than the top symbol (multiplication, division, priority, addition and subtraction). Then the stack top element is found and output in turn, and the current symbol is put into the stack , until the final output suffix expression.
Postfix expressions are also known as Reverse Polish notation , the calculation method is: create a new expression, if the current character is a variable or a number, press the stack, if it is an operator, pop up the two elements at the top of the stack for corresponding operation, and then push the result into the stack. Finally, when the expression is scanned, the result is in the stack.

2.2 storage structure representation

typedef struct {//Digital stack structure
	double data[MAXSIZE];
	int top;
} opstack;

typedef struct {//Symbol stack structure
	char data[MAXSIZE];
	int top;
} stack;

2.3 detailed design

2.3.1 judge whether infix expression is reasonable
//Judge whether infix expression is reasonable
bool judge_infix(char str[]){
	int temp=0;
 	if(str[0]=='/'||str[0]=='*')
		return false;
	if(str[strlen(str)-1]<'0'&&str[strlen(str)-1]>'9')
		return false;
	for(int i=0; i<strlen(str); i++) {
		if(str[i]=='(') {
			if(i==0&&(str[i+1]=='*'||str[i+1]=='/'))
				return false;
			else if(str[i-1]>='0'&&str[i-1]<='9')
				return false;
			temp++;
		} else if(str[i]==')') {
			if(i==0)
				return false;
			else if(str[i-1]=='+'||str[i-1]=='*'||str[i-1]=='-'||str[i-1]=='/')
				return false;
			else if(str[i+1]>='0'&&str[i+1]<='9')
				return false;
			temp--;
		}
	}
	if(temp==0)
		return true;
	return false;
}
2.3.2 infix expression to suffix expression
  1. Create stack

  2. Traverse infix expressions from left to right:

    • Digital direct output
    • Operator:
      When '(' is encountered, it will directly enter the stack, and when it is encountered, it will output all the input data after '(' in the stack, and at the same time '(' will exit the stack but not output. Other symbols will stack the elements in the symbol stack and output them in turn until they encounter a symbol with a lower priority than the current symbol or '(', which will stack the current symbol.
  3. Output the remaining symbols in the stack in turn.

//Infix expression to suffix expression
void TranslateExpress(char str[], char exp[]) {
	stack s;
	char ch, e;
	int i=0, j=0;
	InitStack(&s);
	ch=str[i++];
	while(ch!='\0') {
		switch(ch) {
			case '(':
				Push(&s,ch);
				break;
			case ')':
				while (GetTop(s,&e)&&e!='(') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Pop(&s,&e);
				break;
			case '+':
			case '-':
				while (!StackEmpty(s)&&GetTop(s,&e)&&e!='(') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case '*':
			case '/':
				while(!StackEmpty(s)&&GetTop(s,&e)&&e=='/'||e=='*'||e=='^') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case '^':
				while(!StackEmpty(s)&&GetTop(s,&e)&&e=='^') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case ' ':
				break;
			default:
				while(ch>='0'&&ch<='9') {
					exp[j++]=ch;
					ch=str[i++];
				}
				i--;
				exp[j++]=' ';
		}
		ch=str[i++];
	}
	while(!StackEmpty(s)) {
		Pop(&s,&e);
		exp[j++]=e;
	}
	exp[j]='\0';
}

2.3.3 calculating suffix expression value

  1. Traverse the stack in turn
  2. Check whether it is a number. If it is a number, stack it. If the operator takes the right and left operands of the current operands from the stack in turn and performs operations with the current operator, stack the result.
  3. At the end of the traversal, the result is the top element of the stack.
//Evaluate expression value
double ComputeExpress(char a[]) {
	opstack s;
	int i=0, value;
	float x1, x2, result;
	s.top=-1;
	while (a[i]!='\0') {
		if(a[i]!=' '&&a[i]>='0'&&a[i]<='9') {
			value=0;
			while (a[i]!=' ') {
				value=10*value+a[i]-'0';
				i++;
			}
			s.top++;
			s.data[s.top]=value;
		} else {
			switch(a[i]) {
				case '+':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x1+x2;
					s.data[++s.top]=result;
					break;
				case '-':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x2-x1;
					s.data[++s.top]=result;
					break;
				case '*':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x1*x2;
					s.data[++s.top]=result;
					break;
				case '/':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x2/x1;
					s.data[++s.top]=result;
					break;
				case '^':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=pow(x2,x1);
					s.data[++s.top]=result;
					break;
			}
			i++;
		}
	}
	if(!s.top!=-1) {
		result=s.data[s.top];
		s.top--;
		if(s.top==-1)
			return result;
		else {
			printf("Expression error!");
			//exit(-1);
		}
	}
}

3, Testing and operation

3.1 judge whether the expression is correct

3.2 simple four operations

3.3 including square operation

4, Code implementation

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAXSIZE 50

typedef struct {//Digital stack structure
	double data[MAXSIZE];
	int top;
} opstack;

typedef struct {//Symbol stack structure
	char data[MAXSIZE];
	int top;
} stack;

//Initialization stack
void InitStack(stack *s) {
	s->top=0;
}

//Stack head
int GetTop(stack s, char *e) {
	if(s.top<=0)
		return 0;
	else {
		*e=s.data[s.top-1];
		return 1;
	}
}

//Stack out operation
void Pop(stack *s, char *e) {
	if(s->top<=0)
		printf("Stack empty!");
	else
		*e=s->data[--s->top];
}

//Push operation
void Push(stack *s, char e) {
	if(s->top>=MAXSIZE)
		printf("Stack full!");
	else
		s->data[s->top++]=e;
}

//Judge stack empty
int StackEmpty(stack s) {
	if(s.top==0)
		return 1;
	else return 0;
}

//Evaluate expression value
double ComputeExpress(char a[]) {
	opstack s;
	int i=0, value;
	float x1, x2, result;
	s.top=-1;
	while (a[i]!='\0') {
		if(a[i]!=' '&&a[i]>='0'&&a[i]<='9') {
			value=0;
			while (a[i]!=' ') {
				value=10*value+a[i]-'0';
				i++;
			}
			s.top++;
			s.data[s.top]=value;
		} else {
			switch(a[i]) {
				case '+':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x1+x2;
					s.data[++s.top]=result;
					break;
				case '-':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x2-x1;
					s.data[++s.top]=result;
					break;
				case '*':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x1*x2;
					s.data[++s.top]=result;
					break;
				case '/':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=x2/x1;
					s.data[++s.top]=result;
					break;
				case '^':
					x1=s.data[s.top--];
					x2=s.data[s.top--];
					result=pow(x2,x1);
					s.data[++s.top]=result;
					break;
			}
			i++;
		}
	}
	if(!s.top!=-1) {
		result=s.data[s.top];
		s.top--;
		if(s.top==-1)
			return result;
		else {
			printf("Expression error!");
			//exit(-1);
		}
	}
}

//Infix expression to suffix expression
void TranslateExpress(char str[], char exp[]) {
	stack s;
	char ch, e;
	int i=0, j=0;
	InitStack(&s);
	ch=str[i++];
	while(ch!='\0') {
		switch(ch) {
			case '(':
				Push(&s,ch);
				break;
			case ')':
				while (GetTop(s,&e)&&e!='(') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Pop(&s,&e);
				break;
			case '+':
			case '-':
				while (!StackEmpty(s)&&GetTop(s,&e)&&e!='(') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case '*':
			case '/':
				while(!StackEmpty(s)&&GetTop(s,&e)&&e=='/'||e=='*'||e=='^') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case '^':
				while(!StackEmpty(s)&&GetTop(s,&e)&&e=='^') {
					Pop(&s,&e);
					exp[j++]=e;
				}
				Push(&s,ch);
				break;
			case ' ':
				break;
			default:
				while(ch>='0'&&ch<='9') {
					exp[j++]=ch;
					ch=str[i++];
				}
				i--;
				exp[j++]=' ';
		}
		ch=str[i++];
	}
	while(!StackEmpty(s)) {
		Pop(&s,&e);
		exp[j++]=e;
	}
	exp[j]='\0';
}

//Judge whether infix expression is reasonable
bool judge_infix(char str[]){
	int temp=0;
 	if(str[0]=='/'||str[0]=='*')
		return false;
	if(str[strlen(str)-1]<'0'&&str[strlen(str)-1]>'9')
		return false;
	for(int i=0; i<strlen(str); i++) {
		if(str[i]=='(') {
			if(i==0&&(str[i+1]=='*'||str[i+1]=='/'))
				return false;
			else if(str[i-1]>='0'&&str[i-1]<='9')
				return false;
			temp++;
		} else if(str[i]==')') {
			if(i==0)
				return false;
			else if(str[i-1]=='+'||str[i-1]=='*'||str[i-1]=='-'||str[i-1]=='/')
				return false;
			else if(str[i+1]>='0'&&str[i+1]<='9')
				return false;
			temp--;
		}
	}
	if(temp==0)
		return true;
	return false;
}

int main() {
	char a[MAXSIZE],b[MAXSIZE];
	double f;
	int flag=0;
	printf("Please enter an arithmetic expression:");
	gets(a);
	printf("Infix expression is: %s\n",a);
	bool judge = judge_infix(a);
	if(judge == false){
        printf("Incorrect expression!\n");
        system("pause");
		exit(-1);
	}else
		TranslateExpress(a,b);
		printf("The suffix expression is: %s\n",b);
		f=ComputeExpress(b);
		printf("The calculation result is: %f\n",f);
	system("pause");
	return 0;
}

Posted on Sat, 20 Jun 2020 22:28:40 -0400 by amazing