1. 程式人生 > >Vijos P1849 表示式求值【有限狀態自動機】

Vijos P1849 表示式求值【有限狀態自動機】

描述

給定一個只包含加法和乘法的算術表示式,請你程式設計計算表示式的值。

格式

輸入格式

輸入僅有一行,為需要你計算的表示式,表示式中只包含數字、加法運算子“+”和乘法運算子“*”,且沒有括號,所有參與運算的數字均為 0 到 2 ^ 31 -1 之間的整數。輸入資料保證這一行只有 0~ 9、+、*這 12 種字元。

輸出格式

輸出只有一行,包含一個整數,表示這個表示式的值。注意:當答案長度多於 4 位時,請只輸出最後 4 位,前導 0 不輸出。

樣例1

樣例輸入1

1+1*3+4

樣例輸出1

8

樣例2

樣例輸入2

1+1234567890*1

樣例輸出2

7891

樣例3

樣例輸入3

1+1000000003*1

樣例輸出3

4

限制

每個測試點1s。

提示

樣例解釋:
樣例 1 計算的結果為 8,直接輸出 8。
樣例 2 計算的結果為 1234567891,輸出後 4 位,即 7891。
樣例 3 計算的結果為 1000000004,輸出後 4 位,即 4。

對於 30%的資料,0≤表示式中加法運算子和乘法運算子的總數≤100;
對於 80%的資料,0≤表示式中加法運算子和乘法運算子的總數≤1000;
對於 100%的資料,0≤表示式中加法運算子和乘法運算子的總數≤100000。

來源

NOIP 2013 普及組


問題分析

表示式識別是計算機語言程式處理的基本問題。

簡單的語法識別可以有限狀態自動機來實現。這種方法機械有效,邏輯相對比較簡單易懂。

程式說明

有關狀態,參見程式程式碼註釋。

題記

語法識別是電腦科學的最基本的話題。

參考連結:(略)

AC的C++程式如下:

#include <iostream>
#include <cstdio>

using namespace std;

/*
 * status=1 d
 * status=2 d+ or d*
 * status=3 d+d
 * status=4 d+d*
 *
 */

const int MOD = 10000;

int main()
{
    long long operand1, operand2, operand3, status;
    char op1, op2;


    scanf("%lld", &operand1);
    operand1 %= MOD;
    status = 1;
    for(;;) {
        if(status == 1) {
            scanf("%c", &op1);
            if(op1 == '+' || op1 == '*')
                status = 2;
            else
                break;
        } else if(status == 2) {
            scanf("%lld", &operand2);
            if(op1 == '*') {
                operand1 *= operand2;
                operand1 %= MOD;
                status = 1;
            } else if(op1 == '+')
                status = 3;
        } else if(status == 3) {
            scanf("%c", &op2);
            if(op2 == '*')
                status = 4;
            else if(op2 == '+') {
                operand1 += operand2;
                operand1 %= MOD;
                op1 = op2;
                status = 2;
            } else {
                operand1 += operand2;
                operand1 %= MOD;
                break;
            }
        } else if(status == 4) {
            scanf("%lld", &operand3);
            operand2 *= operand3;
            operand2 %= MOD;
            status = 3;
        } else
            break;
    }
    cout << operand1 << endl;

    return 0;
}