1. 程式人生 > >【資料結構】順序棧 Stack

【資料結構】順序棧 Stack

#include "calculator.h"
#include <iostream>
using namespace std;

//construction
Calculator::Calculator(){
	command=' ';
}

//get_command
void Calculator::get_command(){
	bool waiting =true;
	cout<<"Select command and press <Enter>:";
	while(waiting){
		cin>>command;
		command=tolower(command);
		if(command=='?'||command=='='||command=='+'||
			command=='-'||command=='*'||command=='/'||
			command=='q'||command=='c')
			waiting=false;
		else 
			cout<<"Please enter a valid command:"<<endl
			<<"[?]push to stack [=]print top "<<endl
			<<"[+][-][*][/] are arithmetic operations"<<endl
			<<"[c]clean the stack"<<endl
			<<"[Q] quit"<<endl;
	}
}
//do_command
bool Calculator::do_command(){
	get_command();
	switch(command){
		case '?':
			PutInNum();
			break;
		case '+':
			Add();
			break;
		case '-':
			Sub();
			break;
		case '*':
			Mul();
			break;
		case '/':
			Div();
			break;
		case 'c':
			Clear();
			break;
		case '=':
			ShowResult();
			break;
		case 'q':
			return false;
	}
	return true;
}
//Once enter '?': put the next number into stack
void Calculator::PutInNum(){
	Stack_entry p;
	cout<<"Enter a real number: "<<flush;
	cin>>p;
	if(numbers.push(p)==overflow)
	cout<<"Warning:Stack full,lost number"<<endl;
}

//Once enter '+' : Add the numbers in the stack
void Calculator::Add(){
	Stack_entry p,q;
	if(numbers.top(p)==underflow)
		cout<<"Stack empty"<<endl;
	else{ 
		numbers.top(p);
		numbers.pop();
		if(numbers.top(q)==underflow){
			cout<<"Stack has just one entry"<<endl;
			numbers.push(p);
		}
		else{
			numbers.pop();
			if(numbers.push(p+q)==overflow)
				cout<<"Warning:Stack full,lost result"<<endl;
		}
	}
}
//Once enter '-': Subtract the numbers in the stack
void Calculator::Sub(){
	Stack_entry p,q;
	if(numbers.top(p)==underflow)
		cout<<"Stack empty"<<endl;
	else{ 
		numbers.top(p);
		numbers.pop();
		if(numbers.top(q)==underflow){
			cout<<"Stack has just one entry"<<endl;
			numbers.push(p);
		}
		else{
			numbers.pop();
			if(numbers.push(q-p)==overflow)
				cout<<"Warning:Stack full,lost result"<<endl;
		}
	}
}
//Once enter'*': Multiply the numbers in the stack
void Calculator::Mul(){
	Stack_entry p,q;
	if(numbers.top(p)==underflow)
		cout<<"Stack empty"<<endl;
	else{ 
		numbers.top(p);
		numbers.pop();
		if(numbers.top(q)==underflow){
			cout<<"Stack has just one entry"<<endl;
			numbers.push(p);
		}
		else{
			numbers.pop();
			if(numbers.push(p*q)==overflow)
				cout<<"Warning:Stack full,lost result"<<endl;
		}
	}
}
//Once enter '/': Divide the numbers in the stack 
void Calculator::Div(){
	Stack_entry p,q;
	if(numbers.top(p)==underflow)
		cout<<"Stack empty"<<endl;
	else{ 
		numbers.top(p);
		numbers.pop();
		if(p==0){
			cout<<"Bed command! The second number is 0 and cannot finishi divide command!"<<endl;
		}
		else if(numbers.top(q)==underflow){
			cout<<"Stack has just one entry"<<endl;
			numbers.push(p);
		}
		else{
			numbers.pop();
			if(numbers.push(q/p)==overflow)
				cout<<"Warning:Stack full,lost result"<<endl;
		}
	}
}
//Once enter '=':Show the result of least command
void Calculator::ShowResult(){
	Stack_entry p;
	if(numbers.top(p)==underflow)
		cout<<"Stack empty"<<endl;
	else
		cout<<p<<endl;
}
//Once enter 'q':Stop the calculation
void Calculator::Quit(){
	cout<<"Calculation finished!"<<endl;
}
//Once enter 'c':Clear the stack
void Calculator::Clear(){
	numbers.clear();
}

【過程記錄】

實驗截圖:

【結果分析】

1.實驗中我以課本中計算器的實驗為例,實現並驗證了順序棧各種基本運算。
2.計算器的實現:當用戶輸入“?”時,程式將將即將輸入的數壓入棧中;當用戶輸入“+”“-”“*”“/”等基本運算子,彈出之前被壓入的數字做相應的運算,並將結果壓入棧中。當用戶輸入“=”時,彈出並顯示上一步運算的結果。
3.依照書中的基本思想,我實現了計算器的運算,並做了一些相應的改變:
(1)將計算器作為一個類實現,從而將計算器中用以儲存資料的棧作為私有資料成員,用以實現各種操作的函式作為保護成員函式更好的封裝起來,對使用者只留有命令介面。這樣簡化了主函式,也方便以後的使用。
(2)由於計算器中運算資料儲存在有一定限制的棧中,多次元素按之後可能會使棧狀態變為full,所以我增加了名為clear()的函式可以清空棧。
4.實驗中我遇到的問題:
(1)要注意棧“先進後出”的特點,所以容易弄錯運算數的順序(加法、乘法並沒有影響,但減法和除法運算就可能出現問題),即棧中第一次彈出的資料是第二個運算元,第二次彈出的資料是第一個運算元。
(2)編寫計算器的建構函式時,發現數據成員command(char型別)並不能預設為‘’,但可以是空格‘ ’,之前並沒有注意到這種區別。
(3)驗證時,我發現當輸入“?”之後,如果我輸入的不是預設要輸入的double型別,例如輸入“a”等字母,程式沒有報錯,反而是出現死迴圈,對於這個問題我並沒有解決。