演算法~簡單的計算器(驗證數學表示式是否合法~“狀態機思想”)
(有限狀態機思想~進行狀態轉化,每個狀態下,再進行判斷是否轉化狀態)
1,為什麼儲存結構選擇~棧?
因為棧可以去除括號,處理優先順序~
舉例:14-(5-6)
2,計算思路:
(1)全域性變數compute_flag 標誌是否可以進行計算,初始comute_flag = 0; 遇到 “+”或者“-”時,compute_flag = 1;
遇到“(”,compute_flag = 0;
(2)字串數處理為整型數:number = number * 10 + ch - ‘0’;
【ps舉例:String s="1234"; for(int i = 0; i < s.length(); i++){ number = number*10+s[i]-'0'; }】~‘ascall 碼 相減(- ‘0’)獲取該值 ’。
(3)狀態機過程:迴圈遍歷所有字串元素:判斷第一個字串元素是否為空,空~continue;非空,進入startState~
stateState:若是(“0”~“9”)~進入numberState 狀態;若是“(” 進入operationState狀態。
然後,“退格”【因為迴圈體內部最後一行程式碼是 i++,退格回到s[i] 本身,進入numState 狀態/opState狀態。】
(全域性變數:state、startState、numberState、opState)
(4) numberState 狀態:
如果遇到(“0”~“9”){//處理轉化為整型數:number = number*10+s[i]-'0'; },否則 {
1,先將數number 壓入數字棧number_stack; [字串元素 1 2 3 + 遇到 + ,才知道前三個元素構成一個數字]
2, 判斷compute_state 是否為1,為1,則進行計算;
3,num=0;進入操作符狀態operationState~【遇到 +】,退格 i--;}
(5) operationState狀態:{
1,判斷是“+” 或“-”,壓入操作符棧operation_stack; 修改compute_flag = 1;
2,如果 遇到 "(", 修改compute_flag = 0; 進入數字狀態 numberState~
3,如果遇到(“0”~“9”),進入數字狀態 numberState,退格i --; ~
4,如果 遇到 ")", 直接進行計算
}
(6)最後一個數number的處理【為什麼有最後一個數 ,因為 之前的字串元素 1 2 3 + 遇到 + ,才知道前三個元素構成一個數字,將數壓棧,
但是最後一個數是因為遍歷結束,並非有 “+”的提示】:
如果number != 0,則 壓入數字棧number_stack,然後進行計算;
如果number == 0 且 棧空了,結果就是 0;
3,程式碼:
❀ 計算方法:
/** * 計算 */ void compute(std::stack<int> &number stack, std:: stack<char> &operation_stack){ if(number_state.size() < 2){ return; } int num2 = number_state.top(); number_state.pop(); int num1 = number_state.top(); number_state.pop(); if(operation_stack.top() == '+'){ number_state.push(num1 + num2); }else if(operation_stack.top() == '-'){ number_state.push(num1 - num2); } operation_stack.pop(); }
❀ “狀態機”過程的計算方法:
int calculate(std::String s){ static const int START_STATE = 0; static const int NUMBER_STATE = 1; statci const int OPERATION_STATE = 2; std::stack<int> number_stack; std::stack<char> operation_stack; int number = 0; //用於將字串數處理為整型數 int STATE = START_STATE; int compute_flag = 0; //全域性變數compute_flag 標誌是否可以進行計算 for(int i = 0; i < s.length(); i++){ if(s[i] == '') continue; switch (STATE){ case START_STATE: if(s[i] >= '0' && s[i] <= '9'){ STATE = NUMBER_STATE; }else { STATE = OPERATION_STATE; } i--; //退格,因為迴圈體內部最後一行程式碼是 i++,退格回到s[i] 本身 break; case NUMBER_STATE: if(s[i] >= '0' && s[i] <= '9'){ number = number * 10 + s[i] - '0'; }else{ number_stack(number); if(compute_flag == 1){ compute(number_stack,operation_stack); } number = 0; STATE = OPERATION_STATE; i--; //退格 } break; case OPERATION_STATE: if(s[i] == '+' || s[i] == '-'){ operation_stack.push(s[i]); compute_flag = 1; }else if(s[i] == '('){ STATE = NUMBER_STATE; compute_flag = 0; }else if(s[i] >= '0' && s[i] <= '9'){ STATE = NUMBER_STATE; i--; }else if(s[i] == ')'){ compute(number_stack,operation_stack); } break; } } //最後遍歷湊成的一個數 if(number != 0){ number_stack.push(number); compute(number_stack,operation_stack); }else if(number == 0 && number_stack.empty()){ return 0; } return number_stack.top(); }