实验五

一、实验结论

1、1. 设N个整数有序(由小到大)存放在一维数组中。编写函数binarySearch(),实现使用二分查找算法在一维数组中 查找特定整数item。如果找到,返回item在数组元素中的下标;如果item不在数组中,则返回-1。

方式①:形参是数组,实参是数组名,使用数组元素直接访问方式实现

 1 // 练习:使用二分查找,在一组有序元素中查找数据项
 2 //  形参是数组,实参是数组名 
 3 #include  <stdio.h>
 4 const int N=5;
 5 int binarySearch(int x[], int n, int item);
 6 int main() {
 7     int a[N]={2,4,10,17,22};//已更改数组中整数
 8     int i,index, key;
 9     
10     printf("数组a中的数据:\n");
11     for(i=0;i<N;i++)
12        printf("%d ",a[i]);
13     printf("\n");
14     
15     printf("输入待查找的数据项: ");
16     scanf("%d", &key);
17     
18     // 调用函数binarySearch()在数组a中查找指定数据项item,并返回查找结果给index 
19     // 补足代码① 
20     index=binarySearch(a,N,key); 
21     
22     if(index>=0) 
23         printf("%d在数组中,下标为%d\n", key, index);
24     else
25         printf("%d不在数组中\n", key); 
26    
27    return 0;
28 }
29 int binarySearch(int x[], int n, int item)
30 {
31     int left=0,right=n-1,mid=n/2,i;
32     while(1)
33     {
34         if(item==x[left])
35         return left;
36         
37         if(item==x[right])
38         return right;
39         
40         if(item==x[mid])
41         return mid;
42         
43         for(i=0;item!=x[i];)
44         {
45             if(i>n-1)
46             {
47                 return -1;
48                 break;
49             }
50             i++;
51          } 
52         
53         if(item<x[mid])
54         {
55             right=mid;
56             mid=(right+left)/2;
57         }
58         
59         if(item>x[mid])
60         {
61             left=mid;
62             mid=(right+left)/2;
63         }
64         
65     }
66     
67  } 

不好意思,写到这里才发现已经把函数给出来只是让填空,下面补上所给子函数:

 1 //函数功能描述: 
 2 //使用二分查找算法在数组x中查找特定值item,数组x大小为n 
 3 // 如果找到,返回其下标 
 4 // 如果没找到,返回-1 
 5 int binarySearch(int x[], int n, int item) 
 6 {
 7   int low, high, mid;
 8   low = 0;
 9   high = n-1;
10   while(low <= high) 
11   {        
12     mid = (low+high)/2;
13     if (item == x[mid])
14         return mid;
15     else if(item<x[mid])
16         high = mid - 1;
17     else            
18         low = mid + 1;    
19   }        
20   return -1; 
21 }

方式②:形参是指针变量,实参是数组名,使用指针变量间接访问方式实现

 1 // 练习:使用二分查找,在一组有序元素中查找数据项
 2 //  形参是指针变量,实参是数组名
 3 #include  <stdio.h>
 4 const int N=5;
 5 int binarySearch(int *x, int n, int item);
 6 int main() {
 7     int a[N]={2,4,10,17,22};
 8     int i,index, key;
 9     
10     printf("数组a中的数据:\n");
11     for(i=0;i<N;i++)
12        printf("%d ",a[i]);
13     printf("\n");
14     
15     printf("输入待查找的数据项: ");
16     scanf("%d", &key);
17     
18     // 调用函数binarySearch()在数组a中查找指定数据项item,并返回查找结果
19     // 补足代码①
20     index= binarySearch(a,N,key);
21     
22     if(index>=0) 
23         printf("%d在数组中,下标为%d\n", key, index);
24     else
25         printf("%d不在数组中\n", key); 
26    
27    return 0;
28 }
29 
30 //函数功能描述:
31 //使用二分查找算法在x指向的数据项开始的n个数据中,查找item
32 // 如果找到,返回其位置
33 // 如果没找到,返回-1 
34 int binarySearch(int *x, int n, int item) {
35     int low, high, mid;
36     
37     low = 0;
38     high = n-1;
39     
40     while(low <= high) {
41         mid = (low+high)/2;
42         
43         if (item == *(x+mid))
44             return mid;
45         else if(item < *(x+mid))
46             high = mid - 1;
47         else
48             low = mid + 1;
49     }
50     
51     return -1;
52 }

结果同方式①,不再重复 

 

2、使用选择法对字符串按字典序排序。不能直接使用关系运算符和赋值运算符,要借助字符串处理函数。

 1 // 练习:使用选择法对字符串按字典序排序
 2 #include <stdio.h>
 3 #include <string.h>
 4 void selectSort(char str[][20], int n ); // 函数声明,形参str是二维数组名 
 5 int main() {
 6     char name[][20] = {"John", "Alex", "Joseph", "Candy", "Geoge"};
 7     int i;
 8     
 9     printf("输出初始名单:\n");
10     for(i=0; i<5; i++)
11         printf("%s\n", name[i]);
12         
13     selectSort(name, 5);  // 调用选择法对name数组中的字符串排序
14     
15     printf("按字典序输出名单:\n");
16     for(i=0; i<5; i++)
17         printf("%s\n", name[i]);
18      
19     return 0;
20 } 
21 
22 // 函数定义
23 // 函数功能描述:使用选择法对二维数组str中的n个字符串按字典序排序 
24 void selectSort(char str[][20], int n) {
25     // 补足代码
26         int i, j, k;
27         char temp[20];
28     
29     for(i=0; i<n-1; i++) {
30         k = i;  // k用于记录当前最小元素的下标 
31         
32         for(j=i+1; j<n; j++)
33             if (strcmp(str[j],str[k])<0)
34                 k = j;   // 如果str[j]比当前最小元素还要小,就更新k,确保它总是存放最小元素的下标 
35                 
36         if(k != i) {  // 找到最小元素后,交换str[i]和str[k] 
37             strcpy(temp,str[i]);
38             strcpy(str[i],str[k]);
39             strcpy(str[k],temp);
40         }
41     }
42 }

 

3、 用指针处理字符串

①:假定输入的字符串中只包含字母和*,例如字符串****A*BC*DEF*G*******。编写子函数 delPrefixStar(),删除字符串中所有前导*删除,中间的和后面的*不删除。即删除后,字符串的内容应当是 A*BC*DEF*G*******

 1 // 用指针变量处理字符串练习1
 2 // 删除前导*
 3 #include <stdio.h>
 4 void delPrefixStar(char []); // 函数声明(函数声明中可以省略数组名不写) 
 5 
 6 int main() {
 7     char string[80];
 8     printf("输入一个字符串:\n");
 9     gets(string);
10     
11     printf("\n删除<前导*>之前的字符串:\n");
12     puts(string);
13     
14     delPrefixStar(string);  // 调用函数,删除前导*; 注意实参的写法 
15     
16     printf("\n删除<前导*>之后的字符串:\n");
17     puts(string);
18     
19     return 0;
20 } 
21 
22 // 函数定义
23 // 函数功能描述
24 // 删除字符数组s中前导* 
25 void delPrefixStar(char s[]) {
26     char *target, *source;
27     
28     // 从字符串开始找到不是*的位置
29     source = s;
30     while(*source == '*') 
31         source++;
32     
33     // 从这个位置开始将余下的字符前移
34     target = s;
35     while( *target++ = *source++);
36 }

 

②假定输入的字符串中只包含字母和*,例如字符串****A*BC*DEF*G*******。编写子函数 delStarButPrefix(),除了前导*之外,删除其它*。即删除后,字符串的内容应当是****ABCDEFG

 1 // 用指针变量处理字符串练习2
 2 // 删除中间和末尾的* (即除了前导*,删除字符串中其它全部*) 
 3 #include <stdio.h>
 4 void delStarButPrefix(char []); // 函数声明(函数声明中可以省略数组名不写) 
 5 
 6 int main() {
 7     char string[80];
 8     printf("输入一个字符串:\n");
 9     gets(string);
10     
11     printf("\n删除<中间和末尾的*>之前的字符串:\n");
12     puts(string);
13     
14     delStarButPrefix(string);  // 调用函数,删除中间和末尾的*; 注意实参的写法 
15     
16     printf("\n删除<中间和末尾的*>之后的字符串:\n");
17     puts(string);
18     
19     return 0;
20 } 
21 
22 // 函数定义
23 // 函数功能描述
24 // 删除字符数组s中除了前导*以外的所有*(即删除字符串中间和末尾出现的*) 
25 void delStarButPrefix(char s[]) {
26     int i=0;              // i用于记录字符在字符数组s中的下标 
27     char *p = s;
28     
29     // 跳过前导*,i记录字符在字符数组s中的下标,p记录首个非*字符的位置 
30     while(*p && *p == '*') {
31         p++;
32         i++;
33     }
34     
35     // 从p指向的字符开始,把遇到的*删除 
36     while(*p) {
37         if(*p != '*') {
38             s[i] = *p;
39             i++;
40         }
41         p++;
42     } 
43     
44     s[i] = '\0';   // 思考:这一步这样写的原因 
45 }

感觉可以把第30行改为while( *p == '*')

 

③假定输入的字符串中只包含字母和*,例如字符串****A*BC*DEF*G*******。编写子函数 delMiddleStar(),除了前导*和尾部*之外,删除中间出现的所有*。即删除后,字符串内容应当是 ****ABCDEFG*******

 1 // 用指针变量处理字符串练习3
 2 // 删除字符串中间的* 
 3 #include <stdio.h>
 4 void delMiddleStar(char []); // 函数声明(函数声明中可以省略数组名不写) 
 5 
 6 int main() {
 7     char string[80];
 8     printf("输入一个字符串:\n");
 9     gets(string);
10     
11     printf("\n删除<中间的*>之前的字符串:\n");
12     puts(string);
13     
14     delMiddleStar(string);  // 调用函数,删除字符串中间的*; 注意实参的写法 
15     
16     printf("\n删除<中间的*>之后的字符串:\n");
17     puts(string);
18     
19     return 0;
20 } 
21 
22 // 函数定义
23 // 函数功能描述
24 // 对字符数组s中存放的字符串,删除中间出现的* 
25 void delMiddleStar(char s[]) {
26     int i=0;              
27     char *tail, *head, *p;
28     
29     // 找到末尾第一个非*字符的位置 
30     tail = s;
31     while(*tail)
32         tail++;
33     
34     tail--;
35     
36     while(*tail == '*')
37         tail--;
38     
39     // 找到开头第一个非*字符的位置 
40     head = s;
41     while(*head == '*')
42         head++;
43     
44     
45     // 把中间出现的*去掉  
46     p = s;
47     while(p<=head) {  // 思考这里条件表达式为什么这样写,这个循环的功能? 
48         s[i] = *p;
49         p++;
50         i++;
51     }
52     
53     while(p<tail) {
54         if(*p != '*') {
55             s[i] = *p;
56             i++;
57         }
58         
59         p++;
60     }
61     
62     while(*p) {
63         s[i] = *p;
64         i++;
65         p++;
66     }
67     
68     s[i] = '\0'; // 思考这里为什么要这样做 
69 }

第48行可以删去,因为前导*未改变

 

二、实验总结与体会

1、二分查找算法

数组名作为参数:    形参是数组,       实参是数组名,直接访问各元素x[i];

指针变量作为参数:形参是指针变量,实参是数组名,间接访问*(x+i)等价于x[i]。(第20行第一次我写成了binarySearch(*a,N,key),而实参应为数组名)

 2、选择法排序 使用选择法对字符串排序时注意事项 实验内容

与ex2_1.cpp不同的是,2_2是字符串的比较和赋值,不能直接使用关系运算符和赋值运算符,要借助字符串处理函数

3、使用指针变量对字符串进行处理 注意事项总结

3_2、3与3_1不同的是,并没有把最后一个'\0'赋值,需要再添单独加一个

 

 

https://www.cnblogs.com/astraeus/p/10906460.html

https://www.cnblogs.com/zys-0119/p/10898984.html

https://www.cnblogs.com/ssyxs/p/10912939.html

posted @ 2019-05-21 16:56  涼叡  阅读(242)  评论(1编辑  收藏  举报