Question
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.
My Solution
class Solution {
public:
bool isNumber(string s) {
int size = s.size();
// 預處理,去除左右兩邊空格
int countLS = 0; // 左邊空格
int countRS = 0; // 右邊空格
int idx = 0; // 指向下一個字符位置
char c;
while(isSpace(s[idx++])) // count spaces in left
{
countLS++;
}
idx = size - 1;
while(isSpace(s[idx--])) // count spaces in right
{
countRS++;
}
size -= countLS + countRS;
for(idx = 0; idx < size; idx++)
{
s[idx] = s[idx + countLS];
}
s[size] = '\0';
int ePos = s.find('e'); // e出現的位置
string lStr;
string rStr;
if(ePos != string::npos) // 找到了'e'
{
lStr = s.substr(0, ePos);
rStr = s.substr(ePos + 1, size - ePos - 1);
if(isPotDig(lStr) && isInteger(rStr))
{
return true;
}
}else // 都沒有找到
{
return isPotDig(s);
}
return false;
}
bool isSpace(char c)
{
if(' ' == c || '\t' == c || '\n' == c)
return true;
else
return false;
}
/***********
* 判斷小數
* *********/
bool isPotDig(string s)
{
int size = -1;
while('\0' != s[++size])
{
}
int pPos = s.find('.'); // .出現的位置
if(pPos != string::npos) // 找到了'.'
{
string lStr = s.substr(0, pPos);
string rStr = s.substr(pPos + 1, size - pPos - 1);
if(pPos == 0 && isDigNum(rStr, false, false)) // 左邊爲空右邊爲數字
{
return true;
}
if(isDigNum(lStr, true, false) && pPos + 1 >= size) // 左邊數字右邊空
{
return true;
}
if(isDigNum(lStr, true, true) && isDigNum(rStr, false, false)) // 兩邊都爲數字
{
return true;
}
return false;
}else
{
return isInteger(s);
}
}
/***********
* 判斷整數
* *******/
bool isInteger(string s)
{
return isDigNum(s, true, false);
}
/******************
* 判斷是否有且僅有數字,可以包括符號(不包含'.'和'e'
* ****************/
bool isDigNum(string s, bool sign = false /*是否允許一個符號位*/, bool noDigAfterSign = false/*符號位後面是否允許空*/)
{
int idx = 0;
char c;
bool noDig = true;
bool noSign = true;
if(sign) // 對符號位做預處理,符號位後面必須接數字
{
if(s[0] == '-' || s[0] == '+')
{
idx++;
noSign = false;
}
}
while('\0' != (c = s[idx++]))
{
if(c >= '0' && c <= '9')
{
noDig = false; // have digit
continue;
}
return false; // 有異常字符
}
// 運行到此處,說明沒有異常字符
if(noDigAfterSign && !noSign) // 有符號位,且允許沒有數字,則任何情況都滿足
{
return true;
}else
{
return !noDig; // 必須有數字
}
}
};