Sword refers to Offer 20. A string representing a value

Sword refers to Offer 20. A string representing a value

Problem Description:

Please implement a function to determine whether a string represents a value (including integers and decimals).

The values ​​(in order) can be broken down into the following parts:

  1. some spaces
  2. a decimal or integer
  3. (optional) an 'e' or 'E' followed by an integer
  4. some spaces

Decimals (in order) can be broken down into the following parts:

(optional) a sign character ('+' or '-'

One of the following formats:

  1. At least one digit followed by a dot '.'
  2. At least one digit, followed by a dot '.', followed by at least one digit
  3. A dot '.' followed by at least one digit

**Integers (in order)** can be broken down into the following parts:

  1. (optional) a sign character ('+' or '-')
  2. at least one digit

Some values ​​are listed below:

["+100", “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]

Some non-values ​​are listed as follows:

[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]

Example:

Problem-solving ideas:Idea link

The first thing that comes to mind is to judge whether it is false instead of judging whether it is true. After all, there are so many conditions to be satisfied to judge true, but as long as one condition is not satisfied, it can be judged false. Finally, the efficiency of the code is not bad, so let’s get to the point:

1. First define four flags, corresponding to four characters

  • Is there a number: hasNum
  • Has e:hasE
  • Whether there are positive and negative signs: hasSign
  • Does it dot: hasDot

2. Others also define the string length n and the string index index

3. First deal with the space at the beginning, and the index will move back accordingly

4. Then enter the loop to traverse the string

  • If the current character c is a number: set hasNum to true, move the index back until it is not a number or traverse to the end position; if it has traversed to the end (index == n), end the loop
  • If the current character c is 'e' or 'E': if e has appeared or no number has appeared before the current e, return fasle; otherwise, set hasE = true, and set the other 3 flags to false, because it is necessary to start traversing e The new numbers behind
  • If the current character c is + or -: if there has been + or - or there has been a number or there has been '.', return flase; otherwise set hasSign = true
  • If the current character c is '.': if '.' has appeared or 'e' or 'E' has appeared, return false; otherwise set hasDot = true
  • If the current character c is ' ': end the loop, because it may be a space at the end, but it may also be a space in the middle of the string, continue processing outside the loop
  • If the current character c is a character other than the above 5 cases, directly return false

5. To process spaces, the index will move backward accordingly

6. If the current index index is equal to the length of the string, it means that the traversal has reached the end, but it must satisfy hasNum to be true to finally return true, because if the string is full of symbols and no numbers, it will not work, and there is no number after e It is also not possible, but it is possible to have no symbols, so you only need to judge hasNum among the four flags; so the last return is hasNum && index == n

7. If there is a space in the middle of the string, it is impossible to traverse to the end according to the above ideas, the index will not be equal to n, and the return is false

Code

class Solution {
    
    
    public boolean isNumber(String s) {
    
    
        //将字符s分成char型数组
        char[] array = s.toCharArray();
        //当前字符的索引值
        int index = 0;
        //定义四中字符的标记
        boolean hasNum = false,hasE = false,hasSign = false,hasDot = false;
        //定义索引的最大值,不能超过字符数组的长度
        int n = array.length;

        //当索引移到空字符上,索引值后移
        while(index < n && array[index] == ' '){
    
    
            index++;
        }
        while(index < n){
    
    
            //获取当前索引位置的字符
            char x = array[index];
            //当前字符为数字时
            if(x >= '0' && x<= '9'){
    
    
                hasNum = true;
                //当前字符为'e'和'E'时
            }else if(x == 'e' || x == 'E'){
    
    
                //如果e已经出现或者当前e之前没有出现过数字,返回fasle;否则令hasE = true,
                //并且其他3个flag全部置为false,因为要开始遍历e后面的新数字了
                if(hasE || !hasNum){
    
    
                    return false;
                }
                hasE = true;
                hasNum = false;
                hasDot = false;
                hasSign =false;
                //当前字符为'+'和'-'时
            }else if(x == '+' || x == '-'){
    
    
                //如果已经出现过+或-或者已经出现过数字或者已经出现过'.',返回flase;否则令hasSign = true
                if(hasSign || hasNum || hasDot){
    
    
                    return false;
                }
                hasSign = true;
                //当前字符为'.'
            }else if(x == '.'){
    
    
                //如果已经出现过'.'或者已经出现过'e'或'E',返回false;否则令hasDot = true
                if(hasDot || hasE){
    
    
                    return false;
                }
                hasDot = true;
                //如果当前字符c是' ':结束循环,因为可能是末尾的空格了,但也有可能是字符串中间的空格,在循环外继续处理
            }else if(x == ' '){
    
    
                break;
            }else{
    
    
                //其它为非法字符
                return false;
            }
            //当前索引后移,判断下一个字符
            index++;
        }
        //如果当前索引没有达到字符数组末尾,则剩下的自营应均为空格,否则该字符串不会形成数值
        for(;index < n;index++){
    
    
            if(array[index] != ' '){
    
    
                return false;
            }
        }
        return hasNum;

    }
}

Guess you like

Origin blog.csdn.net/Royalic/article/details/120062906