|
第九章 数组习题分析与解答 一、 选择题 9.1【参考答案】 D) 9.2【参考答案】 A) 9.3【参考答案】 A) 9.4【参考答案】 A) 9.5【参考答案】 C) 9.6【参考答案】 A) 9.7【参考答案】 B) 9.8【参考答案】 D) 9.9【参考答案】 C) 9.10【参考答案】 C) 9.11【参考答案】 C) 9.12【参考答案】 D) 9.13【参考答案】 D) 9.14【参考答案】 A) 9.15【参考答案】 A) 9.16【参考答案】 A) 9.17【参考答案】 C) 9.18【参考答案】 C)
二、 填空题 9.19【参考答案】 [1]9 [2]0 9.20【参考答案】 6 9.21【参考答案】 12 9.22【参考答案】 3 9.23【参考答案】 2721 9.24【参考答案】 -850,2,0 9.25【参考答案】 [1]k=p [2]k 9.26【参考答案】 [1] (c=getchar()) [2] c-′A′ 三、 上机题 9.27【分析与解答】 (1) 对于字符的输入可参考教材例6.3和习题9.26中的while循环,只是要注意,循环的终止条件是:等于′\[KG-*3]n′。 (2) 在while循环体中,用if条件来判断是否为数字字符,若是,就使对应的元素增1;if中的条件表达式可用C的库函数:isdigit(ch),这时要在程序前加:#include <ctype.h>行;也可用:ch>[KG-*3]=′0′&&ch<[KG-*3]=′9′。 (3) 若用num数组元素来进行统计,当ch中是数字“0”时,使num[0]增1、当ch中是数字 “1”时,使num[1]增1……num的下标表达式可用:ch-′0′。 (4) 注意,在定义数组时,数组的大小应符合使用的要求。在利用数组元素作为计数器时,不要忘记首先应该给数组元素赋0值。 (5) 总结:通过本题的编程,要求掌握利用数组元素作为计数器的基本算法。
9.28【分析与解答】 本题的编程请参考例9.8。 (1) 若有以下10个整数: 0 1 2 3 4 5 6 7 8 9 要求从第5个元素依次向前移,则移动之后的数列应该是: 0 1 2 4 5 6 7 8 9 第5个元素不是指下标为5的元素,而是指排列的顺序,对此数列而言是指数值为4的那个。 (2) 完成移动后,数列中的数据个数减1。 (3) 若进行指定操作的函数名为moves,则函数的首部可如下: void moves(int *a,int n,int *m) 这里a用以指向一维数组的首地址,n接受开始移动的元素的位置,m指向主函数中存放元素个数的变量,因为没有函数值返回,因此函数的类型定义为void。 (4) 可用以下for循环完成指定的移动: for(i=n-1;i<*m;i[KG-*3]+[KG-*3]+) a[i-1]=a[i]; 注意,应当先把第n个元素(下标为n-1)移到第n-1个元素(下标为n-2)的位置上,依次葱馨到后向前移动。 (5) 完成移动之后,应使m所指变量中的值减1,表示数列中的数据少了一个;这可由于句: *m=*m-1;来完成。 (6) 可设计一个输出函数,在移动前、后调用此函数输出数组中的数据,以便验证操作是否正确。若输出函数名为:outarr,则函数首部可写成: void outarr( int a[], int num) 形参a指向待输出的数组,num接受数组中元素的个数。输出操作可由一个for循环来完成: for(i=0; i<num; i[KG-*3]+[KG-*3]+) printf(″%d″,a[i]); printf(″\[KG-*3]n\[KG-*3]n″); 退出循环后的printf语句使上面的输出行结束。 (7) 在主函数中定义所需的数组和变量。数组中的值可以在主函数中输入,也可定义一个函数用于输入数据。n的值在主函数中输入,然后调用以上函数。需要注意的是,给n输入的值不能是1,因为第一个元素(下标为0)再向前移,下标就越界了,同时,n的值也不可大于10,因为已指定只有10个元素。 (8) 总结: ① 对于需要进行多次的操作,如本程序中输出数组元素中的值,应当编写一个独立的函数多次调用,而不应重复地编写代码。虽然该函数中只是一个for循环,似乎在主函数中书写两次也不麻烦,但养成良好的模块化程序设计的风格却是十分重要的。 ② 分析以上例子可见,所规定的操作,实际上删除了数列中的第n-1个元素,因此可见删除操作是由移动操作来完成的。
9.29【分析与解答】 (1) 程序要求定义两个数组以便存放原始数据和从中选出的所有奇数。 (2) 若把函数命名为oods,则函数首部可写成: void odds(int *a,int an,int *b,int *bn) 形参a指向存放原始数据的数组,an存放此数组中数据的个数;b指向另一个数组,此数组中将存放将选出的所有奇数,指针bn指向存放奇数个数的存储单元,因为将通过此指针,把奇数的个数传回主函数。 (3) 在odds函数中,可通过一个for循环选出所有的奇数: for(i=0;i<an;i[KG-*3]+[KG-*3]+) if(a[i]%2){ b[j]=a[i];j[KG-*3]+[KG-*3]+; } 在for循环中逐个引用原始的数组元素,若元素中的值不能被2除尽(不为0),则把它放入b所指的数组中;j用作b的下标,每放入一个奇数后,j的值加1;注意,j的初值应该置0。 (4) 当完成以上操作退出循环时,因为在循环内最后进行了一次j[KG-*3]+[KG-*3]+的操作,所以j的值就是奇数的个数,最后应当把它赋给*bn,以便通过指针bn把奇数的个数传回主函数。 (5) 程序需要两次输出数组中元素的值,一次是输出原始数组中的值,一次是输出奇数数组中的值。因此可以使用题9.28中的outarr函数,进行两次调用。 (6) 在主函数中应当定义所需的数组和变量,可以在主函数中给数组元素输入数据。 (7) 总结:本题的算法很简单,要求读者能够编写独立的模块,并在函数之间熟练地传送数据。
9.30【分析与解答】 (1) 例9.9完成了对整数由小到大的排序,而本题是对字符数组中的元素进行由大到小的排序;两者之间并无大的区别,只是数组的类型不同,字符数组中每个元素存放一个字符,字符的大小依据每个字符的ASCII码值的大小。 (2) 若函数形参a指向主函数中待排序的数组,由大到小的排序只需改变内循环中if语句的条件表达式即可: if(a[p]<a[i]) p=i; 此处i是内循环的控制变量。 (3) 排序前后可以调用一个输出函数,输出原始数据和排序后的数据,可参考习题9.28的outarr函数,但注意,这里是对字符数组进行输出。 (4) 总结:读者可以参考例9.9,程序基本相同,但在掌握排序算法的基础上,必须独立完成此程序,不要照抄。
9.31【分析与解答】 (1) 我们把插入操作命名为函数insert,若待插入的数据放在形参x中,指针a指向主函数中的数组,指针n指向存放数组中元素的个数变量,因为插入后,数组中的数据会增加。函数的首部如下: void insert(int *a,int x,int *n) (2) 若数组中原有的有序数列按由小到大排列如下,共12个数: 11 14 17 18 19 20 22 24 26 29 30 33 若x中的数为21,我们立刻知道应插在何处,插入后数列如下,则插入后变成有13个数: 11 14 17 18 19 20 21 22 24 26 29 30 33 因此,对于程序来说应当做以下4件事: ① 能根据待插的数据,按“仍然有序的要求”判断出插入的位置。 ② 把位置腾出来,以便放入插入的数据,但原有的数据不能缺少。 ③ 把x中的数放入腾出来的位置中。 ④ 使原有数组中的数据个数增1。 (3) 现在来做第一个步骤:确定插入的位置。用变量j来放置该位置在数组中的下标,以下while循环将完成此任务: j=0; while(j<*n && a[j]<x) j[KG-*3]+[KG-*3]+; 因为已经假定数列按由小到大排列,当x的值大于当前的元素a[j]时,应当接着与下一个元素比较(执行j[KG-*3]+[KG-*3]+),直到x的值小于或等于当前的元素a[j]时,x就应当插入到下标为j的元素中,在此之前的所有值都比x小。当x的值小于a[0]时,不进入while循环,j的值为0。x就应当插入到下标为0的元素中。当x的值大于数组中所有的元素时,由条件:j<*n 可知,这时j的值将等于*n并退出循环。x就应当插入到下标为j的元素中。 (4) 第二个步骤是要把下标为j的元素后原有的数据移走,但不能改变原来的顺序。那么只能把下标为j至下标为*n-1中的数据依次向后平移;这种平移,应当先把最后的、下标为*n-1的元素中的数据移到下标为*n的元素中,其他依次后移一个单元,直到把a[j]中的值放入a[j+1]中。这可由以下for循环来完成: for(i=*n-1;i>[KG-*3]=j;i--) a[i+1]=a[i]; (5) 第三个步骤是把x放入a[j]中:a[j]=x; (6) 第四步是使存放数据个数的变量中的数增1:*n=*n+1;插入过程到此结束。 (7) 可利用习题9.28中的outarr函数,在插入前和插入后两次输出数组元素,以判断操作是否正确。 (8) 请编写主函数,定义所需的数组和变量,给数组输入一组有序数,正确调用函数。 (9) 请按题目要求至少对程序运行3次,判断程序是否在各种情况下都能得到正确的结果。 (10) 总结:插入算法是程序设计中的一种最基本的算法,希望读者在理解的基础上编写程序。
9.32【分析与解答】 (1) 若函数名为change,函数首部如下: void change(int x,int *a, int *n) 形参x中存放一个待转换的十进制数,指针a指向一个一维数组,数组中每一个元素中存放一个0或1
|