1. 程式人生 > >【題解】Leetcode.65.Valid Number (qduoj.162.莫妮提)

【題解】Leetcode.65.Valid Number (qduoj.162.莫妮提)

題目大意 :
給出一個字串,判斷其是否是一個數字

題目沒有給出具體要求的格式,經過多次嘗試提交併修正後終於AC
最終通過的程式對數字的判斷符合以下幾點要求:
- 只考慮整數和小數的十進位制情況
- 允許前導0
- 小數允許省略整數或小數部分(不能同時省略)
- 允許科學計數法(大小寫e均可)
- 科學記數法e後只能為整數
- 允許正負號(+-)
- 忽略字串開頭和末尾的空格(但中間不能有空格)

思路:
簡單的確定性有限自動機
當最終狀態為2,3,5或8時返回true

typedef enum _Type {Sign,E,Dot,Num,No} Type;

inline Type type(char x){
    if(x >= '0' && x <= '9') return Num;
    if(x == '+' || x == '-') return Sign;
    if(x == 'E' || x == 'e') return E;
    if(x == '.') return Dot;
    return No;
}

bool isNumber(char * s){
    //  +0.0e+0
    // 0123567
8 // ___4____ 若出現小數點,如果小數點左邊沒有數字,則進入狀態4,否則進入狀態3 char *p, *end, state; for(end = s+strlen(s)-1;*end==' ';end--); //忽略末尾空格 for(p = s;*p==' ';p++); //忽略開頭空格 for(state = 0;p <= end;p++){ Type k = type(*p); if(k == No) return false; // 出現意料之外的字元直接返回false if(state < 6
) if(k == Num) state = state <3?2:5; else if(k == Sign) if(state == 0) state = 1; else return false; else if(k == E) if(state > 1 && state != 4) state = 6; else return false; else /*k == Dot */ if (state > 2) return false; else state = state<2?4:3; else if(k == Num) state = 8; else if(k == Dot || k == E) return false; else /* k == Sign */ if(state == 6) state = 7; else return false; } return state == 2 || state == 3 || state == 5 || state == 8; }
#include <stdio.h>
#include <string.h>

enum Type{Sign,E,Dot,Num,No};

inline Type type(char x){
    if(x >= '0' && x <= '9') return Num;
    if(x == '+' || x == '-') return Sign;
    if(x == 'E' || x == 'e') return E;
    if(x == '.') return Dot;
    return No;
}

bool isNumber(char * s){
    //  +0.0e+0
    // 01235678
    // ___4____ 
    char *p, *end, state;
    for(end = s+strlen(s)-1;*end==' ';end--);
    for(p = s;*p==' ';p++);
    for(state = 0;p <= end;p++){
        Type k = type(*p);
        if(k == No) return false;
        if(state < 6)
            if(k == Num) state = state <3?2:5;
            else if(k == Sign)
                if(state == 0) state = 1;
                else return false;
            else if(k == E)
                if(state > 1 && state != 4) state = 6;
                else return false;
            else /*k == Dot */
                if (state > 2) return false;
                else state = state<2?4:3;
        else
            if(k == Num) state = 8;
            else if(k == Dot || k == E) return false;
            else /* k == Sign */
                if(state == 6) state = 7;
                else return false;
    }
    return state == 2 || state == 3 || state == 5 || state == 8;
}

int main(void){
    char str[233];
    for(;gets(str) != NULL;){
        printf("%s - \"%s\"\n", isNumber(str)?"yea":"noo", str);
    }
    return 0;
}