Use stack to calculate prefix expression (implement calculator function)

Recently, I learned the stack part of data structure and algorithm, followed the video tutorial of little turtle step by step, wrote code to consolidate some problems, and shared them on the blog. On the one hand, I recorded my learning process, on the other hand, I often check other people's blogs on the Internet to solve problems, and I should learn from them, It's great if what you write can help others.
To get back to the point, about the stack to realize the calculator function, that is, keyboard input (1.2 + 3) (4-5.5), you can get - 6.3, which involves the conversion of prefix expression (1.2 + 3) (4-5.5) to infix expression 1.23 + 45.5 - *, and the process of calculating the result through infix expression. For the specific principle, please refer to the description of little turtle Video link The p27 28 29 part of is implemented in C language. I use C + + here. I only tested the correctness of the final version and did not compare it with his method. The code is given below:
These are some functions about header file and stack processing:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <ctype.h>
using namespace std;

const int stackMaxLen = 10;

template<class T>
struct Stack
{
	int stacklen;
	T *base;
	T *top;
};

enum STATE
{
	SUCCESS,
	ERROR,
};

template<class T>
Stack<T>* CreatStack()
{
	Stack<T>* p = new Stack<T>;
	p->base = new T[stackMaxLen];
	p->top = p->base;
	p->stacklen = stackMaxLen;
	return p;
}

template<class T>
void DeleteStack(Stack<T>* p)
{
	delete[] p->base;
	if (p)
		delete p;
}

template<class T>
int GetStackFree(Stack<T>* p)
{
	return p->stacklen - (p->top - p->base);
}

template<class T>
void AppendStack(Stack<T>* p)
{
	//Length 0, open up a new space
	int newlen = p->stacklen + stackMaxLen;
	T *temp = new T[newlen];
	memcpy(temp, p->base, sizeof(T)* p->stacklen);
	//Release the previous stack
	delete[] p->base;

	p->base = temp;
	p->top = p->base + p->stacklen;
	p->stacklen = newlen;
}

template<class T>
void Push(Stack<T>* p, T data)
{
	if (GetStackFree(p) == 0)
	{
		AppendStack(p);
	}
	else
	{
		*p->top = data;
		p->top++;
	}
}

template<class T>
STATE Pop(Stack<T>* p, T& data)
{
	if (p->top == p->base)
		return ERROR;
	else
	{
		data = *--p->top;
		return SUCCESS;
	}
}

The function template is used because I use the char stack and the double stack respectively. Of course, it may be better to encapsulate these functions as classes here. But I'm too lazy to do it ~ ~ ~.
The following is the function to obtain infix expression through prefix expression. Here I save infix expression into a char array, and each variable is separated by spaces:

char* GetNifixExp()
{
	cout << "Please enter a prefix expression with´╝âKey end:" << endl;
	Stack<char> *symbolStack = CreatStack<char>();
	char c;
	char *nifixExp = new char[30];
	memset(nifixExp, 0, sizeof(char) * 30);
	int nifixIdx = 0;
	scanf("%c", &c);
	while (c != '#')
	{
		if (c == '+' || c == '-' || c == '/' || c == '*' || c == '(' || c == ')')
		{
			if (c == ')')
			{
				nifixExp[nifixIdx++] = ' ';
				while (Pop(symbolStack, c) == SUCCESS)
				{
					if (c == '(')
					{
						break;
					}
					nifixExp[nifixIdx++] = c;
					nifixExp[nifixIdx++] = ' ';
				}
			}
			else if (c == '+' || c == '-')
			{
				nifixExp[nifixIdx++] = ' ';
				char after;
				if (Pop(symbolStack, after) == SUCCESS)
				{
					if (after == '*' || after == '/')
					{
						nifixExp[nifixIdx++] = after;
						nifixExp[nifixIdx++] = ' ';
						char afterMulti;
						while (Pop(symbolStack, afterMulti) == SUCCESS)
						{
							nifixExp[nifixIdx++] = afterMulti;
							nifixExp[nifixIdx++] = ' ';
						}
					}
					else
					{
						Push(symbolStack, after);
					}
				}
				Push(symbolStack, c);
			}
			else
			{
				if(c == '*' || c == '/')
					nifixExp[nifixIdx++] = ' ';
				Push(symbolStack, c);
			}

		}
		else if (c >= '0' && c <= '9' || c == '.')
		{
			nifixExp[nifixIdx++] = c;
		}
		scanf("%c", &c);
	}
	while (Pop(symbolStack, c) == SUCCESS)
	{
		nifixExp[nifixIdx++] = ' ';
		nifixExp[nifixIdx++] = c;
	}
	DeleteStack(symbolStack);
	getchar();
	return nifixExp;
}

The following is the infix expression calculated by stack:

double CalcNifixExp(char* nifixExp)
{
	Stack<double> *p = CreatStack<double>();
	char c;
	char g_c[10];
	int i = 0;
	c = *nifixExp++;
	double pre, aft;
	while (c != '\0')
	{
		while (c > '0' && c < '9' || c == '.')
		{
			g_c[i++] = c;
			g_c[i] = '\n';
			c = *nifixExp++;
			if (i > 10 || c == ' ')
			{
				double f = atof(g_c);
				Push(p, atof(g_c));
				i = 0;
				break;
			}

		}

		switch (c)
		{
		case '+':
			Pop(p, aft);
			Pop(p, pre);
			Push(p, pre + aft);
			break;
		case '-':
			Pop(p, aft);
			Pop(p, pre);
			Push(p, pre - aft);
			break;
		case '*':
			Pop(p, aft);
			Pop(p, pre);
			Push(p, pre * aft);
			break;
		case '/':
			Pop(p, aft);
			Pop(p, pre);
			if (aft == 0)
			{
				cout << "Divisor cannot be 0" << endl;
				break;
			}
			Push(p, pre / aft);
			break;
		default:
			break;
		}

		c = *nifixExp++;
	}
	Pop(p, aft);
	DeleteStack(p);

	return aft;
}

Finally, the main function:

int main()
{
	char* nifixExp = GetNifixExp();
	cout << "Infix expression is:" << nifixExp << endl;

	double result = CalcNifixExp(nifixExp);
	cout << "The calculation result is:" << result << endl;

	delete[] nifixExp;
	system("pause");
	return 0;
}

Of course, this is only the simplest calculator function, and there is no exception handling. If there are any bug s, you are welcome to point out. Finally, a screenshot of calculation results is attached:

Tags: C++ data structure stack

Posted on Sun, 28 Nov 2021 06:28:52 -0500 by help_needed