谭浩强c语言课后习题笔记[第6章]

第六章 数组

6.1 筛选法求100以内的素数

#include<stdio.h>

int main()
{
	//所谓筛选法就是在一张纸上写上1~100,在把非素数挖掉,剩下的就是素数 
	int i,j,a[100],count=0;
	
	for(i=0;i<100;i++) //有序赋值 
		a[i]=i+1; 
	
	//判断素数
	for(i=0;i<100;i++) //外层控制要判断的数 
	{
		for(j=2;j<a[i];j++)
			if(a[i]%j==0)
			{
				a[i]=1; //1是非素数,由于1不再循环内,不如把1作为判断为非素数的标志,精简代码 
				break; 
			} 
	}
	
	for(i=0;i<100;i++) //每5个一行,打印 
	{
		if(a[i]!=1)
		{
			printf("%5d",a[i]);
			count++;
			if(count%5==0)
				printf("\n");	
		} 	
	}
	 
		
	return 0;
}
/*
输出结果
    2    3    5    7   11
   13   17   19   23   29
   31   37   41   43   47
   53   59   61   67   71
   73   79   83   89   97
*/

6.2 用选择法对10个整数排序

#include<stdio.h>

int main()
{
	int i,j,a[10],min,temp;
	
	for(i=0;i<10;i++) //有序赋值 
		scanf("%d",&a[i]); 
		
	printf("sort before:\n");	//排序前
	for(i=0;i<10;i++) //每5个一行,打印 
		printf("%5d",a[i]);	
	//选择排序(第一个和后续所有比较)
	//冒泡排序(第一个和第二个比较,第二个和第三个比较,两两比较) 
	//从小到大排 
	for(i=0;i<10;i++) //外层控制比较数 
	{
		min=i; 
		for(j=i+1;j<10;j++) //内层控制后续数 
			if(a[min]<a[j]==0) //从大到小则改为大于。 
			{
				temp=a[min]; //交换
				a[min]=a[j];
				a[j]=temp;
			} 
	}
	printf("\nsort after:\n");	//排序后
	for(i=0;i<10;i++) //每5个一行,打印 
		printf("%5d",a[i]);	 	
	 
		
	return 0;
}
/*输出结果
9 7 2 4 6 3 1 5 8 0
sort before:
    9    7    2    4    6    3    1    5    8    0
sort after:
    0    1    2    3    4    5    6    7    8    9
*/

6.3 求3阶矩阵的对角线元素之和

#include<stdio.h>

int mainsum(int a[][3]);
 
int main()
{
	int i,j,a[3][3],sum;
	
	//赋值 
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			scanf("%d",&a[i][j]);
	
	//求主对角线之和
	//main3sum(a)	
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			if(i==j)
				sum+=a[i][j];	

	printf("主对角线之和 %d",sum);
	
	return 0;
}

int main3sum(int a[][3]) //抽象成函数 
{
	int i,j,sum=0;
	
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			if(i==j)
				sum+=a[i][j];
	return sum; 
}

6.4 在有序数组(升序)中插入一个数

#include<stdio.h>
#define N 1000
void upsort(int a[],int length); 
void insert(int a[],int *length);
int main()
{
	int i,j,a[N],length;
	
	scanf("%d",&length);
	for(i=0;i<length;i++) //有序赋值 
		scanf("%d",&a[i]); 
		
	printf("sort before:\n");	//排序前 
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	
	
	upsort(a,length); //排序
	 
	printf("\nsort after:\n");	//排序后
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	 	
	
	//插入函数
	//先考虑插入一个数后是否越界
	printf("\ninsert value = ");
	int num;
	scanf("%d",&num); 
	
	if(length+1>N) //判断越界 
		printf("sorry!can not insert anyone");
	else
	{
		if(num>a[length-1]||length==0) //判断是否大于最后一个数 
			a[length]=num;
		else
		{
			for(i=0;i<length;i++) //判断a[0]-a[n-1]的数 
			{
				if(num<=a[i]) //标记第一次出现比num大的下标 
				{
					for(j=length;j>=i;j--) //后移数组 
						a[j+1]=a[j];
					a[i]=num; //把标记为赋值num的值			
				} 
				break;	//结束循环	
			}		
		}
		length++; //只要可插入,别忘了数组长度+1 ! 
	}
	
	
	printf("\ninsert after:\n");	//排序后
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	  
	 
		
	return 0;
}
 
void upsort(int a[],int length)
{
	int i,j,min,temp;
	//选择排序(第一个和后续所有比较)
	//冒泡排序(第一个和第二个比较,第二个和第三个比较,两两比较) 
	//从小到大排 
	for(i=0;i<length;i++) //外层控制比较数 
	{
		min=i; 
		for(j=i+1;j<length;j++) //内层控制后续数 
			if(a[min]<a[j]==0) //从大到小则改为大于。 
			{
				temp=a[min]; //交换
				a[min]=a[j];
				a[j]=temp;
			} 
	}		
} 

void insert(int a[],int *length) //抽象为函数,由于长度会改变,记得传入地址 
{
	int i,j,num;
	scanf("%d",&num); 
	
	if(*length+1>N) //判断越界 
		printf("sorry!can not insert anyone");
	else
	{
		if(num>a[*length-1]||*length==0) //判断是否大于最后一个数 
			a[*length]=num;
		else
		{
			for(i=0;i<*length;i++) //判断a[0]-a[n-1]的数 
			{
				if(num<=a[i]) //标记第一次出现比num大的下标 
				{
					for(j=*length;j>=i;j--) //后移数组 
						a[j+1]=a[j];
					a[i]=num; //把标记为赋值num的值			
				} 
				break;	//结束循环	
			}		
		}
		*length++; //只要可插入,别忘了数组长度+1 ! 
	}	
}

6.5 数组逆序排列其数值

#include<stdio.h>
#define N 1000

void inverse(int a[],int length); 
 
int main()
{
	int i,j,a[N],length;
	
	scanf("%d",&length);
	for(i=0;i<length;i++) //有序赋值 
		scanf("%d",&a[i]); 
		
	printf("inverse before:\n");	//排序前 
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	
	
	int temp;
	for(i=0;i<length/2;i++)
	{
		temp=a[i];
		a[i]=a[length-1-i];
		a[length-1-i]=temp;
	}
	 
	printf("\ninverse after:\n");	//排序后
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	 	
	 
		
	return 0;
}

void inverse(int a[],int length) //抽象成函数 
{
	int i,temp;
	for(i=0;i<length/2;i++)
	{
		temp=a[i];
		a[i]=a[length-1-i];
		a[length-1-i]=temp;
	}	
}

6.6 杨辉三角

#include<stdio.h>
#define N 100 
int main()
{
	int i,j,a[N][N],level;
	
	scanf("%d",&level);
	
	for(i=0;i<level;i++)
	{
		for(j=0;j<=i;j++)
		{
			if(j==0||j==i)
				a[i][j]=1;
			else
				a[i][j]=a[i-1][j-1]+a[i-1][j];
		}	
	} 
	
	for(i=0;i<level;i++)
	{
		for(j=0;j<i+1;j++)
			printf("%-5d ",a[i][j]);
		printf("\n");	
	}
	
	return 0;
}
/*
12
1
1     1
1     2     1
1     3     3     1
1     4     6     4     1
1     5     10    10    5     1
1     6     15    20    15    6     1
1     7     21    35    35    21    7     1
1     8     28    56    70    56    28    8     1
1     9     36    84    126   126   84    36    9     1
1     10    45    120   210   252   210   120   45    10    1
1     11    55    165   330   462   462   330   165   55    11    1
*/


6.7 魔方阵

图解:

在这里插入图片描述

可以看到三种不同颜色的线,代表三种不同的状态

  1. 直接由行-1,列+1 找到空格子,直接赋值。

  2. 在行-1,列+1时,行列已经时边界,则到边界的一段要到另一端,在在空格子里赋值。

  3. 在上述两种行为后发现格子中已经存在数,则在原数的下方赋值。

    (要是原始的下方也有值咋办,应该不会出现这个情况)

#include<stdio.h>
#define N 1000 
int main()
{
	int i,j,a[N][N]={0},n,k;
	scanf("%d",&n);
	
	a[0][n/2]=1; //初始赋值 
	int temp_i,temp_j;
	for(i=0,j=n/2,k=2;k<=n*n;k++) //循环结束的条件时把1-n^2全都赋值完 
	{
		temp_i=i; //保存前一个数的坐标  
		temp_j=j; //保存前一个数的坐标 
		i=i-1;
		j=j+1;
		if(i<0&&j>n-1) //如果上一个数是第一行第n列时 
		{
			i=temp_i+1;
			j=temp_j;	
		}
		else
		{
			if(i<0) 
				i=n-1;
			if(j>n-1)
				j=0;		
		}	
		if(a[i][j]) //如果格子存在数
		{
			i=temp_i+1;
			j=temp_j;
			if(i>n-1)
				i=0;
			a[i][j]=k; 
		} 		
		else //若是空格子直接赋值
			a[i][j]=k;
	}
		
	//打印
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
			printf("%4d",a[i][j]);
		printf("\n");	
	}

		
	return 0;
}
/*
输出结果
----------------------------
3
  8  1  6
  3  5  7
  4  9  2
----------------------------
5
 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
----------------------------
*/




6.8 鞍点

#include<stdio.h>
#define N 100 
int main()
{
	int i,j,a[N][N],n,m;
	
	//设置阶数 
	scanf("%d %d",&n,&m);
	//赋值 
	for(i=0;i<n;i++)
		for(j=0;j<m;j++)
			scanf("%d",&a[i][j]);
	
	printf("\n");
	
	int max,min,x_index,y_index;
	x_index=y_index=-1;
	for(i=0;i<n;i++)
	{
		max=0; 
		for(j=0;j<m;j++)
		{
			if(a[i][max]<=a[i][j]) //找到这一行的最大值,记录下标
			//这里用<=的原因,假定鞍点至多只有一个,一行可能有多个相同的最大值,去最后一个 
				max=j;			
		}
		
		//已找到一行的max(i,j)注意i是固定还在外层循环里,故来判定列的最小值的行下标是否为i 
		min=0; 
		for(j=0;j<n;j++) //行遍历注意j<n,不是j<m了 
		{
			if(a[min][max]>=a[j][max]) //找到这一列的最小值 
				min=j;			
		}
		if(min==i) //若最小值下标与外层行下标一致则是。驻点只有一个 
		{
			x_index=min; 
			y_index=max;
			break;	
		}
	}
	if(i>=n)
		printf(" not exist !");
	else
		printf("a[%d][%d] = %d",x_index,y_index,a[x_index][y_index]);

	
	return 0;
}
/*
4 5
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20

a[0][4] = 5
*/
-----------------------
/*
2 2
1 7
4 1

 not exist !
*/

6.9 降序数组的折半查找

#include<stdio.h>
#define N 1000

void downsort(int a[],int length);
int bisearch(int a[],int length,int search);
 
int main()
{
	int i,j,a[N],length;
	
	scanf("%d",&length);
	for(i=0;i<length;i++) //有序赋值 
		scanf("%d",&a[i]); 
		
	printf("inverse before:\n");	//排序前 
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	
	
	downsort(a,length); //排序 从大到小 
	 
	printf("\ninverse after:\n");	//排序后
	for(i=0;i<length;i++) //每5个一行,打印 
		printf("%5d",a[i]);	 	
	 
	//折半查找 
	int search,index=-1,front,end,middle;
	printf("\nsearch = :");
	scanf("%d",&search);	
	//index=bisearch(a,length,search);
	front=0;
	end=length-1;
	middle=0;
	while(front<=end)
	{
		middle=(front+end)/2;
		if(a[middle]>search) //左边 
			front=middle+1;		
		else if(a[middle]<search)  //右边 
			end=middle-1; 
		else
		{
			index=middle;
			break;	
		}	
	}	
	
	if(index>=0)
		printf("%d 是数组第 %d 个元素",search,index+1);
	else
		printf("数组内无此数");
	
	return 0;
}

int bisearch(int a[],int length,int search) //抽象成函数 找不到返回-1,找得到返回下标 
{
	int i,front,end,middle,index;
	front=0;
	end=length-1;
	middle=0;
	while(front<=end)
	{
		middle=(front+end)/2;
		if(a[middle]>search) //左边 
			front=middle+1;		
		else if(a[middle]<search)  //右边 
			end=middle-1; 
		else
			return index;	
	}
	return -1; //找不到返回 -1 不存在下标负数
}
 
void downsort(int a[],int length)
{
	int i,j,min,temp;
	//选择排序(第一个和后续所有比较)
	//冒泡排序(第一个和第二个比较,第二个和第三个比较,两两比较) 
	//从小到大排 
	for(i=0;i<length;i++) //外层控制比较数 
	{
		min=i; 
		for(j=i+1;j<length;j++) //内层控制后续数 
			if(a[min]>a[j]==0) //从大到小则改为大于。 
			{
				temp=a[min]; //交换
				a[min]=a[j];
				a[j]=temp;
			} 
	}		
}

6.10 二维数组统计字母数字空格等个数

#include<stdio.h>
#define N 100

int statistics(char c);

int main()
{
	
	int i,j,box[5]={0};
	char c[3][81];
	//给每一行赋值 
	for(i=0;i<3;i++)
		gets(c[i]);
	
	//统计字符 
	for(i=0;i<3;i++)
	{	
		for(j=0;j<strlen(c[i]);j++)
			box[statistics(c[i][j])]++;
	} 
	
	//打印统计结果
	printf("大写英文\t%d",box[0]); 
	printf("小写英文\t%d",box[1]);
	printf("数字\t%d",box[2]);
	printf("空格\t%d",box[3]);
	printf("其他字符\t%d",box[4]);
	
	return 0; 
} 

int statistics(char c) //抽象为函数形式
{
	if(c>='A'&&c<='Z')
		return 0;
	else if(c>='a'&&c<='z')
		return 1;
	else if(c>='0'&&c<='9')
		return 2;
	else if(c==' ')
		return 3;
	else
		return 4;		
}
/*输出结果
I am a student.
123456
ASDFG
大写英文        6
小写英文        10
数字            6
空格            3
其他字符        1
*/

6.11 打印平行四边形

#include<stdio.h>
#define N 100 
int main()
{
	int i,j,a[N][N],n;
	
	//设置阶数 
	scanf("%d",&n);
	//赋值 
	for(i=0;i<n;i++)
	{
		for(j=0;j<i;j++) //打印空格 
			printf(" ");
		for(j=0;j<n;j++) //打印 * 
			printf("* ");
		printf("\n");
	}
	
	return 0; 
} 

6.12 密码翻译

#include<stdio.h>
#include<string.h>
int main()
{
	
	int i;
	char c[80];
	gets(c);

	
	putchar('\n');
	//编译成密文
	for(i=0;i<strlen(c);i++)
	{	 
		if(c[i]>='A'&&c[i]<='Z')
			c[i]='A'+25-(c[i]-'A');
		else if(c[i]>='a'&&c[i]<='z')
			c[i]='a'+25-(c[i]-'a');
	}
	
	puts(c); 
	
	putchar('\n');
	
	//翻译回原文 
	for(i=0;i<strlen(c);i++)
	{	 
		if(c[i]>='A'&&c[i]<='Z')
			c[i]='Z'-25+('Z'-c[i]);
		else if(c[i]>='a'&&c[i]<='z')
			c[i]='z'-25+('z'-c[i]);
	} 
	 
	puts(c); 
	
	return 0; 
} 





/*
输出结果
R droo erhrg Xsrmz mvcg dvvp.

I will visit China next week.

R droo erhrg Xsrmz mvcg dvvp.

*/
----------------------------------
/*
I will visit China next week.

R droo erhrg Xsrmz mvcg dvvp.

I will visit China next week.
*/

6.13 链接两个字符串,不使用strcat

#include<stdio.h>
#define N 100

void u_stract(char str1[],char str2[]);

int main()
{
	char a[N],b[N];
	
	//赋值	
	gets(a);
	gets(b);
		
	u_stract(a,b);
	//打印链接后的a 
	puts(a);
	
	return 0; 
} 

void u_stract(char str1[],char str2[]) //抽象为函数形式
{
	int i,j;
	while(str1[i]!='\0') i++;
	
	for(j=0;str2[j]!='\0';j++,i++)
		str1[i]=str2[j];
		
	str1[i]='\0';		
}


6.14 比较字符串,不使用strcmp

#include<stdio.h>
#define N 100

int u_strcmp(char str1[],char str2[]);

int main()
{
	char a[N],b[N],c[N],d[N];
	
	//赋值	
	gets(a);
	gets(b); //相同值
    gets(c); //a>c
	gets(d); //a<d
		
	//输出结果
	printf("相同值结果 %d\n",u_strcmp(a,b));
    printf("a>c结果 %d\n",u_strcmp(a,c));
    printf("a<d结果 %d\n",u_strcmp(a,d));
	
	return 0; 
}

int u_strcmp(char str1[],char str2[]) //抽象为函数形式
{
	int i,j;
	for(i=0;str1[i]!='\0'||str2[i]!='\0';i++)
		if(str1[i]>str2[i])
			return 1;
		else if(str1[i]<str2[i])
			return -1;
		else
			continue;
	if(str1[i]=='\0'&&str2[i]!='\0')
		return -1;
	else if(str1[i]!='\0'&&str2[i]=='\0')
		return 1;
	else if(str1[i]=='\0'&&str2[i]=='\0')
		return 0;		
}
/*
输出结果
12345
12345
123
123456789
相同值结果 0
a>c结果 1
a<d结果 -1
*/

6.15 复制字符串,不使用strcpy

#include<stdio.h>
#define N 100

void u_strcpy(char str1[],char str2[]) ;

int main()
{
	char a[N],b[N];
	
	//赋值	
	gets(a);
	gets(b); //相同值
	
	u_strcpy(a,b);	
	//输出结果
	printf("打印拷贝后的a:↓\n"); 
	puts(a);
	
	return 0; 
}

void u_strcpy(char str1[],char str2[]) //抽象为函数形式
{
	int i;
	for(i=0;str2[i]!='\0';i++)
		str1[i]=str2[i];
	
	 str1[i]='\0';
}
/*
输出结果
12345679865465465
1212
打印拷贝后的a:↓
1212
*/
发布了137 篇原创文章 · 获赞 8 · 访问量 4345

猜你喜欢

转载自blog.csdn.net/qq_35891520/article/details/104920740