剑指offer——表示数值的字符串(好题)(了解下库函数和正则)

来源:互联网 发布:linux 设置目录权限 编辑:程序博客网 时间:2024/06/04 22:45

题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。

思路:
应该只是考察普通的写法和科学计数法两种?
“.56”是正确的表达。
“+0E3”算正确么?
从前往后进行判断。把e是否出现设为flag,如果e出现的,小数点可出现两次,否则最多只能出现一次。
正负号只能出现在开头,e之后一定要跟一个正负号和整数。


public class Solution {    public boolean isNumeric(char[] str) {        if(str==null)            return false;        boolean symbols = false;;        boolean point = false;        int i = 0;        if(str[0]=='+'||str[0]=='-'){            symbols = true;            i++;        }        for(;i<str.length;i++){            if(str[i]=='.'){                if(point==false){ //最多只能出现一次小数点                    point = true;                    continue;                }                else                    return false;            }            if(str[i]=='e'||str[i]=='E')                break;            if((str[i]-'0')>9||(str[i]-'0')<0)                return false;        }        // 当i不是因为越界跳出循环时(即碰到e跳出)        if(i!=str.length&&(str[i]=='e'||str[i]=='E')){            if(i==0||(str[i-1]-'0')>9||(str[i-1]-'0')<0||i==str.length-1) // 科学计数符号在首位;在第二位但前面不是数字的情况;在字符串的最后                return false;        ++i;        if(str[i]=='+'||str[i]=='-'){            i++;        }        for(;i<str.length;i++){            if((str[i]-'0')>9||(str[i]-'0')<0)                return false;        }        }         // 没有e的时候,排除只有一个+或-的表达式        if(symbols==true&&str.length==1)            return false;        if(str[str.length-1]=='+'||str[str.length-1]=='-') // 排除e的后面只有一个+或-的情况            return false;        return true;    }}

public class test {      // 数组下标成员变量      int index;      public boolean isNumeric_2(char[] str) {          // 输入异常          if (str == null)              return false;          index = 0;          // 正负号开头          if (str[index] == '+' || str[index] == '-')              index++;          if (index == str.length)              return false;          // 设置numeric判断是否为数字          boolean numeric = true;          scanDigits(str);          if (index != str.length) {              // 小数              if (str[index] == '.') {                  index++;                  scanDigits(str);                  if (index < str.length && (str[index] == 'e' || str[index] == 'E'))                      numeric = isExponential(str);              } else if (str[index] == 'e' || str[index] == 'E')                  numeric = isExponential(str);              else                  // 出现了异常字符                  numeric = false;          }          return numeric && index == str.length;      }      // 扫描数组,如果当前字符为数字,index++      private void scanDigits(char[] str) {          while (index < str.length && str[index] >= '0' && str[index] <= '9')              index++;      }      // 判断是否为科学计数法表示的数值的结尾部分      private boolean isExponential(char[] str) {          if (str[index] != 'e' && str[index] != 'E')              return false;          index++;          if (index == str.length)              return false;          if (str[index] == '+' || str[index] == '-')              index++;          if (index == str.length)              return false;          scanDigits(str);          // 如果存在特殊字符,index不会为str.length          return index == str.length ? true : false;      }  }  

可以通过的方法,用到了库函数

public class Solution {    public boolean isNumeric(char[] str) {        try {            double re = Double.parseDouble(new String(str));        } catch (NumberFormatException e) {            return false;        }        return true;    }}

利用正则表达式(‘+’代表前面的字符至少出现一次,‘*’表示任意次数)

public class Solution {    public boolean isNumeric(char[] str) {        String string = String.valueOf(str);        return string.matches("[\\+-]?[0-9]*(\\.[0-9]*)?([eE][\\+-]?[0-9]+)?");    }}