Skip to content

Instantly share code, notes, and snippets.

@y-fedorov
Created June 13, 2018 10:35
Show Gist options
  • Save y-fedorov/2d0e356218650bd2e788b481b101e971 to your computer and use it in GitHub Desktop.
Save y-fedorov/2d0e356218650bd2e788b481b101e971 to your computer and use it in GitHub Desktop.
65. 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.
Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.
Copyright © 2018 LeetCode
*/
#include "stdafx.h"
#include <iostream>
#include <functional>
#include <cctype>
#include <algorithm>
bool isNumber(std::string s) {
//trim L
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
return !std::isspace(ch);
}));
//trim R
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
return !std::isspace(ch);
}).base(), s.end());
if (s.length() == 0)
return false;
bool prevDigit = false;
bool nextDigitRequired = false;
bool expanentaMode = false;
bool onlyOneDotAllowed = false;
bool onlyOneSignAllowed = false;
for (auto &c : s) {
bool isDigit = std::isdigit(c) != 0;
bool isSpace = std::isspace(c) != 0;
bool isDot = c == '.';
bool isExpanenta = c == 'e';
bool isMunus = c == '-';
bool isPlus = c == '+';
if (isDigit) {
prevDigit = true;
nextDigitRequired = false;
continue;
}
if (isDot && !onlyOneDotAllowed && !expanentaMode) {
nextDigitRequired = !prevDigit;
onlyOneDotAllowed = true;
continue;
}
// Epanenta mode allows plus or minus inside of experession
if (expanentaMode && (isPlus || isMunus) && !onlyOneSignAllowed) {
nextDigitRequired = true;
onlyOneSignAllowed = true;
continue;
}
if (nextDigitRequired) {
return false;
}
if (isMunus || isPlus) {
nextDigitRequired = true;
if (prevDigit) {
return false;
}
continue;
}
if (isExpanenta && prevDigit && !expanentaMode) {
expanentaMode = true;
nextDigitRequired = true;
continue;
}
return false;
}
if (nextDigitRequired) {
return false;
}
return true;
}
void checkValue(std::string input, bool expected)
{
auto result = isNumber(input);
if (result != expected) {
throw new std::runtime_error("Failed on \"" + input + "\" Expected: " + (expected ? "(True)" : "(False)"));
}
}
int main()
{
// Default from task
checkValue("0", true);
checkValue(" 0.1", true);
checkValue("abc", false);
checkValue("1 a", false);
checkValue("2e10", true);
// Addtional checks
checkValue("", false);
checkValue(" ", false);
checkValue("2e10 ", true);
checkValue("2e10e2", false);
checkValue("2e", false);
checkValue("1 ", true);
checkValue(".1", true);
checkValue("3.", true);
checkValue("..2", false);
checkValue("1 4", false);
checkValue("1 4", false);
checkValue("1..4", false);
checkValue("1 ", true);
checkValue(" .9", true);
checkValue("-9", true);
checkValue(" -9.0", true);
checkValue("3-2", false);
checkValue("0- ", false);
checkValue("+1", true);
checkValue(" +.8", true);
checkValue("1e.", false);
checkValue(".-4", false);
checkValue("6e6.5", false);
checkValue(" 005047e+6", true);
checkValue("459277e38+", false);
checkValue("2e+60++604", false);
checkValue("32.e-80123", true);
std::cout << "Success!" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment