目录
表示数值的字符串判断
数组中出现次数超过数组长度一半的数
表示数值的字符串判断
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串"+100"
,"5e2"
,"-123"
,"3.1416"
和"-1E-16"
都表示数值。
但是"12e"
,"1a3.14"
,"1.2.3"
,"+-5"
和"12e+4.3"
都不是。
算法思路:首先要认识字符串表示数字的规则,表示数值的字符串遵循模式 A[.[B]][E/eC]或者.B[E/eC],其中A为数值的整数部分,B紧跟着小数点为数值的小数部分,C紧跟着'E'或者'e'为数值的指数部分。在小数里可能没有数值的整数部分。例如,小数.123等于0.123。因此A部分不是必须的,如果一个数没有整数部分,那么它的小数部分不能为空。
上述A和C都有可能以'+'或者'-'开头的0~9的数位串;B也是0~9的数位串,但前面不能有正负号。
以表示数值的字符串123.45e+6为例,'123'是他的整数部分A,'45'为他的小数部分B,'+6'是他的指数部分C。
首先应该判断'+','-'两个符号,接着尽可能多的扫描数字0~9,也就是前面的整数部分A,如果遇到小数点'.',则开始扫描小数部分B,如果遇到字符'E','e',则开始扫描表示指数部分的c部分。也就是说我们可以把它合并成一个整体的公式+(-)A.Be+(-)C,用该公式来整理以下思路:首先判断'+'或者'-'如果存在,接着进行遍历,找A部分,也就是整数部分,到此处如果结束便是一个数值,接着判断小数点部分,遇到小数点直接进行+1,继续遍历,此处应该扫描小数部分b,接着判断'e/E'符号,此处可以有‘+’‘-’,判断指数部分c,结束。
代码如下:
bool pdzg(char *arr)
{ int i = 0;
bool isarr = false;
while (arr[i] == ' '){
i++;
}//初始化判断最前面的空格
if (arr[i] == '+' || arr[i] == '-') i++;//整数部分的加减号,有无对结果无影响
while (arr[i] >= '0' && arr[i] <= '9'){//判断整数部分,此处如果有也是合法的,若没有也不影响
isarr = true;//标记此处合法,若此处结束返回值为true
i++;
}
if (arr[i] == '.') ++i;//扫描'.'符号,该处合法与否在于其后面有没有小数部分
while (arr[i] >= '0' && arr[i] <= '9'){//扫描小数部分
isarr = true;//若存在小数部分则前面的'.'合法,
i++;
}
if (isarr && (arr[i] == 'e' || arr[i] == 'e')){//如果存在e/E,其合法性同样要看指数部分
i++;
isarr = false;//此处标记,若没有指数部分到该处结束,则不合法
if (arr[i] == '-' || arr[i] == '+') ++i;//'+','-',此处合法性仍要看后面指数部分
while (arr[i] >= '0'&&arr[i] <= '9'){扫描指数部分,
++i;
isarr = true; //存在指数部分则合法。
}
}
return (arr[i] == '\0'&&isarr);//只有数组遍历完全后,isarr为true标记着合法,同时为真才能确保该字符串表示数字。
}
此处代码解释较完完整,若又不懂可留言解答。
数组中出现次数超过数组长度一半的数
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
该题方法较多:1)用类对象进行,将每一个数组元素出现的次数均表示出来,然后和数组长度的一半进行比较。
2)首先进行排序,若一个数字出现的次数大于数组长度的一半,那么该数组排序后中间的数字便是我们需要的结果。
3)第三种方法便是最推荐用的抵消法,定义元素result和times,一个为数组中出现的元素,一个为出现的次数,将数组首元素进行result赋值,开始从第二元素开始遍历,若和result相同,则times加一,若不同则进行减一操作,若times为0,则进行开始重新赋值。因为求的元素出现次数大于数组长度的一半,所以所求元素的times肯定大于等于1。最后进行判断,元素出现次数是否大于元素长度的一半,若大于则返回元素,若不大于则返回0;代码如下
int numsmid(int*arr, int len){
assert(arr != NULL&&len > 0);
int times=1;
int count = 0;
int result=arr[0];
for (int i = 1; i < len; i++){
if (times == 0){
result = arr[i];
times = 1;
}
else{
if (result == arr[i]){
times++;
}
else times--;
}
}
for (int j = 0; j < len; j++)
{
if (result == arr[j]) count++;
}
if (count>len/2)//判断
return result;
else return 0;
}