“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”

preface

The effective figures of question 65 are as follows:

Example 1:

Input: s = 0 Output: trueCopy the code

Example 2:

Input: s = "e" Output: falseCopy the code

Example 3:

Input: s = "." Output: falseCopy the code

Example 4:

Input: s = ".1" Output: trueCopy the code

A, thinking

If in the daily development process, I will most likely use regular expressions to check whether a string is a valid number. But since this is an algorithm exercise, we’ll do it the other way.

I did this in an exhaustive way, where the most interesting case is whether there is and only one scientific notation e in the string, and e is not at the head or the tail

  • If they containeJudge:eWhether it is preceded by an integer or a decimal,eWhether the following is an integer
  • If it does not containe: Checks whether the string is an integer or a decimal

For example

Take the slightly more complicated STR = +.3e-10 as an example

  1. In order toeAs a tag, the string is divided into3 +.- 10
  2. Easy to know,eIn front of3 +.Meets the decimal standard
  3. Easy to know,eAt the back of the- 10Meets the integer criteria
  4. To sum up,+.3e-10Is a valid number

Second, the implementation

The implementation code

The code is long, but it’s all commented out, and it pulls out common things into common methods. In general, it is relatively easy to understand, so it will not be explained too much.

    /** * complex case simulation */
    public boolean isNumber(String s) {
        char[] chars = s.toCharArray();
        int ePosition = -1; // The position of e
        for (int i=0; i<chars.length; i++) {
            // Look for e
            char c = chars[i];
            if (c == 'e' || c == 'E') {
                ePosition = i;
                break; }}// Check whether the preceding part of e is correct
        if(ePosition ! = -1) {  // There is a science count identifier
            // E cannot start or end
            if (ePosition == 0 || ePosition == chars.length -1) {
                return false;
            }
            // E cannot be followed by a single plus or minus sign
            if (chars.length - ePosition == 2 && (chars[ePosition + 1] = ='+' || chars[ePosition + 1] = =The '-')) {
                return false;
            }
            // E cannot be preceded by a single plus or minus sign
            if (ePosition == 1 && (chars[0] = ='+' || chars[0] = =The '-')) {
                return false;
            }
            return isDecimalOrInteger(chars, ePosition) && isInteger(chars, true, ePosition + 1, chars.length);
        } else {
            returnisDecimalOrInteger(chars, chars.length); }}/** * interval: left open and right closed */
    private boolean isDecimalOrInteger(char[] chars , int end) {
        int dotPosition = -1;
        // Determine if there are any
        for (int i =0; i<end; i++) {
            if (chars[i] == '. ') {
                dotPosition = i;
                break; }}// At least one digit followed by a dot '.'
        // At least one digit followed by a dot '.', followed by at least one digit
        // A dot '.' followed by at least one digit
        if (dotPosition == 0 && end == 1 || (dotPosition == end -1 && (chars[dotPosition-1] < '0' || chars[dotPosition-1] > '9'))) {
            return false;
        } else if(dotPosition ! = -1) {
            return isInteger(chars, true.0, dotPosition) && isInteger(chars, false, dotPosition + 1, end);
        } else {
            return isInteger(chars, true.0, end); }}/** * interval: left open and right closed */
    private boolean isInteger(char[] chars, boolean withSymbol, int start, int end) {
        for (int i=start; i<end; i++) {
            char c = chars[i];
            if (withSymbol && i == start && (c == The '-' || c == '+')) {
                continue;
            }else if (c < '0' || c > '9') {
                return false; }}return true;
    }
Copy the code

The test code

public static void main(String[] args) {
    String str = "+.3e-10";
    boolean flag = new Number65().isNumber(str);
    System.out.println(flag);
}
Copy the code

The results of

Third, summary

In a logical reasoning way, it is really Debug all the time. I submitted almost 20 times in total before I was able to pass all the test cases.

Finite-state machines are a better way to do this, and the logic will be clearer!

Thank you to see the end, very honored to help you ~♥

If you think my writing is good, you might as well give me a thumbs-up! If you have any questions, please see the comments section