最近要复习一下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