/* binsearch(),二分查找,在v[0]<=v[1]...<=v[n-1]中查找x */
int binsearch(int x, int v[], int n)
{
int low, high, mid;//!
low = 0;
high = n - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (v[mid] < x)//无“=”
low = mid + 1;//注意+1,代表Mid不算在内
else if (v[mid] > x)
high = mid - 1;
else
return v[mid];
}
return -1;//没有找到匹配的值
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二分查找的关键点:
1、三个量:中间序号mid,最大序号high,最小序号low.
注意三个量的初始化!
2、前提:已经排序的数组
3、low=mid+1;high=mid-1;排除了mid这一项
4、mid=(low+high)/2 放到循环里面,放到外面多此一举(毕竟循环内部也要放一次)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* 统计数字、字符、空白符及其他字符出现次数【switch版】 */
int main(void)
{
int c;
int nwhite, ndigit[10], nother;
int i;
for (i = 0;i < 10;i++)
ndigit[i] = 0;
nwhite = nother = 0;
while ((c = getchar()) != EOF)
{
switch (c)
{
case '0':case'1':case'2':case'3':case'4':
case'5':case'6':case'7':case'8':case'9':
ndigit[c - '0']++;//注意这种处理,将字符数字与整数数字互相转化
break;
case ' ':case'\n':case'\t':
nwhite++;
break;
default:
nother++;
break;//!!!养成习惯!
}
}
//打印...
return 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、return :
1.1 函数不一定都有返回值(return),没有返回值的函数将把控制权返回给调用者,
但是不一定返回有用的值。主调函数也可以忽略函数返回的值
1.2 main()本身也是个函数,也可以向调用者(程序的执行环境--操作系统)返回
一个值。一般情况,返回值为0,代表程序正常终止;非0,代表程序出现异常
1.3 函数的返回值有两种作用:a.返回一个需要的值 b.向其执行环境返回状态
2、使用c=getchar(),需要将c声明为int。
这样可以使c也存贮EOF的值(可能为-1,char型只能存正整数)
3、(c=getchar())!=EOF,()不可以省略!
否则执行顺序变成:c=(getchar()!=EOF),c将会被赋值为0或1.
4、使用switch语句时,养成向default:后面也加上break的习惯!
降低我们添加其他分支时,犯错误的可能性。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* atoi(),将字符串转化成对应数值。---Vol.2*/
//改进部分:可以处理带符号(+ -)的字符;可以处理前导空白符
#include<ctype.h>
int atoi(char s[])
{
int i, n, sign;
for (i = 0;isspace(s[i]);i++)//跳过前导空白符
;
sign = (s[i] == '-') ? -1 : 1;//处理符号
if (s[i] == '+' || s[i] == '-')
i++;
for (n = 0;isdigit(s[i]);i++)
n = n * 10 +( s[i] - '0');
return sign*n;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、<ctype.h>中:
1.isdigit(),判断是否是数字
2.tolower(),将大写字母变为小写字母
3.isspace(),判断是否为空白符(空格、换行符、制表符...)
2、缺陷:1.只能跳过前面的空白符
3、注意此函数中的操作:1.如何跳过前导空白符
2.如何处理带符号的字符串
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* shellsort(),shell排序算法:按递增顺序对v[0]...v[n-1]排序 */
void shellsort(int v[], int n)
{
int gap, i, j, temp;
for (gap = n / 2;gap > 0;gap /= 2)
for (i = gap;i < n;i++)//右边界限
for (j = i - gap;j >= 0 && v[j] > v[i];j -= gap)//左边界限
{
//交换v[j]和v[i](v[j+gap])
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}
/* reverse(s),倒置字符串s中各个字符的位置 */
#include<string.h>
void reverse(char s[])
{
int temp;
int i, j;
for (i = 0, j = string(s) - 1;i < j;j--, i++)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、string(),计算字符串长度
2、元素交换可以用一条语句来操作(,运算符),例如:
temp=a,a=b,b=temp;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* itoa(),将数字转化为字符串并保存到字符串s中 */
void itoa(int n, char s[])
{
int c, i;
int sign;//可以对符号进行处理
sign = n;//记录符号
if (sign < 0)
n = -n;
i = 0;
//逆序生成数字字符
do
s[i++] = (n % 10) + '0';//注意要加上'0'
while ((n / 10) > 0);//!!
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、一开始生成的逆序的字符串,最后要把字符串倒置
2、要考虑到负数的情况,对符号进行处理
3、do-while语句中,while()后要有“;”
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* trim(),删除字符串s尾部的空格符、换行符、制表符 */
#include<string.h>
int trim(char s[])
{
int n;
for (n = string(s) - 1;n >= 0;n--)
if (n != '\n'&&n != '\t'&&n != ' ')
break;
s[n + 1] = '\0';
return n;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、反向寻找第一个不是空白符的字符,然后跳出循环
2、处理字符串注意在结尾处加上'\0'!!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/