《剑指offer》第二十题:表示数值的字符串
// 面试题20:表示数值的字符串 // 题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如, // 字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值,但“12e”、 // “1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是 #include <stdio.h> bool scanUnsignedInteger(const char** str); bool scanInteger(const char** str); // 数字的格式可以用A[.[B]][e|EC]或者.B[e|EC]表示,其中A和C都是 // 整数(可以有正负号,也可以没有),而B是一个无符号整数 bool isNumeric(const char* str) //传入为首地址 { if (str == nullptr) return false; //判断整数部分 bool isNumber = scanInteger(&str); //传入地址是因为需要修改str的值, //判断小数部分 if (*str == '.') { ++str; //可以没有整数或者小数部分 isNumber = scanUnsignedInteger(&str) || isNumber; } //判断指数部分 if (*str == 'E' || *str == 'e') { ++str; //指数前或者后不能没有数字 isNumber = scanInteger(&str) && isNumber; } //判断是否已经到达末尾 return isNumber && *str == '\0'; } bool scanUnsignedInteger(const char** str) { const char* before = *str; //原来的位置 while (**str != '\0' && **str >= '0' && **str <= '9') ++(*str); return before < *str; } // 整数的格式可以用[+|-]B表示, 其中B为无符号整数 bool scanInteger(const char** str) { if (**str == '+' || **str == '-') ++(*str); //此时str为指向地址的指针 return scanUnsignedInteger(str); }

// ====================测试代码==================== void Test(const char* testName, const char* str, bool expected) { if (testName != nullptr) printf("%s begins: ", testName); if (isNumeric(str) == expected) printf("Passed.\n"); else printf("FAILED.\n"); } int main(int argc, char* argv[]) { Test("Test1", "100", true); Test("Test2", "123.45e+6", true); Test("Test3", "+500", true); Test("Test4", "5e2", true); Test("Test5", "3.1416", true); Test("Test6", "600.", true); Test("Test7", "-.123", true); Test("Test8", "-1E-16", true); Test("Test9", "1.79769313486232E+308", true); printf("\n\n"); Test("Test10", "12e", false); Test("Test11", "1a3.14", false); Test("Test12", "1+23", false); 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", "e1", false); Test("Test19", "+.", false); Test("Test20", "", false); Test("Test21", nullptr, false); return 0; }
分析:因为需要更改str的值,所以函数调用使用了**str,*str意为指向地址的指针,**str意为指向字符串的值。

class Solution { public: bool isNumeric(char* string) { if (string == nullptr) return false; bool isNumber = scanInteger(&string); if (*string == '.') { ++string; isNumber = scanUnsignedInteger(&string) || isNumber; } if (*string == 'e' || *string == 'E') { ++string; isNumber = scanInteger(&string) && isNumber; } return isNumber && *string == '\0'; } bool scanUnsignedInteger(char** string) { const char* before = *string; while (**string != '\0' && **string >= '0' && **string <= '9') ++(*string); return before < *string; } bool scanInteger(char** string) { if (**string == '+' || **string == '-') ++(*string); return scanUnsignedInteger(string); } };