Algorithmus leetcode|65. Signifikante Zahlen (Rost schlägt hart)



65. Gültige Zahlen:

Signifikante Zahlen (in der Reihenfolge) können in die folgenden Teile unterteilt werden:

  1. eine Dezimalzahl oder Ganzzahl
  2. (optional) ein 'e'oder 'E', gefolgt von einer Ganzzahl

Dezimalzahlen (in der Reihenfolge) können in die folgenden Teile zerlegt werden:

  1. (optional) ein Symbolzeichen ( '+'oder '-')
  2. Eines der folgenden Formate:
    1. mindestens eine Ziffer gefolgt von einem Punkt'.'
    2. Mindestens eine Ziffer, gefolgt von einem Punkt '.', gefolgt von mindestens einer Ziffer
    3. Ein Punkt '.', gefolgt von mindestens einer Ziffer

Ganzzahlen (in der Reihenfolge) können in die folgenden Teile unterteilt werden:

  1. (optional) ein Symbolzeichen ( '+'oder '-')
  2. mindestens eine Ziffer

Nachfolgend sind einige gültige Zahlen aufgeführt:["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]

Nachfolgend sind einige ungültige Nummern aufgeführt:["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]

sGeben Sie bei gegebener Zeichenfolge seine gültige Zahl zurück true.

Beispiel 1:

输入:
	
	s = "0"
	
输出:
	
	true

Beispiel 2:

输入:
	
	s = "e"
	
输出:
	
	false

Beispiel 3:

输入:
	
	s = "."
	
输出:
	
	false

Hinweis:

  • 1 <= s.length <= 20
  • sEnthält nur englische Buchstaben (Groß- und Kleinbuchstaben), Zahlen ( 0-9), Pluszeichen '+', Minuszeichen '-'oder Punkte '.'.

analysieren:

  • Angesichts dieses Algorithmusproblems geriet der zweite Leiter erneut in tiefe Gedanken.
  • Der zweite Leiter ist der Meinung, dass sich diese Frage von anderen Algorithmusfragen unterscheidet und dass die Beurteilung, ob sie effektiv ist, nicht mit einem Algorithmus vergleichbar ist.
  • Wenn das Gehirn Zahlen sieht, fällt es sofort ein Urteil.
  • Ich hätte nicht erwartet, ein so umständliches Programm zu schreiben.
  • Das Entwurfsmuster enthält ein Zustandsmuster , das hier als Referenz verwendet werden kann.
  • Wenn Sie zur Beurteilung viel Verzweigungslogik verwenden, werden die Leute verrückt, aber mit der Zustandsumschaltmethode ist es sehr klar.
  • Der Zustand der signifikanten Ziffern ist vorhersehbar und endlich. Der endliche Zustandsautomat wird ja so genannt.

antworten:

Rost:

impl Solution {
    
    
    pub fn is_number(s: String) -> bool {
    
    
        s.chars()
         .try_fold(State::new(), State::handle)
         .as_ref()
         .map_or(false, State::is_valid)
    }
}

type Result = std::result::Result<State, ()>;

enum State {
    
    
    Start,
    Sign,
    Integer,
    Dot,
    EmptyDot,
    Decimal,
    E,
    ExpSign,
    Exponent,
    End,
}

impl State {
    
    
    pub fn new() -> Self {
    
    
        State::Start
    }

    pub fn is_valid(&self) -> bool {
    
    
        use State::*;
        match self {
    
    
            Start | Sign | E | ExpSign | EmptyDot => false,
            _ => true,
        }
    }

    pub fn handle(self, c: char) -> Result {
    
    
        use State::*;
        match self {
    
    
            Start => match c {
    
    
                ' ' => Ok(Start),
                '+' | '-' => Ok(Sign),
                '0'..='9' => Ok(Integer),
                '.' => Ok(EmptyDot),
                _ => Err(()),
            }
            Sign => match c {
    
    
                '0'..='9' => Ok(Integer),
                '.' => Ok(EmptyDot),
                _ => Err(()),
            }
            Integer => match c {
    
    
                '0'..='9' => Ok(Integer),
                '.' => Ok(Dot),
                'e' | 'E' => Ok(E),
                ' ' => Ok(End),
                _ => Err(()),
            }
            EmptyDot => match c {
    
    
                '0'..='9' => Ok(Decimal), // "  .1" or "  +.1"
                _ => Err(()),
            }
            Dot => match c {
    
    
                '0'..='9' => Ok(Decimal),
                'e' | 'E' => Ok(E),   // "46.e3"
                ' ' => Ok(End),
                _ => Err(()),
            }
            Decimal => match c {
    
    
                '0'..='9' => Ok(Decimal),
                'e' | 'E' => Ok(E),
                ' ' => Ok(End),
                _ => Err(()),
            }
            E => match c {
    
    
                '+' | '-' => Ok(ExpSign),
                '0'..='9' => Ok(Exponent),
                _ => Err(()),
            }
            ExpSign => match c {
    
    
                '0'..='9' => Ok(Exponent),
                _ => Err(()),
            }
            Exponent => match c {
    
    
                '0'..='9' => Ok(Exponent),
                ' ' => Ok(End),
                _ => Err(()),
            }
            End => match c {
    
    
                ' ' => Ok(End),
                _ => Err(()),
            }
        }
    }
}

gehen:

type State int
type CharType int

const (
    STATE_INITIAL State = iota
    STATE_INT_SIGN
    STATE_INTEGER
    STATE_POINT
    STATE_POINT_WITHOUT_INT
    STATE_FRACTION
    STATE_EXP
    STATE_EXP_SIGN
    STATE_EXP_NUMBER
    STATE_END
)

const (
    CHAR_NUMBER CharType = iota
    CHAR_EXP
    CHAR_POINT
    CHAR_SIGN
    CHAR_ILLEGAL
)

func toCharType(ch byte) CharType {
    
    
    switch ch {
    
    
    case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
        return CHAR_NUMBER
    case 'e', 'E':
        return CHAR_EXP
    case '.':
        return CHAR_POINT
    case '+', '-':
        return CHAR_SIGN
    default:
        return CHAR_ILLEGAL
    }
}

func isNumber(s string) bool {
    
    
    transfer := map[State]map[CharType]State{
    
    
        STATE_INITIAL: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_INTEGER,
            CHAR_POINT:  STATE_POINT_WITHOUT_INT,
            CHAR_SIGN:   STATE_INT_SIGN,
        },
        STATE_INT_SIGN: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_INTEGER,
            CHAR_POINT:  STATE_POINT_WITHOUT_INT,
        },
        STATE_INTEGER: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_INTEGER,
            CHAR_EXP:    STATE_EXP,
            CHAR_POINT:  STATE_POINT,
        },
        STATE_POINT: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_FRACTION,
            CHAR_EXP:    STATE_EXP,
        },
        STATE_POINT_WITHOUT_INT: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_FRACTION,
        },
        STATE_FRACTION: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_FRACTION,
            CHAR_EXP:    STATE_EXP,
        },
        STATE_EXP: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_EXP_NUMBER,
            CHAR_SIGN:   STATE_EXP_SIGN,
        },
        STATE_EXP_SIGN: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_EXP_NUMBER,
        },
        STATE_EXP_NUMBER: map[CharType]State{
    
    
            CHAR_NUMBER: STATE_EXP_NUMBER,
        },
    }
    state := STATE_INITIAL
    for i := 0; i < len(s); i++ {
    
    
        typ := toCharType(s[i])
        if _, ok := transfer[state][typ]; !ok {
    
    
            return false
        } else {
    
    
            state = transfer[state][typ]
        }
    }
    return state == STATE_INTEGER || state == STATE_POINT || state == STATE_FRACTION || state == STATE_EXP_NUMBER || state == STATE_END
}

c++:

class Solution {
    
    
public:
    enum State {
    
    
        STATE_INITIAL,
        STATE_INT_SIGN,
        STATE_INTEGER,
        STATE_POINT,
        STATE_POINT_WITHOUT_INT,
        STATE_FRACTION,
        STATE_EXP,
        STATE_EXP_SIGN,
        STATE_EXP_NUMBER,
        STATE_END
    };

    enum CharType {
    
    
        CHAR_NUMBER,
        CHAR_EXP,
        CHAR_POINT,
        CHAR_SIGN,
        CHAR_ILLEGAL
    };

    CharType toCharType(char ch) {
    
    
        if (ch >= '0' && ch <= '9') {
    
    
            return CHAR_NUMBER;
        } else if (ch == 'e' || ch == 'E') {
    
    
            return CHAR_EXP;
        } else if (ch == '.') {
    
    
            return CHAR_POINT;
        } else if (ch == '+' || ch == '-') {
    
    
            return CHAR_SIGN;
        } else {
    
    
            return CHAR_ILLEGAL;
        }
    }

    bool isNumber(string s) {
    
    
        unordered_map<State, unordered_map<CharType, State>> transfer{
    
    
            {
    
    
                STATE_INITIAL, {
    
    
                    {
    
    CHAR_NUMBER, STATE_INTEGER},
                    {
    
    CHAR_POINT, STATE_POINT_WITHOUT_INT},
                    {
    
    CHAR_SIGN, STATE_INT_SIGN}
                }
            }, {
    
    
                STATE_INT_SIGN, {
    
    
                    {
    
    CHAR_NUMBER, STATE_INTEGER},
                    {
    
    CHAR_POINT, STATE_POINT_WITHOUT_INT}
                }
            }, {
    
    
                STATE_INTEGER, {
    
    
                    {
    
    CHAR_NUMBER, STATE_INTEGER},
                    {
    
    CHAR_EXP, STATE_EXP},
                    {
    
    CHAR_POINT, STATE_POINT}
                }
            }, {
    
    
                STATE_POINT, {
    
    
                    {
    
    CHAR_NUMBER, STATE_FRACTION},
                    {
    
    CHAR_EXP, STATE_EXP}
                }
            }, {
    
    
                STATE_POINT_WITHOUT_INT, {
    
    
                    {
    
    CHAR_NUMBER, STATE_FRACTION}
                }
            }, {
    
    
                STATE_FRACTION,
                {
    
    
                    {
    
    CHAR_NUMBER, STATE_FRACTION},
                    {
    
    CHAR_EXP, STATE_EXP}
                }
            }, {
    
    
                STATE_EXP,
                {
    
    
                    {
    
    CHAR_NUMBER, STATE_EXP_NUMBER},
                    {
    
    CHAR_SIGN, STATE_EXP_SIGN}
                }
            }, {
    
    
                STATE_EXP_SIGN, {
    
    
                    {
    
    CHAR_NUMBER, STATE_EXP_NUMBER}
                }
            }, {
    
    
                STATE_EXP_NUMBER, {
    
    
                    {
    
    CHAR_NUMBER, STATE_EXP_NUMBER}
                }
            }
        };

        int len = s.length();
        State st = STATE_INITIAL;

        for (int i = 0; i < len; i++) {
    
    
            CharType typ = toCharType(s[i]);
            if (transfer[st].find(typ) == transfer[st].end()) {
    
    
                return false;
            } else {
    
    
                st = transfer[st][typ];
            }
        }
        return st == STATE_INTEGER || st == STATE_POINT || st == STATE_FRACTION || st == STATE_EXP_NUMBER || st == STATE_END;
    }
};

Python:

from enum import Enum

class Solution:
    def isNumber(self, s: str) -> bool:
        State = Enum("State", [
            "STATE_INITIAL",
            "STATE_INT_SIGN",
            "STATE_INTEGER",
            "STATE_POINT",
            "STATE_POINT_WITHOUT_INT",
            "STATE_FRACTION",
            "STATE_EXP",
            "STATE_EXP_SIGN",
            "STATE_EXP_NUMBER",
            "STATE_END"
        ])
        Chartype = Enum("Chartype", [
            "CHAR_NUMBER",
            "CHAR_EXP",
            "CHAR_POINT",
            "CHAR_SIGN",
            "CHAR_ILLEGAL"
        ])

        def toChartype(ch: str) -> Chartype:
            if ch.isdigit():
                return Chartype.CHAR_NUMBER
            elif ch.lower() == "e":
                return Chartype.CHAR_EXP
            elif ch == ".":
                return Chartype.CHAR_POINT
            elif ch == "+" or ch == "-":
                return Chartype.CHAR_SIGN
            else:
                return Chartype.CHAR_ILLEGAL
        
        transfer = {
    
    
            State.STATE_INITIAL: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_INTEGER,
                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT,
                Chartype.CHAR_SIGN: State.STATE_INT_SIGN
            },
            State.STATE_INT_SIGN: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_INTEGER,
                Chartype.CHAR_POINT: State.STATE_POINT_WITHOUT_INT
            },
            State.STATE_INTEGER: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_INTEGER,
                Chartype.CHAR_EXP: State.STATE_EXP,
                Chartype.CHAR_POINT: State.STATE_POINT
            },
            State.STATE_POINT: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_FRACTION,
                Chartype.CHAR_EXP: State.STATE_EXP
            },
            State.STATE_POINT_WITHOUT_INT: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_FRACTION
            },
            State.STATE_FRACTION: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_FRACTION,
                Chartype.CHAR_EXP: State.STATE_EXP
            },
            State.STATE_EXP: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER,
                Chartype.CHAR_SIGN: State.STATE_EXP_SIGN
            },
            State.STATE_EXP_SIGN: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER
            },
            State.STATE_EXP_NUMBER: {
    
    
                Chartype.CHAR_NUMBER: State.STATE_EXP_NUMBER
            },
        }

        st = State.STATE_INITIAL
        for ch in s:
            typ = toChartype(ch)
            if typ not in transfer[st]:
                return False
            st = transfer[st][typ]
        
        return st in [State.STATE_INTEGER, State.STATE_POINT, State.STATE_FRACTION, State.STATE_EXP_NUMBER, State.STATE_END]


Java:

class Solution {
    
    
    public boolean isNumber(String s) {
    
    
        Map<State, Map<CharType, State>> transfer = new HashMap<State, Map<CharType, State>>();
        Map<CharType, State> initialMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT);
            put(CharType.CHAR_SIGN, State.STATE_INT_SIGN);
        }};
        transfer.put(State.STATE_INITIAL, initialMap);
        Map<CharType, State> intSignMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT);
        }};
        transfer.put(State.STATE_INT_SIGN, intSignMap);
        Map<CharType, State> integerMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            put(CharType.CHAR_EXP, State.STATE_EXP);
            put(CharType.CHAR_POINT, State.STATE_POINT);
        }};
        transfer.put(State.STATE_INTEGER, integerMap);
        Map<CharType, State> pointMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
            put(CharType.CHAR_EXP, State.STATE_EXP);
        }};
        transfer.put(State.STATE_POINT, pointMap);
        Map<CharType, State> pointWithoutIntMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
        }};
        transfer.put(State.STATE_POINT_WITHOUT_INT, pointWithoutIntMap);
        Map<CharType, State> fractionMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
            put(CharType.CHAR_EXP, State.STATE_EXP);
        }};
        transfer.put(State.STATE_FRACTION, fractionMap);
        Map<CharType, State> expMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
            put(CharType.CHAR_SIGN, State.STATE_EXP_SIGN);
        }};
        transfer.put(State.STATE_EXP, expMap);
        Map<CharType, State> expSignMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
        }};
        transfer.put(State.STATE_EXP_SIGN, expSignMap);
        Map<CharType, State> expNumberMap = new HashMap<CharType, State>() {
    
    {
    
    
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
        }};
        transfer.put(State.STATE_EXP_NUMBER, expNumberMap);

        int length = s.length();
        State state = State.STATE_INITIAL;

        for (int i = 0; i < length; i++) {
    
    
            CharType type = toCharType(s.charAt(i));
            if (!transfer.get(state).containsKey(type)) {
    
    
                return false;
            } else {
    
    
                state = transfer.get(state).get(type);
            }
        }
        return state == State.STATE_INTEGER || state == State.STATE_POINT || state == State.STATE_FRACTION || state == State.STATE_EXP_NUMBER || state == State.STATE_END;
    }

    public CharType toCharType(char ch) {
    
    
        if (ch >= '0' && ch <= '9') {
    
    
            return CharType.CHAR_NUMBER;
        } else if (ch == 'e' || ch == 'E') {
    
    
            return CharType.CHAR_EXP;
        } else if (ch == '.') {
    
    
            return CharType.CHAR_POINT;
        } else if (ch == '+' || ch == '-') {
    
    
            return CharType.CHAR_SIGN;
        } else {
    
    
            return CharType.CHAR_ILLEGAL;
        }
    }

    enum State {
    
    
        STATE_INITIAL,
        STATE_INT_SIGN,
        STATE_INTEGER,
        STATE_POINT,
        STATE_POINT_WITHOUT_INT,
        STATE_FRACTION,
        STATE_EXP,
        STATE_EXP_SIGN,
        STATE_EXP_NUMBER,
        STATE_END
    }

    enum CharType {
    
    
        CHAR_NUMBER,
        CHAR_EXP,
        CHAR_POINT,
        CHAR_SIGN,
        CHAR_ILLEGAL
    }
}

Vielen Dank, dass Sie diesen Artikel gelesen haben ~
Willkommen bei 【Gefällt mir】【Favoriten】【Kommentar】Gehen Sie dreimal hintereinander ~ Es
ist nicht schwer aufzugeben, aber es muss cool sein, durchzuhalten ~
Ich hoffe, wir können uns alle verbessern jeden Tag wenig ~
Dieser Artikel wurde vom weißen Hut des zweiten Meisters geschrieben: https://le-yi.blog.csdn.net/Blog original ~


Guess you like

Origin blog.csdn.net/leyi520/article/details/131974927