c语⾔程序设计第五版课后答案谭浩强第六章习题答案
第六章:利⽤数组处理批量数据
1. ⽤筛选法求100之内的素数
【答案解析】
素数:约数为1和该数本⾝的数字称为素数,即质数
筛选法:⼜称为筛法。先把N个⾃然数按次序排列起来。1不是质数,也不是合数,要划去。第⼆个数2是质数留下来,⽽把2后⾯所有能被2整除的数都划去。2后⾯第⼀个没划去的数是3,把3留下,再把3后⾯所有能被3整除的数都划去。3后⾯第⼀个没划去的数是5,把5留下,再把5后⾯所有能被5整除的数都划去。这样⼀直做下去,就会把不超过N 的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊⼈是把数写在涂腊的板上,每要划去⼀个数,就在上⾯记以⼩点,寻求质数的⼯作完毕后,这许多⼩点就像⼀个筛⼦,所以就把埃拉托斯特尼的⽅法叫做“埃拉托斯特尼筛”,简称“筛法”。(另⼀种解释是当时的数写在纸草上,每要划去⼀个数,就把这个数挖去,寻求质数的⼯作完毕后,这许多⼩洞就像⼀个筛⼦。)
【代码实现】
//⽤筛选法求100以内的素数
#include<stdio.h>
int main()
{
int i, j, k = 0;
// 将数组汇总每个元素设置为:1~100
int a[100];
for (i = 0; i < 100; i++)
a[i] = i+1;
// 因为1不是素数,把a[0]⽤0标记
// 最后⼀个位置数字是100,100不是素数,因此循环可以少循环⼀次
a[0] = 0;
for (i = 0; i < 99; i++)
{
// ⽤a[i]位置的数字去模i位置之后的所有数据
// 如果能够整除则⼀定不是素数,该位置数据⽤0填充
for (j = i + 1; j < 100; j++)
{
if (a[i] != 0 && a[j] != 0)
{
//把不是素数的都赋值为0
if (a[j] % a[i] == 0)
a[j] = 0;
}
}
}
printf(" 筛选法求出100以内的素数为:\n");
for (i = 0; i < 100; i++)
{
//数组中不为0的数即为素数
if (a[i] != 0)
printf("%3d", a[i]);
}
printf("\n");
return 0;
}
【运⾏结果】
2. ⽤选择法对10个整数排序
【答案解析】
选择排序原理:
总共两个循环,外循环控制选择的趟数,内循环控制具体选择的⽅式。
⽤maxPos标记区间中⾸元素位置,然后⽤后序元素依次与maxPos标记的元素进⾏⽐较,如果有元素⼤于maxPos位置的元素,⽤maxPos标记该元素的位置,直到区间的末尾。
该趟选择完成后,即到该区间中最⼤元素,如果maxPos标记的最⼤元素不在区间末尾,⽤maxPos位置元素与区间末尾的元素进⾏交换。
继续新⼀趟选择,直到区间中剩余⼀个元素
【代码实现】
#include<stdio.h>
int main()
{
int array[] = {2,8,3,9,5,7,1,4,0,6};
int size = sizeof(array) / sizeof(array[0]);
// 输出原数组
printf("排序前数组中数据为:");
for (int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
// 选择排序过程:
// 外循环控制选择的趟数,总共选择size-1趟,
// 减1是因为最后⼀趟选择区间中剩余⼀个元素,该趟选择可以忽略
for (int i = 0; i < size-1; ++i)
{
// ⽤maxPos标记[0, size-i)区间中最⼤元素
// 在该趟选择没有开始前,默认认为0号位置就是最⼤元素
int maxPos = 0;
for (int j = 1; j < size - i; ++j)
{
// 遍历区间[0, size-i)中元素,如果有元素⽐maxPos位置元素⼤,maxPos记录该元素位置c程序设计语言第几版最好
if (array[j] > array[maxPos])
maxPos = j;
}
// 如果最⼤元素不在区间末尾时,将最⼤元素与区间末尾元素交换
if (maxPos != size - i - 1)
{
int temp = array[maxPos];
array[maxPos] = array[size - i - 1];
array[size - i - 1] = temp;
}
}
// 输出原数组
printf("选择排序后数组中数据为:");
for (int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}
【结果截屏】
优化:既然⼀趟选择能到最⼤的元素,那么也可以到最⼩的元素,因此在⼀趟中可以到最⼩和最⼤两个元素,最⼩元素放在区间左侧,最⼤元素放在区间右侧,可以减少选择的趟数。
#include<stdio.h>
int main()
{
int array[] = {2,8,3,9,5,7,1,4,0,6};
int size = sizeof(array) / sizeof(array[0]);
// 输出原数组
printf("排序前数组中数据为:");
for (int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
int begin = 0, end = size - 1;
// [begin, end]区间中进⾏选择
while (begin < end)
{
int maxPos = begin; // 标记区间中最⼤元素的位置
int minPos = begin; // 标记区间中最⼩元素的位置
int index = begin + 1;
while (index <= end)
{
if (array[index] > array[maxPos])
maxPos = index;
if (array[index] < array[minPos])
minPos = index;
++index;
}
// 如果最⼤元素不在区间末尾,则交换
if (maxPos != end)
{
int temp = array[maxPos];
array[maxPos] = array[end];
array[end] = temp;
}
// 如果在交换前区间末尾刚好存储的是最⼩的元素,则最⼩的元素被交换到maxPos位置
// 此时需要更新minPos
if (minPos == end)
minPos = maxPos;
// 如果最⼩元素不在区间起始位置,则交换
if (minPos != begin)
{
int temp = array[minPos];
array[minPos] = array[begin];
array[begin] = temp;
}
// 最⼤与最⼩元素已经在区间的起始和末尾的位置,
// 因此begin往后移动,end往前移动
begin++;
end--;
}
// 输出原数组
printf("选择排序后数组中数据为:");
for (int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}
3. 求⼀个3 X 3的整形矩阵对⾓线元素之和
【答案解析】
矩阵:即⼆维数组,矩阵⾏和列相等的⼆维数组称为⽅阵。
1 2 3
4 5 6
7 8 9
左上⾓到右下⾓对⾓线上数字:⾏下标和列下标相等
右上⾓到左下⾓对⾓线上数字:列下标减1 ⾏下标加⼀
通过两个循环来取到对⾓线上的元素,并对其求和即可。
【代码实现】
#include<stdio.h>
int main()
{
int array[3][3];
int sumLT2RB = 0; // 标记左上⾓到右下⾓对⾓线元素之和
int sumRT2LB = 0; // 标记右上⾓到左下⾓对⾓线元素之和
printf("请输⼊3⾏3列的矩阵:\n");
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
scanf("%d", &array[i][j]);
}
// 左上⾓到右下⾓对⾓线
for (int i = 0; i < 3; ++i)
sumLT2RB += array[i][i];
for (int i = 0, j = 2; i < 3; ++i, j--)
sumRT2LB += array[i][j];
printf("左上⾓到右下⾓对⾓线元素之和: %d\n", sumLT2RB);
printf("右上⾓到左下⾓对⾓线元素之和: %d\n", sumRT2LB);
return 0;
}
【结果截屏】
4. 有⼀个已经排好序的数组,要求输⼊⼀个数后,按原来顺序的规律将它插⼊数组中【答案解析】
将数据插⼊到已排序的序列中,只需两步即可:
1. 待插⼊元素在数组中的插⼊位置
2. 插⼊元素
具体如下:
注意:极端情况下,end可能会被减为-1,⽐如在上述序列中插⼊0
【代码实现】
#include<stdio.h>
int main()
{
int num = 0;
int array[10] = {1,2,3,4,5,6,7,8,9};
printf("请输⼊⼀个整数:");
scanf("%d", &num);
printf("原数组序列为:\n");
for (int i = 0; i < 9; ++i)
printf("%d ", array[i]);
printf("\n");
// 数组为升序
// 在数组中待插⼊元素的位置,具体的⽅式为:
// 从后往前依次与数组中元素进⾏⽐较,如果要插⼊元素num⽐end位置数据⼩,则num⼀定插在end位置之前
// 因此将end位置数据往后搬移⼀个位置
// 如果num⼤于end位置元素或者end已经在区间最左侧,则位置到
// 最后将新元素插⼊到end+1的位置
int end = 8;
while (end >= 0 && num < array[end])
{
array[end+1] = array[end];
end--;
}
array[end + 1] = num;
printf("插⼊元素%d之后的结果为:\n", num);
for (int i = 0; i < 10; ++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}
【结果截图】
5. 将⼀个数组中的值按逆序重新存放。例如:原来顺序为8,6,5,4,1。要求改为1,4,5,6,8。【答案解析】
该题为数组的逆置,具体处理⽅式如下:
如果begin < end时,则循环进⾏⼀下操作
1. 给定两个下标begin和end,begin放在数组起始的位置,end放在数组最后⼀个元素的位置
2. 交换begin和end位置的元素
3. begin往后移动,end往前移动
【代码实现】
#include<stdio.h>
int main()
{
int array[5] = {8,6,5,4,1};
int begin = 0, end = 4;
printf("逆序之前数组为:");
for (int i = 0; i < 5; ++i)
printf("%d ", array[i]);
printf("\n");
// 逆序:begin在数组最左侧,end在数组最右侧
// 只要begin < end,将begin和end位置元素进⾏交换
/
/ 然后begin往后移动⼀步,end往前移动⼀步
while (begin < end)
{
int temp = array[begin];
array[begin] = array[end];
array[end] = temp;
begin++;
end--;
}
printf("逆置之后数组为:");
for (int i = 0; i < 5; ++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}
【结果截屏】
6. 输出⼀下的杨慧三⾓(要求输出10⾏)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
……
【答案解析】
仔细观察杨慧三⾓可以看到:
第0列和对⾓线上的数据全部为1,其余位置上的数据为上⼀⾏正对数据与上⼀⾏正对前⼀个数据之和。
⽐如:a[4][2] = a[3][2] + a[3][1]
【代码实现】
#include<stdio.h>
int main()
{
int array[10][10];
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j <= i; ++j)
{
// 对⾓线和第0列上全部为1
if (i == j || 0 == j)
array[i][j] = 1;
else
array[i][j] = array[i - 1][j] + array[i - 1][j - 1];
}
}
// 打印杨慧三⾓的前10⾏
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j <= i; ++j)
{
printf("%5d", array[i][j]);
}
printf("\n");
}
return 0;
}
【结果截屏】
7. 输出"魔⽅阵"。所谓魔⽅阵是指这样的⽅阵,它的每⼀⾏、每⼀列和对⾓线之和均相等。例如:
8 1 6
3 5 7
4 9 2
要求输出1~$n^2$的⾃然数构成的魔⽅阵。
【答案解析】
| 17 | 24 | 1 | 8 | 15 |
--------------------------
| 23 | 5 | 7 | 14 | 16 |
--------------------------
| 4 | 6 | 13 | 20 | 22 |
--------------------------
| 10 | 12 | 19 | 21 | 3 |
-
-------------------------
| 11 | 18 | 25 | 2 | 9 |
仔细观察上述矩阵,可以看到以下规律:
魔⽅阵的⽣成⽅法为:在第0⾏中间置1,对从2开始的其余$n^2-1$个数依次按下列规则存放:
1. 将1放在第1⾏的中间⼀列。
2. 从2开始直到n*n⽌,各数依次按此规律存放:每⼀个数存放的⾏⽐前⼀个数的⾏数减1,列数加1。
3. 如果上⼀⾏的⾏数为1,则下⼀个数的⾏数为n(指最下⼀⾏)。
4. 当上⼀个数的列数为n时,下⼀个数的列数应该为1。
5. 如果按上⾯规律确定的位置有数,或者上⼀个数是第1⾏第n列时,则把下⼀个数放在上⼀个数的下⾯。
【代码实现】
#include <stdio.h>
int main()
{
int a[15][15], n, i, j, k;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论