zoukankan      html  css  js  c++  java
  • LeetCode之“字符串”:Valid Number(由此引发的对正则表达式的学习)

      题目链接

      题目要求: 

      Validate if a given string is numeric.

      Some examples:
      "0" => true
      " 0.1 " => true
      "abc" => false
      "1 a" => false
      "2e10" => true

      Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

      这道题看起来貌似简单,实则要考虑的情况非常多。更可惜的是LeetCode并不支持正则表达式。。。。下文先试着以正则表达式的方法去解决这个问题。

      C++现在是提供了对正则表达式的支持的,但貌似用的少,更多的是Boost库提供的正则表达式。

      法一和法二的测试用例来自一博文,且这两个方法均测试通过。测试用例可从百度云下载得到。另外,具体的文件读写及函数验证程序如下:

     1 #include <fstream>
     2 ... ...
     3 ifstream in("C:\Users\xiehongfeng100\Desktop\LeetCode_Valid_Number_Test_Cases.txt");
     4 if (in) // if file exists
     5 {
     6     string line;
     7     while (getline(in, line)) // read each line from 'in'
     8     {
     9         string input;
    10         bool expect;
    11 
    12         // extract 'input'
    13         line.erase(0, 1);
    14         int tmpFind = line.find('"');
    15         input = line.substr(0, tmpFind);
    16         while (input.begin() != input.end() && input.front() == ' ')
    17             input.erase(input.begin());
    18         while (input.begin() != input.end() && input.back() == ' ')
    19             input.pop_back();
    20             
    21         // extract 'expect'
    22         string expectStr = line.substr(tmpFind + 2, line.size() - line.find('	', tmpFind + 2) - 1);
    23         if (expectStr == "TRUE")
    24             expect = true;
    25         else
    26             expect = false;
    27 
    28         // validate
    29         bool isValid = isNumber(input);
    30         if (isValid != expect)
    31             cout << "Something wrong! " << line << endl;
    32     }
    33 }
    34 else
    35 {
    36     cout << "No such file" << endl;
    37 }
    View Code

      1. 法一:基于C++自身正则表达式

      用正则表达式写出来的程序非常简洁:

    1 #include <regex>
    2 ... ...
    3 bool isNumber(string buf)
    4 {
    5     regex pattern("[+-]?(\.[0-9]+|[0-9]+\.?)[0-9]*(e[+-]?[0-9]+)?", regex_constants::extended);
    6     match_results<string::const_iterator> result;
    7     return regex_match(buf, result, pattern);
    8 }

      2. 法二:基于Boost库正则表达式

      Boost库的正则表达式的语法跟C++自身提供的有点差别。Boost库的跟其他语言更加兼容。

    1 #include <boost/regex.hpp>
    2 ... ...
    3 bool isNumber(string buf)
    4 {
    5     string Reg = "[+-]?(\.\d+|\d+\.?)\d*(e[+-]?\d+)?";
    6     boost::regex reg(Reg);
    7     return boost::regex_match(buf, reg);
    8 }

      3. 法三:列举所有情况

       这种方法很繁杂。。。

     1 class Solution {
     2 public:
     3     bool isValidChar(char c)
     4     {
     5         string str = "0123456789.e+-";
     6         return str.find(c) != -1;
     7     }
     8 
     9     bool isDigit(int in)
    10     {
    11         char ref[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    12         for (int i = 0; i < 10; i++)
    13         {
    14             if (in == ref[i])
    15                 return true;
    16         }
    17         return false;
    18     }
    19 
    20     bool isNumber(string s) {
    21         // clear spaces
    22         while (s.begin() != s.end() && s.front() == ' ')
    23             s.erase(0, 1);
    24         while (s.begin() != s.end() && s.back() == ' ')
    25             s.pop_back();
    26 
    27         int szS = s.size();
    28         if (szS == 0)
    29             return false;
    30         // only '.'
    31         if (szS == 1 && s[0] == '.')
    32             return false;
    33         // 'e' at the first or last position of s
    34         if (s[0] == 'e' || s[szS - 1] == 'e')
    35             return false;
    36         // too many signs
    37         if (szS > 1 && (s[0] == '-' || s[0] == '+') && (s[1] == '-' || s[1] == '+'))
    38             return false;
    39         // sign at the last
    40         if (s[szS - 1] == '+' || s[szS - 1] == '-')
    41             return false;
    42 
    43         szS = s.size();
    44         int countDot = 0;
    45         int countE = 0;
    46         for (int i = 0; i < szS; i++)
    47         {
    48             if (!isValidChar(s[i]))
    49                 return false;
    50 
    51             if (s[i] == '.') //'.e at the begining, ' '.+/-' are not allowed
    52             {
    53                 countDot++;
    54                 if (i + 1 < szS && ((i == 0 && s[i + 1] == 'e') || s[i + 1] == '+' || s[i + 1] == '-'))    // '.e'
    55                     return false;
    56             }
    57             if (s[i] == 'e') // 'e.' 'e+/-...+/-' are not allowed
    58             {
    59                 countE++;
    60                 if (i + 1 < szS)
    61                 {
    62                     int pos1 = s.find('.', i + 1);
    63                     if (pos1 != -1)
    64                         return false;
    65                 }
    66                 if (i + 2 < szS)
    67                 {
    68                     int pos2 = s.find('+', i + 2);
    69                     int pos3 = s.find('-', i + 2);
    70                     if (pos2 > (i + 1) || pos3 > (i + 1))
    71                         return false;
    72                 }
    73             }
    74             if (s[i] == '+') // '+e' '+-' 'digit+/' are not allowed
    75             {
    76                 if (i + 1 < szS && (s[i + 1] == 'e' || s[i + 1] == '-'))
    77                     return false;
    78                 if (i > 0 && isDigit(s[i - 1]))
    79                     return false;
    80             }
    81             if (s[i] == '-') // '. at the last' '-e' '-+' 'digit+/' are not allowed
    82             {
    83                 if (i + 1 < szS && ((i + 1 == szS - 1 && s[i + 1] == '.') || s[i + 1] == 'e' || s[i + 1] == '+'))
    84                     return false;
    85                 if (i > 0 && isDigit(s[i - 1]))
    86                     return false;
    87             }
    88 
    89             if (countDot > 1 || countE > 1) // no double dots or double e can exit
    90                 return false;
    91 
    92         }
    93 
    94         return true;
    95     }
    96 };
    View Code
  • 相关阅读:
    OA权限管理的实现(下)
    Eclipse及其插件介绍和下载(转)
    [转载]在Redhat Linux AS 4下实现软件RAID
    RAID磁盘阵列术语详解(转)
    [转载]关于"编译器失败,错误代码为128。"的解决方案
    Android的SurfaceView使用
    剖析 SurfaceView Callback以及SurfaceHolder
    android drawable 应用
    Android layout xml总结
    listView控件,adapter,以及其他控件的组合
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4555670.html
Copyright © 2011-2022 走看看