C语言求解 表示数值的字符串
解题思路
这道题看起来比较难,但是实际上只是很复杂!因为情况比较多,需要一步一步的实现。对于一个数字,整数——> 小数 ——>科学数,依次进行判断
小数的组成部分 [若干空格]任意整数[无符号整数] 科学数的组成部分 有小数
整数判定
要判断一个数是否为整数,其满足的条件有:
整数(按顺序)可以分成以下几个部分:
- 若干空格
- (可选)一个符号字符('+' 或 '-')
- 至少一位数字
- 若干空格
第一步 去除字符串首位的空格。
第二步 判断第一位是否为+ -符号。
第三步 判断之后所有的字符是否都在0~9之间。
由于之后的小数判断和科学数判断会用到整数,因此将纯整数(不包含前后空格)额外标注出来。
/*
* @brief 整数判断函数
* @param 输入一个字符串
* @return 返回 3:无前后空格 无+-号 的优质整数
* @return 返回 4:无前后空格 必须有+ 或者- 的整数
* @return 返回 0 :不是整数
*/
int isInt(char* num);
小数判定
- 若干空格
- (可选)一个符号字符('+' 或 '-')
- 可能是以下描述格式之一:
3.1 至少一位数字,后面跟着一个点 '.'
3.2 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
3.3 一个点 '.' ,后面跟着至少一位数字 - 若干空格
第一步:去除前后空格
第二步:判断第一个字符是否为+ -
第三步:判断第一个字符是否为小数点 如果为小数点 后续必须是一个优质整数(无符号 无空格)
第四步:吞掉前面的数字(0~9)
第五步:判断当前是否为小数点 如果是,判断是否到字符串尾,没到字符串尾 判断后续是否为优质整数(无符号,无空格)
/*
* @brief 小数判断函数
* @param 输入一个字符串
* @return 返回 3: 没有前导空格和后导空格(可以有 + -号)
* @return 返回0:不是小数
*/
int isFloat(char* num) ;
判断科学数
- 若干空格
- 一个整数或者小数
- 一个 'e' 或 'E' ,后面跟着一个整数(可正可负)
- 若干空格
第一步: 去除前后空格
第二步:遍历整个字符串寻找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;
}