1. 程式人生 > >資料結構---棧和佇列(例題、練習及解答)

資料結構---棧和佇列(例題、練習及解答)

棧的應用

Q1:簡單表示式求值

限定的簡單表示式求值問題是使用者輸入一個包含+、-、*、/、正整數和圓括號的合法算術表示式,計算該表示式的結果。

思路:(1)將算術表示式轉換成字尾表示式

(2)字尾表示式求值

具體執行程式碼:

#include <iostream>
using namespace std;
#define MaxSize 50

typedef char ELemType;                                //儲存字尾表示式的運算子棧,char型別
typedef struct {
	ELemType data[MaxSize];
	int top;
}SqStack;
void initStack(SqStack* &s) {
	s = (SqStack*)malloc(sizeof(SqStack));
	s->top = -1;
}
bool Pop(SqStack* s, ELemType &e) {
	if (s->top == -1) return false;
	e = s->data[s->top];
	s->top--;
	return true;
}
bool Push(SqStack* s, ELemType e) {
	if (s->top == MaxSize - 1) return false;
	s->top++;
	s->data[s->top] = e;
	return true;
}
bool StackNotEmpty(SqStack* &s) {
	return s->top != -1;
}
ELemType GetTop(SqStack* s) {
	return s->data[s->top];
}

typedef double ELemType1;                   //儲存運算資料的棧,最後剩下的棧中元素即為運算結果
typedef struct {                            //為double型別,具體實現完全同上
	ELemType1 data[MaxSize];
	int top;
}SqStack1;
void initStack(SqStack1* &s) {
	s = (SqStack1*)malloc(sizeof(SqStack1));
	s->top = -1;
}
bool Pop(SqStack1* s, ELemType1 &e) {
	if (s->top == -1) return false;
	e = s->data[s->top];
	s->top--;
	return true;
}
bool Push(SqStack1* s, ELemType1 e) {
	if (s->top == MaxSize - 1) return false;
	s->top++;
	s->data[s->top] = e;
	return true;
}
bool StackNotEmpty(SqStack1* &s) {
	return s->top != -1;
}
ELemType1 GetTop(SqStack1* s) {
	return s->data[s->top];
}

void trans(char exp[], char postexp[]) {            //把算式轉換為字尾表示式,儲存在char型陣列postexp中
	SqStack* Optr;
	initStack(Optr);
	int i = 0, j=0;
	while (exp[i] != '\0') {
		switch (exp[i]) {
		case '+':
		case '-':
			while (StackNotEmpty(Optr) && (GetTop(Optr) != '(')) {
				ELemType temp;
				Pop(Optr, temp);
				postexp[j] = temp;
				j++;
			}
			Push(Optr, exp[i]);
			i++;
			break;
		case '*':
		case '/':
			while (StackNotEmpty(Optr) && (GetTop(Optr) != '(')
				&& (GetTop(Optr) != '+') && (GetTop(Optr) != '-')) {
				ELemType temp;
				Pop(Optr, temp);
				postexp[j] = temp;
				j++;
			}
			Push(Optr, exp[i]);
			i++;
			break;
		case ')':
			while (StackNotEmpty(Optr) && (GetTop(Optr) != '(')) {
				ELemType temp;
				Pop(Optr, temp);
				postexp[j] = temp;
				j++;
			}
			if (GetTop(Optr) == '(') {
				ELemType temp;
				Pop(Optr, temp);
			}
			i++;
			break;
		case '(':
			Push(Optr, exp[i]);
			i++;
			break;
		default:
			postexp[j] = exp[i];
			j++;
			i++;
			if (exp[i]<'0' || exp[i]>'9') { 
				postexp[j] = '#'; 
				j++;
			}
			break;
		}
	}
	while (StackNotEmpty(Optr)) {
		ELemType temp;
		Pop(Optr, temp);
		postexp[j] = temp;
		j++;
	}
}

double compvalue(char postexp[], int n) {            //對字尾表示式進行求值
	SqStack1* s1;
	initStack(s1);
	for (int i = 0; i < n; i++) {
		double d = 0;
		if (postexp[i] >= '0'&&postexp[i] <= '9') {
			while (postexp[i]!='#') {
				d = 10 * d + postexp[i] - '0'; 				i++;
			}
			Push(s1, d);
		}
		else if (postexp[i] == '*'|| postexp[i] == '/' || postexp[i] == '+' || postexp[i] == '-') {
			double a, b;
			Pop(s1, a);
			Pop(s1, b);
			switch (postexp[i]) {
			case '*':
				Push(s1, a*b);
				break;
			case '/':
				Push(s1, b/a);
				break;
			case '+':
				Push(s1, a+b);
				break;
			case '-':
				Push(s1, b-a);
				break;
			}
		}
	}
	double result;
	Pop(s1, result);
	return result;
}

int main() {
	char exp[] = "(56-20)/(4+2)";
	char postexp[13];
	trans(exp, postexp);
	for (int i = 0; i < 13; i++) {
		cout << postexp[i];
	}
	cout << endl << endl;
	cout << compvalue(postexp, 13) << endl;

	system("pause");
}