最近要复习一下C和C++的基础知识,于是计划把之前学过的谭浩强的《C程序设计》和《C++程序设计》习题重新做一遍。
编译环境为:操作系统32位Win7,编译工具VC++6.0
第七章:数组
7.1)用筛选法求100之内的素数
#include<stdio.h> void main() { //创建数组并初始化 int num[101]; //-1:未判断的数字 0:是素数 1:不是素数 int counter; for(counter = 0; counter < 101; counter++) { num[counter] = -1; } num[0] = 0; num[1] = 0; num[2] = 0; int i, j, k, sign; //sign 1:不是素数 0:是素数 for(i = 3; i <= 100; i++) { //对于已经判断的数字不重复判断 if(num[i] != -1) { continue; } //判断当前数是否为素数 sign = 0; for(j = 2; j < i / 2 + 1; j++) { if(i % j == 0) { sign = 1; break; } } if(sign) { num[i] = 1; } else { num[i] = 0; } //当前判断数的倍数都不是素数 for(k = i; k < 100; k = k + i) { //已判断的数字不重复判断 if(num[k] != -1) { continue; } num[k] = 1; } } //输出标记的素数 for(i = 2; i < 100; i++) { if(num[i] == 0) { printf("%d,", i); } } printf("\b \n"); }
7.2)用选择法对10个整数进行排序
#include<stdio.h> void main() { int a[10] = { 4, 5, 2, 9, 8, 1, 3, 7, 0, 6}; //选择排序 //maxx:i之后最大值下标 int i, j, maxx, temp; for(i = 0; i < 9; i++) { maxx = i; for(j = i + 1; j < 10; j++) { if(a[j] > a[maxx]) maxx = j; } if(a[maxx] > a[i]) { temp = a[i]; a[i] = a[maxx]; a[maxx] = temp; } } //输出排序后数组 for(i = 0; i < 10; i++) { printf("%d,", a[i]); } printf("\b \n"); }
7.3)求一个3×3的整形矩阵对角线元素之和
#include<stdio.h> void main() { int a[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; printf("对角线元素之和:%d\n", a[0][0] + a[1][1] + a[2][2]); }
7.4)已有一个排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中
#include<stdio.h> void main() { //原数组 int a[10] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 }; //插入数字 int num = 4; //新数组 int b[11]; //为新数组赋值 int i, sign = 0; for(i = 0; i < 10; i++) { if(num > a[i]) { b[i] = a[i]; } else { if(!sign) { b[i] = num; sign = 1; } b[i + 1] = a[i]; } } for(i = 0; i < 11; i++) { printf("%d,", b[i]); } printf("\b \n"); }
7.5)将一个数组中的值按逆序重新存放
#include<stdio.h> void main() { int a[5] = { 8, 6, 5, 4, 1 }; //j:数组长度 int i, j, temp; j = sizeof(a)/sizeof(int); //逆序换位 for(i = 0; i < j / 2; i++) { temp = a[i]; a[i] = a[j - i - 1]; a[j - i - 1] = temp; } //输出数组内容 for(i = 0; i < j; i++) { printf("%d,", a[i]); } printf("\b \n"); }
7.6)输出杨辉三角形的前10行
#include<stdio.h> void main() { int a[10] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int i, j; for(i = 0; i < 10; i++) { //计算下一行数组 for(j = i; j > 0; j--) { a[j] = a[j] + a[j-1]; } //输出当前数组 for(j = 0; j <= i; j++) { printf(" %d ", a[j]); } printf("\n"); } }
7.7)输出指定阶幻方
幻方的生成需要分类讨论,分为:
①奇阶幻方,使用Merzirac法生成
②双偶幻方,使用Spring法生成
③单偶幻方,使用Strachey法生成
简易的使用方法见代码中的注释
#include<stdio.h> #define n 6 void main() { //初始化幻方矩阵 int a[n][n], i, j; for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { a[i][j] = 0; } } if(n % 2) //奇数阶幻方(Merzirac法) { //在第一行居中的方格内放1 //依次向右上方填入2、3、4... //如果右上方已有数字,则向下移一格继续填写 int x = 0, y = n / 2, tempx, tempy, counter; for(counter = 1; counter <= n * n; counter++) { //赋值 a[x][y] = counter; //考虑右上的数字 tempx = x - 1; if(tempx < 0) { tempx += n; } tempy = y + 1; if(tempy >= n) { tempy -= n; } //右上数字为0则走到右上 if(a[tempx][tempy] == 0) { x = tempx; y = tempy; } else //否则向下走一格 { x++; if(x >= n) { x -= n; } } } //另有Loubere法:在居中的方格向上一格内放1 //依次向右上方填入2、3、4... //如果右上方已有数字,则向上移两格继续填写 } else if(n % 4 == 0) //双偶幻方:能被4整除的偶数阶幻方(Spring法) { //在方阵内顺序填写1-n^2 //将所有非主副对角线上的数字交换到其中心对称的位置 //填写数字 int counter = 1; for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { a[i][j] = counter++; } } //交换数字 int temp; for(i = 0; i < n; i++) { for(j = 0; j < n - i - 1; j++) { if(i == j) { continue; } temp = a[i][j]; a[i][j] = a[n - i - 1][n - j - 1]; a[n - i - 1][n - j - 1] = temp; } } } else if(n % 2 == 0) //单偶幻方:不能被4整除的偶数阶幻方(Strachey法) { //http://en.wikipedia.org/wiki/Strachey_method_for_magic_squares //将矩阵分为4部分,分别按n/2阶幻方的方法填数 // A C | A填1到n*n/4 B填n*n/4+1到n*n/2 // D B | C填n*n/2+1到n*n/4*3 D填n*n/4*3+1到n*n int x = 0, y = n / 4, tempx, tempy, counter; for(counter = 1; counter <= n * n / 4; counter++) { //赋值 a[x][y] = counter; a[x + n / 2][y + n / 2] = counter + n * n / 4; a[x][y + n / 2] = counter + n * n / 2; a[x + n / 2][y] = counter + n * n / 4 * 3; //考虑右上的数字 tempx = x - 1; if(tempx < 0) { tempx += n / 2; } tempy = y + 1; if(tempy >= n / 2) { tempy -= n / 2; } //右上数字为0则走到右上 if(a[tempx][tempy] == 0) { x = tempx; y = tempy; } else //否则向下走一格 { x++; if(x >= n / 2) { x -= n / 2; } } } //将左n/4列的数字,A和D对应位置互换 int temp; for(i = 0; i < n / 2; i++) { for(j = 0; j < n / 4; j++) { temp = a[i][j]; a[i][j] = a[i + n / 2][j]; a[i + n / 2][j] = temp; } } //将右n/4-1列的数字,B和C对应位置互换 for(i = 0; i < n / 2; i++) { for(j = n - 1; j > n - n / 4; j--) { temp = a[i][j]; a[i][j] = a[i + n / 2][j]; a[i + n / 2][j] = temp; } } //交换A和D的中心 temp = a[n / 4][0]; a[n / 4][0] = a[n - n / 4 - 1][0]; a[n - n / 4 - 1][0] = temp; //交换A和D中间行最左端的值 temp = a[n / 4][n / 4]; a[n / 4][n / 4] = a[n - n / 4 - 1][n / 4]; a[n - n / 4 - 1][n / 4] = temp; } //输出幻方 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { printf("%d\t", a[i][j]); } printf("\n"); } }
7.8)找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小。一个二维数组也可能没有鞍点
#include<stdio.h> #define width 5 #define height 5 void main() { //创建二维数组 int a[height][width] = { { 5, 0, 0, 0, 0 }, { 5, 0, 0, 0, 0 }, { 3, 1, 1, 1, 1 }, { 5, 0, 0, 0, 0 }, { 5, 0, 0, 0, 0 } }; int row_max; //行最大值 int row_max_x; //行最大值横坐标 int row_max_y; //行最大值纵坐标 int column_min; //行最小值 //遍历各行 int i, j, k; for(i = 0; i < height; i++) { //寻找第i行的最大值 row_max = a[i][0]; for(j = 1; j < width; j++) { if(a[i][j] > row_max) { row_max = a[i][j]; } } //所有满足最大值的点,查看是否是该列的最小值 for(j = 0; j < width; j++) { if(a[i][j] == row_max) { column_min = a[0][j]; for(k = 0; k < height; k++) { if(a[k][j] < column_min) { column_min = a[k][j]; } } if(row_max == column_min) { printf("Find saddle point: (%d,%d)\n", i, j); } } } } }
7.9)有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不再数组中,则输出“无此数”
#include<stdio.h> #define length 15 void main() { int a[length] = { 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; int n, left, right; scanf("%d", &n); left = 0; //左边界 right = length - 1; //右边界 while(true) { //与左边界吻合的情况 if(a[left] == n) { printf("Number Found: a[%d] is %d\n", left, a[left]); break; } //与右边界吻合的情况 if(a[right] == n) { printf("Number Found: a[%d] is %d\n", right, a[right]); break; } //未找到的情况 if((left >= right - 1) || a[left] > n || a[right] < n) { printf("Number Not Found!\n"); break; } //折半缩小排查区域 if(a[(left + right) / 2] > n) { right = (left + right) / 2; } else { left = (left + right) / 2; } } }
7.10)有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数
#include<stdio.h> #define row_count 3 #define row_length 100 void main() { char words[row_count][row_length] = { { "abcdefg HIJKLMN 1234_5678" }, { "!@#$%^&*() 0987654321" }, { "kakaka_gagaga" } }; int count_of_AtoZ = 0; //大写字母数 int count_of_atoz = 0; //小写字母数 int count_of_0to9 = 0; //数字数 int count_of_spac = 0; //空格数 int count_of_othr = 0; //其他字符数 int i, j; for(i = 0; i < row_count; i++) { for(j = 0; words[i][j] != '\0'; j++) { if(words[i][j] >= 'A' && words[i][j] <= 'Z') { count_of_AtoZ++; } else if(words[i][j] >= 'a' && words[i][j] <= 'z') { count_of_atoz++; } else if(words[i][j] >= '0' && words[i][j] <= '9') { count_of_0to9++; } else if(words[i][j] == ' ') { count_of_spac++; } else { count_of_othr++; } } } printf("A-Z: %d\n", count_of_AtoZ); printf("a-z: %d\n", count_of_atoz); printf("0-9: %d\n", count_of_0to9); printf("space: %d\n", count_of_spac); printf("other: %d\n", count_of_othr); }
7.11)输出图案
#include<stdio.h> void main() { char s[14] = "* * * * *"; int i, j; for(i = 0; i < 5; i++) { for(j = 0; j < 2 * i; j++) { printf(" "); } printf("%s\n", s); } }
7.12)有一行电文,已按下面的规律译成密码
A→Z a→z
B→Y b→y
C→X c→x
。。。。。。
要求编写程序将密码译回原文
#include<stdio.h> void main() { char s[100]; gets(s); //读取一行内容 printf("Your input: %s\n", s); int i; char c; //逐个筛查读取到的内容并输出 printf("My output: "); for(i = 0; (c = s[i]) != '\0'; i++) { if(c >= 'A' && c <= 'Z') { c = 'A' + 26 - (c - 'A') - 1; } if(c >= 'a' && c <= 'z') { c = 'a' + 26 - (c - 'a') - 1; } printf("%c", c); } printf("\n"); }
7.13)将两个字符串连接起来,不使用strcat函数
#include<stdio.h> void main() { char a[100], b[100], c[200]; printf("Input string a: "); gets(a); printf("Input string b: "); gets(b); int i, j; for(i = 0; a[i] != '\0'; i++) { c[i] = a[i]; } for(j = 0; b[j] != '\0'; i++, j++) { c[i] = b[j]; } c[i] = '\0'; printf("%s\n", c); }
7.14)比较两个字符串大小,不使用strcpy函数
#include<stdio.h> void main() { char a[100], b[100]; printf("Input string a: "); gets(a); printf("Input string b: "); gets(b); int i; for(i = 0; i < 100; i++) { if(a[i] == '\0' && b[i] == '\0') { printf("0\n"); break; } else if(a[i] == b[i]) { continue; } else { printf("%d\n", a[i] - b[i]); break; } } }
7.15)将字符数组s2中的全部字符复制到字符数组s1中,不用strcpy函数
#include<stdio.h> void main() { char a[100], b[100]; printf("Input string a: "); gets(a); printf("Input string b: "); gets(b); int i; for(i = 0; b[i] != '\0'; i++) { a[i] = b[i]; } a[i] = '\0'; printf("%s\n", a); }
END