diff --git a/NumericStrings/NumericString.cpp b/NumericStrings/NumericString.cpp index 6c60d35..37b4909 100644 --- a/NumericStrings/NumericString.cpp +++ b/NumericStrings/NumericString.cpp @@ -1,84 +1,74 @@ -/* - * Question Description: - * (Question 12 in ) How do you check whether a string stands for a number or not? - * Numbers include positive and negative integers and floats. For example, strings “+100.”, “5e2”, “-.123”, “3.1416”, and “-1E-16” - * stand for numbers, but “12e”, “1a3.14”, “1.2.3”, “+-5”, and “12e+5.4” do not. +/* +* Question Description: +* (Question 12 in ) How do you check whether a string stands for a number or not? +* Numbers include positive and negative integers and floats. For example, strings "+100.", "5e2", "-.123", "3.1416", and "-1E-16" +* stand for numbers, but "12e", "1a3.14", "1.2.3", "+-5", and "12e+5.4" do not. */ #include -void scanDigits(char** string); -bool isExponential(char** string); +bool scanUnsignedInteger(const char** str); +bool scanInteger(const char** str); -bool isNumeric(char* string) +// the form of exponent is like A[.[B]][e|EC] or .B[e|EC] +// where A and C is an integer with or without sign, and B is an unsigned integer +bool isNumeric(const char* str) { - if(string == NULL) + if (str == NULL) return false; - if(*string == '+' || *string == '-') - ++string; - if(*string == '\0') - return false; + bool numeric = scanInteger(&str); - bool numeric = true; - - scanDigits(&string); - if(*string != '\0') - { - // for floats - if(*string == '.') - { - ++string; - scanDigits(&string); - - if(*string == 'e' || *string == 'E') - numeric = isExponential(&string); - } - // for integers - else if(*string == 'e' || *string == 'E') - numeric = isExponential(&string); - else - numeric = false; + // for floats + // you can have no integer part such as .123 means 0.123 + // in the meanwhile, you can have no decimal part such as 233. means 233.0 + // what's more, 233.666 is OK also. + if (*str == '.') { + ++str; + numeric = scanUnsignedInteger(&str) || numeric; } - return numeric && *string == '\0'; -} + // for exponent + if (*str == 'e' || *str == 'E') { + ++str; + numeric = scanInteger(&str) && numeric; + } -void scanDigits(char** string) -{ - while(**string != '\0' && **string >= '0' && **string <= '9') - ++(*string); + return numeric && *str == '\0'; } -bool isExponential(char** string) +bool scanUnsignedInteger(const char** str) { - if(**string != 'e' && **string != 'E') - return false; - - ++(*string); - if(**string == '+' || **string == '-') - ++(*string); + const char* pBefore = *str; + while (**str != '\0' && **str >= '0' && **str <= '9') + ++(*str); - if(**string == '\0') - return false; + // return true when there are some digits in str + return *str > pBefore; +} - scanDigits(string); - return (**string == '\0') ? true : false; +// an integer's form is like [+|-]B, where B is an unsigned integer +bool scanInteger(const char** str) +{ + if (**str == '+' || **str == '-') + ++(*str); + return scanUnsignedInteger(str); } // ==================== Test Code ==================== -void Test(char* testName, char* string, bool expected) +void Test(const char* testName, const char* str, bool expected) { - if(testName != NULL) + if (testName != NULL) printf("%s begins: ", testName); - if(isNumeric(string) == expected) + if (isNumeric(str) == expected) printf("Passed.\n"); else printf("FAILED.\n"); } + int main(int argc, char* argv[]) { Test("Test1", "100", true); @@ -99,6 +89,9 @@ int main(int argc, char* argv[]) Test("Test13", "1.2.3", false); Test("Test14", "+-5", false); Test("Test15", "12e+5.4", false); + Test("Test16", ".", false); + Test("Test17", ".e1", false); + Test("Test18", "+.", false); - return 0; + return 0; }