C语言求解 表示数值的字符串

解题思路

这道题看起来比较难,但是实际上只是很复杂!因为情况比较多,需要一步一步的实现。对于一个数字,整数——> 小数 ——>科学数,依次进行判断

小数的组成部分 [若干空格]任意整数[无符号整数] 科学数的组成部分 有小数

整数判定

要判断一个数是否为整数,其满足的条件有:

整数(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. (可选)一个符号字符('+' 或 '-')
  3. 至少一位数字
  4. 若干空格

第一步 去除字符串首位的空格。

第二步 判断第一位是否为+ -符号。

第三步 判断之后所有的字符是否都在0~9之间。

由于之后的小数判断和科学数判断会用到整数,因此将纯整数(不包含前后空格)额外标注出来。

/*
* @brief 整数判断函数
* @param 输入一个字符串
* @return 返回 3:无前后空格 无+-号 的优质整数
* @return 返回 4:无前后空格 必须有+ 或者- 的整数
* @return 返回 0 :不是整数
*/
int isInt(char* num);

小数判定

  1. 若干空格
  2. (可选)一个符号字符('+' 或 '-')
  3. 可能是以下描述格式之一:
    3.1 至少一位数字,后面跟着一个点 '.'
    3.2 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
    3.3 一个点 '.' ,后面跟着至少一位数字
  4. 若干空格

第一步:去除前后空格

第二步:判断第一个字符是否为+ -

第三步:判断第一个字符是否为小数点 如果为小数点 后续必须是一个优质整数(无符号 无空格)

第四步:吞掉前面的数字(0~9)

第五步:判断当前是否为小数点 如果是,判断是否到字符串尾,没到字符串尾 判断后续是否为优质整数(无符号,无空格)

/*
* @brief 小数判断函数
* @param 输入一个字符串
* @return 返回 3: 没有前导空格和后导空格(可以有 + -号)
* @return 返回0:不是小数
*/
int isFloat(char* num) ;

判断科学数

  1. 若干空格
  2. 一个整数或者小数
  3. 一个 'e' 或 'E' ,后面跟着一个整数(可正可负)
  4. 若干空格

第一步: 去除前后空格

第二步:遍历整个字符串寻找e或者E的位置,并且记录个数 如果个数不是1 返回0

第三步:创建新的字符串,接收e之前的字符串,判断其是否为整数或者小数(可以带符号)

第四步:判断e之后的字符串,判断其是否为整数

是科学数返回1,否则返回0;

判断是否为数字

如果满足以上三个任意一个为真 否则为假

完整代码

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param str string字符串 
 * @return bool布尔型
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/*科学计数法的数字(按顺序)可以分成以下几个部分:
1.若干空格
2.一个整数或者小数
3.(可选)一个 'e' 或 'E' ,后面跟着一个整数(可正可负)
4.若干空格
*/
int isScience(char* num) {
	//整数或者小数 直接返回1;
	if (isInt(num) != 0 || isFloat(num) != 0)
		return 1;
	int len = strlen(num);
	char *part1=(char *)malloc(len);
	int part1_i = 0;
	int flag = 3;
	int i = 0,j=0;
	int count_e = 0,loc_e=0;
	//首先去除前导空格
	while (num[i] == ' ') {
		flag = 5;
		i++;
	}
	//去除后导空格
	while (num[len - 1] == ' ')
	{
		flag++;
		num[len - 1] = '\0';
		len--;
	}
	//先寻找e 或者E的位置以及个数
	for (j = i; j < len; j++)
		if (num[j] == 'e' || num[j] == 'E')
		{
			loc_e = j;
			count_e++;
		}
	//e的个数不是1 
	if (count_e != 1)
		return 0;
	//找到e的位置 判断e前的部分是否为整数或者小数
	for (int k = i; k < loc_e; k++)
		part1[k - i] = num[k];
	part1[loc_e - i] = '\0';
	//前半部分为小数 或者整数(可以包含符号)
	if (isFloat(part1) != 3 && isInt(part1) != 3&&isInt(part1) != 4)
		return 0;
    //后半部分为整数 (可以含有符号)
	if (isInt(&num[loc_e + 1]) != 3&&isInt(&num[loc_e + 1])!=4)
		return 0;
	return 1;

}
/*小数(按顺序)可以分成以下几个部分:
1.若干空格
2.(可选)一个符号字符('+' 或 '-')
3. 可能是以下描述格式之一:
3.1 至少一位数字,后面跟着一个点 '.'
3.2 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
3.3 一个点 '.' ,后面跟着至少一位数字
4.若干空格
*/
/*
* @brief 小数判断函数
* @param 输入一个字符串
* @return 返回 3: 没有前导空格和后导空格 (可以含有+ 或 -)
* @return 返回0:不是小数
*/
int isFloat(char* num) {
	int len = strlen(num);
	int flag = 3;
	int i = 0;
	//首先去除前导空格
	while (num[i] == ' ') {
		flag = 5;
		i++;
	}
		
	//去除后导空格
	while (num[len - 1] == ' ')
	{
		flag++;
		num[len - 1] = '\0';
		len--;
	}
	//判断第一个字符是否是符号
	if (num[i] == '+' || num[i] == '-')
	{
		i++;
	}
	//判断去除符号的字符是否为"."
	if (num[i] == '.')
	{
		i++;
		//遇到小数点 判断小数点后面必须为 优质整数
		if (isInt(&num[i]) == 3)
			return flag;
		else
			return 0;
	}
	//第一个字符不是小数点
	else {
		//非数字 返回0
		if (num[i] < '0' || num[i]>'9')
			return 0;
		//是数字 则吞掉小数点前所有数字
		else {
			while (num[i]>= '0'&&num[i]<='9' && i < len)
				i++;
			if (num[i] != '.')
				return 0;
			// 最后一位是小数点 返回1;
			else if (i == len - 1)
			{
				return flag;
			}
			else if (isInt(&num[i+1]) == 3)
				return flag;
			else
				return 0;

		}
	}
}
/*整数(按顺序)可以分成以下几个部分:
1.若干空格
2.(可选)一个符号字符('+' 或 '-')
3. 至少一位数字
4.若干空格
*/
/*
* @brief 小数判断函数
* @param 输入一个字符串
* @return 返回 3:无前后空格 无正负号 优质整数
* @return 返回 4:没有导空格整数 一定含有一个+ 或者-的半优质整数
* @return 返回 0 :不是整数
*/
int isInt(char* num) {
	int len = strlen(num);
	int flag = 3;
	int i = 0;
	//去除前导空格
	if (num[0] == ' ')
		flag = 5;
	if (num[len-1] == ' ')
		flag ++;
	while (num[i] == ' ' && i < len) {
		i++;
	}
		
	//判断首位 是否有符号
	if (num[i] == '+')
	{
        flag++;
		i++;
	}
	else if (num[i] == '-')
	{
        flag++;
		i++;

	}
	//判断第一个字符是否为数字 不是数字返回0
	if (num[i] < '0' || num[i]>'9')
		return 0;
	//遍历所有的数字
	while (num[i] >= '0' && num[i] <= '9' && i < len)
		i++;
	//如果指向尾 说明全是数字。
	if (i == len)
		return flag;
	//说明中断,此时需要判断是不是空格引起的"1244 ff"
	else {
		flag = 2;
		for (; i < len; i++)
			if (num[i] != ' ')
				return 0;
	}
	return flag;
}
/*例如,字符串["+100", "5e2", "-123", "3.1416", "-1E-16"]都表示数值。
但是["12e", "1a3.14", "1.2.3", "+-5", "12e+4.3"]都不是数值。

提示 :
1.1 <= str.length <= 25
2.str 仅含英文字母(大写和小写),数字(0 - 9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。
3.如果怀疑用例是不是能表示为数值的,可以使用python的print(float(str))去查看
进阶:时间复杂度O(n)\O(n) ,空间复杂度O(n)\O(n)*/

bool isNumeric(char* str) {
	if (isInt(str) || isFloat(str) || isScience(str) != 0)
		return true;
	else return false;
}