第六章:利用数组处理批量数据 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记录该元素位置 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 行下标加一
通过两个循环来取到对角线上的元素,并对其求和即可。