1. 程式人生 > >雙棧實現整數(支援大於十的整數)計算器【資料結構】

雙棧實現整數(支援大於十的整數)計算器【資料結構】

通過棧的操作實現簡單的計算器

首先定義兩個棧,一個叫s_num用來存放運算元,另一個叫s_opt用來存放操作符。

再定義一個字元陣列用來存放輸入的表示式,初始化為0;

當表示式的字元不為‘/0’時,或者操作符棧中不為空的時候,就要一直執行程式!

在執行的時候做兩個判斷,輸入的不是數字就是操作符,當輸入數字的時候進棧就可以了,並且i++,遍歷下一個。

當遇到操作符時:有三種情況

一、入棧的情況:(入棧結束後,i++,遍歷下一個輸入字元)

1.操作符棧為空的時候。

2.操作符的優先順序大於棧頂元素的時候。

3.當棧頂元素為’(‘時,並且輸入不為')'時。

二、出棧不計算(結束後,i++,遍歷下一個字元)

1.操作符出棧不計算的情況只有一種情況就是“(  ”操作符出棧的時候。

當輸入為“  )”時,並且棧頂為“(  ”時,就是兩個符號相遇時,出棧“(  ”並不計算。

三、出棧計算(計算完將數字存入s_num中就可以了,不需要遍歷下一個字元)

將輸入的字元與棧頂元素比較,滿足情況的話將棧頂元素出棧,並取num棧中的數字進行運算,這是不需要i++,遍歷下一個輸入字元,break後再將輸入的字元與棧頂元素比較,判斷是入棧還是出棧!!!

1.輸入的操作符為"/0"的時候,並且操作符棧不為空的時候,要將操作符中的所有元素出棧運算。

2.輸入的操作符優先順序小於或等於棧頂元素時。

3.當輸入的字元為“  )”時,並且棧頂元素不為“(  ”時。

#include <iostream>
#include <stack>

using namespace std;

stack<char> s_opt;//操作符棧
stack<int> s_num;//資料棧

int Priority(char ch){//判斷優先順序
	switch(ch){
		case '(':
			return 3;
		case '*':
		case '/':
			return 2;
		case '+':
		case '-':
			return 1;
		default:
			return 0;
	}
}

int main(){

	char opt[1024] = {0};
	int i = 0, tmp = 0, num1 = 0, num2 = 0;
	cout << "Please input: " << endl;
	cin >> opt;
	while(opt[i] != '\0' || s_opt.empty() != true){
        if(opt[i] >= '0' && opt[i] <= '9'){
            tmp = tmp * 10 + opt[i] - '0';
            i++;
            if(opt[i] > '9' || opt[i] < '0'){
                s_num.push(tmp);
                tmp = 0;

            }
        }
        else{
			if((opt[i] == ')') && (s_opt.top() == '(')){
				s_opt.pop();
				i++;
				continue;
			}

			if((s_opt.empty()) == true || (Priority(opt[i]) > Priority(s_opt.top()))||(s_opt.top() == '(' && (opt[i] != ')'))){
				s_opt.push( opt[i]);
				i++;
				continue;
			}

			if( ((opt[i] == '\0') &&( s_opt.empty() != true)) || ( (opt[i] == ')') && (s_opt.top() != '(') )||(Priority(opt[i]) <= Priority(s_opt.top()))	){
				char ch = s_opt.top();
				s_opt.pop();
				int num1,num2;
				switch(ch){
					case'+':
						num1 = s_num.top();
						s_num.pop();
						num2 = s_num.top();
						s_num.pop();
						s_num.push(num1 + num2);
						break;

					case'-':
						num1 = s_num.top();
						s_num.pop();
						num2 = s_num.top();
						s_num.pop();
						s_num.push(num2 - num1);//1 2
					break;
					case'*':
						num1 = s_num.top();
						s_num.pop();
						num2 = s_num.top();
						s_num.pop();
						s_num.push(num1 * num2);
					break;
					case'/':
						num1 = s_num.top();
						s_num.pop();
						num2 = s_num.top();
						s_num.pop();
						s_num.push(num1 / num2);
					break;
				}
			}
		}
	}

	cout << s_num.top() << endl;
	return 0;
}