【LeetCode|编译原理】剑指 Offer 20. 表示数值的字符串

文章目录

    • 题目链接
    • 标签
    • 步骤
    • 实现代码(C++)

题目链接

剑指 Offer 20. 表示数值的字符串

标签

有限状态自动机(FA)

步骤

Step1. 去除字符串左、右空格;

string strip(string str) {
    int start = -1;
    for (int i = 0; i < str.length(); i++) {
        if (str[i] != ' ') {
            start = i;
            break;
        }
    }
    if (start == -1) return str;
    int end = -1;
    for (int i = str.length() - 1; i >= 0; i--) {
        if (str[i] != ' ') {
            end = i;
            break;
        }
    }
    return str.substr(start, end - start + 1);
}

Step2. 写出正规文法:
S → ( + ∣ − ∣ ϵ ) ( I N T ∣ F L O A T ) E X P I N T → d i g i t ( d i g i t ) ∗ F L O A T → d i g i t ( d i g i t ) ∗ . ( d i g i t ) ∗ ∣ . d i g i t ( d i g i t ) ∗ E X P → ( + ∣ − ∣ ϵ ) I N T ∣ ϵ \mathrm{S}\rightarrow (+|-|\mathrm{\epsilon )(INT}|\mathrm{FLOAT)EXP} \\ \mathrm{INT}\rightarrow \mathrm{digit(digit)}^* \\ \mathrm{FLOAT}\rightarrow \mathrm{digit(digit)}^*.(\mathrm{digit)}^*|.\mathrm{digit(digit)}^* \\ \mathrm{EXP}\rightarrow (+|-|\mathrm{\epsilon )INT}|\mathrm{\epsilon} S(+ϵ)(INTFLOAT)EXPINTdigit(digit)FLOATdigit(digit).(digit)∣.digit(digit)EXP(+ϵ)INTϵ

Step3. 根据正规文法画出NFA:

【LeetCode|编译原理】剑指 Offer 20. 表示数值的字符串_第1张图片

Step4. 根据NFA写代码:从左至右遍历,遇到包含ε的转移,单独处理。遍历完成后,看状态是否为终态(2、4、7),是则返回 true,否则 false。

for (int i = 0; i < str.length(); i++) {
    char ch = str[i];
    switch (state) {
        case 0:
            if (isFlag(ch)) {
                state = 1;
            } else {
                state = 1;
                i--; // 处理ε情况,i--
            }
            break;
        case 1:
            if (isDigit(ch)) {
                state = 2;
            } else if (ch == '.') {
                state = 3;
            } else {
                return false;
            }
            break;
        case 2:
            if (isDigit(ch)) {
                state = 2;
            } else if (ch == '.') {
                state = 4;
            } else if (ch == 'e' || ch == 'E') {
                state = 5;
            } else {
                return false;
            }
            break;
        case 3:
            if (isDigit(ch)) {
                state = 4;
            } else {
                return false;
            }
            break;
        case 4:
            if (isDigit(ch)) {
                state = 4;
            } else if (ch == 'e' || ch == 'E') {
                state = 5;
            } else {
                return false;
            }
            break;
        case 5:
            if (isFlag(ch)) {
                state = 6;
            } else {
                state = 6;
                i--; // 处理ε情况,i--
            } 
            break;
        case 6:
            if (isDigit(ch)) {
                state = 7;
            } else {
                return false;
            }
            break;
        case 7:
            if (isDigit(ch)) {
                state = 7;
            } else {
                return false;
            }
            break;
    }
}

实现代码(C++)

class Solution {
public:
    string strip(string str) {
        int start = -1;
        for (int i = 0; i < str.length(); i++) {
            if (str[i] != ' ') {
                start = i;
                break;
            }
        }
        if (start == -1) return str;
        int end = -1;
        for (int i = str.length() - 1; i >= 0; i--) {
            if (str[i] != ' ') {
                end = i;
                break;
            }
        }
        return str.substr(start, end - start + 1);
    }
    bool isDigit(char c) {
        if (c >= '0' && c <= '9') {
            return true;
        }
        return false;
    }
    bool isFlag(char c) {
        if (c == '+' || c == '-') {
            return true;
        }
        return false;
    }
    bool isNumber(string s) {
        int len = s.length();
        // step 1/4:去除首尾空格
        string str = strip(s);
        int state = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str[i];
            switch (state) {
                case 0:
                    if (isFlag(ch)) {
                        state = 1;
                    } else {
                        state = 1;
                        i--;
                    }
                    break;
                case 1:
                    if (isDigit(ch)) {
                        state = 2;
                    } else if (ch == '.') {
                        state = 3;
                    } else {
                        return false;
                    }
                    break;
                case 2:
                    if (isDigit(ch)) {
                        state = 2;
                    } else if (ch == '.') {
                        state = 4;
                    } else if (ch == 'e' || ch == 'E') {
                        state = 5;
                    } else {
                        return false;
                    }
                    break;
                case 3:
                    if (isDigit(ch)) {
                        state = 4;
                    } else {
                        return false;
                    }
                    break;
                case 4:
                    if (isDigit(ch)) {
                        state = 4;
                    } else if (ch == 'e' || ch == 'E') {
                        state = 5;
                    } else {
                        return false;
                    }
                    break;
                case 5:
                    if (isFlag(ch)) {
                        state = 6;
                    } else {
                        state = 6;
                        i--;
                    } 
                    break;
                case 6:
                    if (isDigit(ch)) {
                        state = 7;
                    } else {
                        return false;
                    }
                    break;
                case 7:
                    if (isDigit(ch)) {
                        state = 7;
                    } else {
                        return false;
                    }
                    break;
            }
        }
        string finalState = "247";
        return finalState.find(state+'0', 0) == string::npos ? false : true;
    }
};

你可能感兴趣的:(C++,编译原理,leetcode,编译原理,NFA)