Leetcode 65. Significant digits

Posted by weiwei on Tue, 30 Jun 2020 10:51:32 +0200


This question perfectly explains what "test case oriented programming" is. Because there are many situations to be considered, the basic idea is to first write rules to judge the invalid situation according to the given test cases, and then make special judgment on the remaining cases according to the submitted errors. If all "invalid cases" are not met, it will be effective. The title specially mentions "we intentionally make the problem statement fuzzy", which is very spiritual. Therefore, it is difficult to consider all the situations at the beginning. WA knows which test cases (rules) there are several times.
First, summarize some rules from the test cases given in the title

  1. The given string may contain the space of prefix and suffix, so the space of prefix and suffix should be removed first;
  2. It is possible that the string is a scientific number, so the character 'e' or 'e' will appear, but 'e' (or 'e') can only appear once and cannot appear at the beginning and end of the string;
  3. 'e' (or 'e') may be followed by a '+' or '-', the sign can only appear in two places, one is the beginning of the string, the other is after 'e' (or 'e'). If there is a sign in other positions, it can be judged as invalid! In addition, if there is a sign after 'e' (or 'e'), there must be a number after it. Therefore, it is necessary to judge whether the sign is the end of the string. If it is, it can also be judged as invalid;
  4. The beginning of the string can be positive or negative, but it is invalid if there are only positive and negative signs;
    Then summarize some rules from the submitted test cases
  5. A string can start with "." for example, ". 1" means 0.1. It is legal that the string is followed by a number, and it is illegal to follow "." with other characters;
  6. 'and' e 'can only appear once, and more than once is invalid
class Solution {
public:
    bool isNumber(string s) {
        int left = 0, right = s.size() - 1;                  //Filter the prefix and suffix spaces from the left and right respectively
        while(left <= right && s[left] == ' ') {
            ++left;
        }
        while(left <= right && s[right] == ' ') {
            --right;
        }
        if(left > right) {                                    //If the string consists of only spaces, it is invalid
            return false;
        }
        s = s.substr(left, right - left + 1);                 //Leave the string after removing the prefix and suffix spaces
        if(s[0] == '+' || s[0] == '-') {                      //If the string starts with a positive and negative sign, the string at the beginning is deleted and judged again
            s = s.substr(1);                                  //substr only passes in a parameter 1, which means that the substring from the first position to the end is left (that is, the sign of the zero position is deleted)
        }
        if(s.empty()) {                                       //If the string is empty after deleting the sign, it is invalid
            return false;
        }
        if(s[0] == '.' && (s.size() == 1 || s[1] == 'e' || s[1] == 'E')) {    //If a string begins with a '.', three situations are invalid: (1) the string has only one character '.'; (2) the next character is' e'; (3) the next character is' E'. In fact, as long as the character after "." is not a number, it is invalid, but other cases are judged elsewhere.
            return false;
        }
        int dotNum = 0, eNum = 0;                  //Record the number of '. And' E '(or' E ')
        for(int i = 0; i < s.size(); ++i) {
            if(s[i] == '.') {                      
                if(dotNum > 0 || eNum > 0) {       //If '. Occurs more than 1 or appears after' E '(or' E '), it is invalid
                    return false;
                } else {
                    ++dotNum;
                }
            } else if(s[i] == 'e' || s[i] == 'E') {            
                if(i == 0 || i == s.size() - 1 || eNum > 0) {      //If 'E' (or 'E') appears at the beginning or end, or occurs more than 1, it is invalid
                    return false;
                } else if(s[i + 1] == '+' || s[i + 1] == '-') {     //If the character after 'E' (or 'E') is positive or negative, special judgment is required
                    if(i + 1 == s.size() - 1) {                     //A number is required after the sign. If the sign is the last character (there is nothing behind it), it is invalid
                        return false;
                    } else {
                        ++i;                                        //If there is something behind the sign, we skip the sign and continue to judge what follows
                    }
                }
                ++eNum;
            } else if(!(s[i] >= '0' && s[i] <= '9')) {              //In other cases, the characters can only be numbers, and the others are invalid
                return false;
            }
        }
        return true;                                                //If none of the above conditions are met, we assume that the string can be represented as a valid number!
    }
};

Complexity analysis: the time complexity is O(n) because the string is only traversed once; only constant variables are opened, and the space complexity is O(1).

Topics: Programming