实验结论
1. 二分查找
形参是数组,实参是数组名
// 练习:使用二分查找,在一组有序元素中查找数据项 #include <stdio.h> const int N=10; int binarySearch(int x[], int n, int item); int main() { int a[N]={1,3,9,16,21,23,45,65,98,1026}; int i,index, key; while(1){ printf("\n\n数组a中的数据:\n"); for(i=0;i<N;i++) printf("%d ",a[i]); printf("\n"); printf("输入待查找的数据项: "); scanf("%d", &key); // 调用函数binarySearch()在数组a中查找指定数据项item,并返回查找结果给index // 补足代码① index=binarySearch(a,N,key); if(index>=0) printf("%d在数组中,下标为%d\n", key, index); else printf("%d不在数组中\n", key); } return 0; } //使用二分查找算法在数组x中查找特定值item,数组x大小为n int binarySearch(int x[], int n, int item) { int low, high, mid; low = 0; high = n-1; while(low <= high) { mid = (low+high)/2; if (item == x[mid]) return mid; // 如果找到,返回其下标 else if(item < x[mid]) high = mid - 1; else low = mid + 1; } return -1; // 如果没找到,返回-1 }
形参是指针变量,实参是数组名
// 练习:使用二分查找,在一组有序元素中查找数据项 #include <stdio.h> const int N=7; int binarySearch(int *x, int n, int item); int main() { int a[N]={1,2,3,9,16,21,200}; int i,index, key; printf("数组a中的数据:\n"); for(i=0;i<N;i++) printf("%d ",a[i]); printf("\n"); printf("输入待查找的数据项: "); scanf("%d", &key); // 调用函数binarySearch()在数组a中查找指定数据项item,并返回查找结果 // 补足代码① index=binarySearch(a,N,key); if(index>=0) printf("%d在数组中,下标为%d\n", key, index); else printf("%d不在数组中\n", key); return 0; } //使用二分查找算法在x指向的数据项开始的n个数据中,查找item int binarySearch(int *x, int n, int item) { int low, high, mid; low = 0; high = n-1; while(low <= high) { mid = (low+high)/2; if (item == *(x+mid)) return mid; // 如果找到,返回其位置 else if(item < *(x+mid)) high = mid - 1; else low = mid + 1; } return -1; // 如果没找到,返回-1 }
2. 选择法排序
// 选择法对字符串按字典序排序 #include <stdio.h> #include <string.h> void selectSort(char str[][20], int n ); int main() { char name[][20] = {"John", "Alex", "Joseph", "Candy", "Geoge"}; int i; printf("输出初始名单:\n"); for(i=0; i<5; i++) printf("%s\n", name[i]); selectSort(name, 5); printf("按字典序输出名单:\n"); for(i=0; i<5; i++) printf("%s\n", name[i]); return 0; } // 函数功能描述:使用选择法对二维数组str中的n个字符串按字典序排序 void selectSort(char str[][20], int n) { // 补足代码 int i, j, k, temp ; for(i=0; i<n-1; i++) { k = i; for(j=i+1; j<n; j++) if (str[j][0] < str[k][0]) k = j; if(k != i) { for(j=0;j<20;j++){ temp = str[i][j]; str[i][j] = str[k][j]; str[k][j] = temp; } } } }
或者把temp定义为数组(然而我的第一反应还是偏向于较为熟悉的上边)
void selectSort(char str[][20], int n) { int i,j,k; char temp[20]; for(i=0;i<n-1;i++){ k=i; for(j=i+1;j<n;j++) if(strcmp(str[j],str[k])<0) k=j; if(k!=i){ strcpy(temp,str[i]); strcpy(str[i],str[k]); strcpy(str[k],temp); } } }
3. 用指针处理字符串
// 用指针变量处理字符串练习1 // 删除前导* #include <stdio.h> void delPrefixStar(char []); int main() { char string[80]; printf("输入一个字符串:\n"); gets(string); printf("\n删除<前导*>之前的字符串:\n"); puts(string); delPrefixStar(string); // 注意实参的写法 printf("\n删除<前导*>之后的字符串:\n"); puts(string); return 0; } // 删除字符数组s中前导* void delPrefixStar(char s[]) { char *target, *source; source = s; // 从字符串开始找到不是*的位置 while(*source == '*') source++; target = s; // // 从这个位置开始将余下的字符前移 while( *target++ = *source++); }
// 用指针变量处理字符串练习2 // 删除中间和末尾的* (即除了前导*,删除字符串中其它全部*) #include <stdio.h> void delStarButPrefix(char []); int main() { char string[80]; printf("输入一个字符串:\n"); gets(string); printf("\n删除<中间和末尾的*>之前的字符串:\n"); puts(string); delStarButPrefix(string); printf("\n删除<中间和末尾的*>之后的字符串:\n"); puts(string); return 0; } void delStarButPrefix(char s[]) { int i=0; char *p = s; while(*p && *p == '*') { // 跳过前导*,i记录字符在字符数组s中的下标,p记录首个非*字符的位置 p++; i++; } while(*p) { if(*p != '*') { s[i] = *p; i++; } p++; //删除字符数组s中除了前导*以外的所有*(即删除字符串中间和末尾出现的*) } s[i] = '\0'; //赋值中,'\0'并未被赋值进数组,所以要单独赋值,使数组结构完整 }
// 用指针变量处理字符串练习3 // 删除字符串中间的* #include <stdio.h> void delMiddleStar(char []); int main() { char string[80]; printf("输入一个字符串:\n"); gets(string); printf("\n删除<中间的*>之前的字符串:\n"); puts(string); delMiddleStar(string); printf("\n删除<中间的*>之后的字符串:\n"); puts(string); return 0; } // 对字符数组s中存放的字符串,删除中间出现的* void delMiddleStar(char s[]) { int i=0; char *tail, *head, *p; tail = s; // 找到末尾第一个非*字符的位置 while(*tail) tail++; //行进到最后 tail--; while(*tail == '*') tail--; head = s; // 找到开头第一个非*字符的位置 while(*head == '*') head++; // 把中间出现的*去掉 p = s; while(p<=head) { // 这里实现的功能enmmm 在开头没有*号时我附我自己 ,直到head处 s[i] = *p; p++; i++; } while(p<tail) { //开始判断去*号 if(*p != '*') { s[i] = *p; i++; } p++; } while(*p) { //由于*p虽然到tail处 但内容仍不为零 依然是 我附我自己 直到末尾遇到\0 s[i] = *p; i++; p++; } s[i] = '\0'; //让数组可以正常结束 }
实验总结和体会
细想一下,上次做实验已经是很久以前了,实验的内容也显得有一些困难了,如果让我自己设计虽然没什么问题,不过肯定要花很长的时间。再加上有用很多时间去花在百科园上,而没用电脑编程验证一些所学内容,导致还很多内容是模糊的(主要是指针变量的调用)。近些天的坑也多集中在指针的调用上,对于指针的应用简直硬伤。甚至在函数的定义和调用上还是会出现问题,比如括号内不写定义数据类型,或者在函数的形参实参拎不清。除了这些就是二维数组的练习试水太少了,以至于在交换行时不会用strcpy,虽然对每一个元素交换和strcpy本质是相同的流程,但是别人既然已经写好了为什么不用呢。