剑指offer -- 表示数值的字符

题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100"、“5e2”、”-123”、“3.1416"及”-1E-16"都表示数,但"12e"、1a3.14"、“1.2.3”、“±5"及“12e+5.4”都不是。

分析:判断一个字符串是否表示一个数值 通过题中给出的例子我们能分析出
一个字符串是否是一个能表示出一个数值的模板

+/-/ A . B E(e) +/-/ C

一个有符号整数A(整数部分)
一个符号整数B (小数部分)
E(e)后面表示 指数部分 C
C为有符号整数

我们先扫描整数部分,当然整数部分可以不存在。如.023 表示数字 0.023。(在c语言中是合法的,不信你可以用编译器试试~)
有可能会遇到+/- 。然后遇到 .,开始扫描小数部分,然后遇到 E/e开始扫描指数部分,也是会可能在开头遇到 +/- 。
综上,我们需要一个函数扫描A、C 还需要一个函数扫描B,而扫描 A 、C的函数其实就是去掉可能存在的 +/- ,然后把参数传到 扫描B的函数里。

#include<iostream>
using namespace std;

bool IsInterger(const char **str);
bool UnsignedIsInteger(const char **str);
bool IsNumber(const char *str){
    
    
	if(str == NULL)
		return false;

	bool flag = IsInterger(&str) ; //整数部分

	if(*str == '.'){
    
    
		str++;
		
		flag = UnsignedIsInteger(&str) || flag; //整数部分可以不存在 同样 小数点后面也可以没有数字 所以是 ||
		
	}

	if(*str == 'E'||*str == 'e'){
    
    
		str++;

		flag = flag && IsInterger(&str); //如果存在指数部分 则前面必须存在数值 而且后面也必须存在数字 且全部是数字 为整数
	}

	return flag && *str == '\0'; //即使走过了上面flag为true 但是那也只能证明指数部分存在的数位 前面可能存在部分整数 
	      //比如 -12.34E12.5 所以必须要走到结尾 才是真正完成
 
}

bool IsInterger(const char **str){
    
    
	if(**str == '+' || ** str == '-')  //去掉+/-
		(*str) ++;

	return UnsignedIsInteger(str);
}

bool UnsignedIsInteger(const char **str){
    
    
	const char *before = *str;

	while(**str !='\0' && **str >= '0' && **str <= '9')
		(*str)++;

	return *str > before; //存在部分整数则str后移 返回true 不存在则false
}

int main()
{
    
    
	const char *str1 = "+123.45+75.e-3";
	const char *str2 = ".123e+12";
	const char *str3 = "+123.456E+4.5"; 
	const char *str4 = "-123.456E-5";
	const char *str5 = "-.123";
	const char *str6 = "-.E6";

	cout<<IsNumber(str1)<<" "<<IsNumber(str2)<<" "<<IsNumber(str3)<<endl;
	cout<<IsNumber(str4)<<" "<<IsNumber(str5)<<" "<<IsNumber(str6)<<endl;
	

	return 0;
}

在这里插入图片描述

不知道有的朋友看完上面的代码会不会有一点疑问,我们在扫描函数的时候为什么要传const char ** , 传 一个*不就可以了吗?就是遍历指针向后走呀,我们确实是遍历指针向后走,但是我们遍历指针到指定位置,然后返回结果以后,我们希望的是再把str传到函数里的时候,是从上次遍历结束的位置开始遍历,str从上次的位置结束,只是在这个函数里到了这个位置。出了函数还是原来的指针变量,所以要传二级指针每次遍历改变指针的指向。

Guess you like

Origin blog.csdn.net/scarificed/article/details/120417183