演算法~簡單的計算器(驗證數學表示式是否合法~“狀態機思想”)

一樂樂發表於2021-08-05

演算法~簡單的計算器(驗證數學表示式是否合法~“狀態機思想”)

(有限狀態機思想~進行狀態轉化,每個狀態下,再進行判斷是否轉化狀態)

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();
}

 

 

 

 

 

 

 

 

 

 

相關文章