C语言小练习(九)

系列文章目录(从第七期开始难度递增,适合C语言期末复习)

C语言小练习(一)
C语言小练习(二)
C语言小练习(三)
C语言小练习(四)
C语言小练习(五)
C语言小练习(六)
C语言小练习(七)
C语言小练习(八)
C语言小练习(九)



前言

本文为《C语言小练习》的第九篇文章,今天同样练习三个项目,准备好了吗?


一、矩阵

问题描述 :
请写一个程序,对于一个m行m列(2<m<20)的方阵,求其每一行、每一列及主、辅对角线元素之和,然后按照从大到小的顺序依次输出这些值。
注:主对角线是方阵从左上角到右下角的一条斜线,辅对角线是方阵从右上角到左下角的一条斜线。

输入说明 :
输入数据的第一行为一个正整数m;
接下来为m行、每行m个整数表示方阵的元素。

输出说明 :
从大到小排列的一行整数,每个整数后跟一个空格,最后换行。

输入样例 :
4
15 8 -2 6
31 24 18 71
-3 -9 27 13
17 21 38 69

输出样例 :
159 145 144 135 81 60 44 32 28 27

#include<stdio.h>
int main()
{
	int m,i,j,temp;
	int sum1[100]={0},sum2[100]={0};
	int sum3,sum4;
	int a[20][20]={0};
	int b[100]={0}; 
	scanf("%d",&m);
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			sum1[i]+=a[i][j];	
		}
	}//求每行之和 
	
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			sum2[i]+=a[j][i];	
		}
	}//求每列之和 
	
	for(i=0;i<m;i++)
	{
		sum3+=a[i][i];	
	}//求主对角线之和 
	
	for(i=0,j=m-1;i<m;i++,j--)
	{
		sum4+=a[i][j];
	}//求辅对角线之和 
	
	for(i=0;i<m;i++)
	{
		b[i]=sum1[i];
	}//将每行之和填入比较数组中 
	
	for(j=0;j<m;j++)
	{
		b[i]=sum2[j];
		i++;
	}//将每列之和填入比较数组中
	
	b[2*m]=sum3;
	b[2*m+1]=sum4;//将主辅对角线之和填入比较数列之中 
	
	for(i=0;i<2*m+1;i++)
	{
		for(j=0;j<2*m+1-i;j++)
		{
			if(b[j]<b[j+1])
			{
				temp=b[j];
				b[j]=b[j+1];
				b[j+1]=temp;	
			}	
		}
	}//冒泡排序交换顺序 
	
	for(i=0;i<2*m+2;i++)
	{
		printf("%d ",b[i]);
	}//循环输出排序后的结果 
	
	return 0;
 }     

算法总结:
(1)题目要点分析:
<1>输入m*m的方阵:使用二维数组来存储数据
拓展:输入方阵并输出

	int m,a[100][100]={0};
	scanf("%d",&m);
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			printf("%3d",a[i][j]);
		}
		printf("\n");
	}

<2>行,列和对角线的求和:
a.每行数字的求和:

for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			sum1[i]+=a[i][j];	
		}
	} 

b.每列数字的求和:

for(i=0;i<m;i++)
	{
		for(j=0;j<m;j++)
		{
			sum2[i]+=a[j][i];	
		}
	}

c.主对角线(左上到右下)数字求和:

for(i=0;i<m;i++)
	{
		sum3+=a[i][i];	
	}

d.辅对角线(右上到左下)数字求和:

for(i=0,j=m-1;i<m;i++,j--)
	{
		sum4+=a[i][j];
	}

分析: 这四个求和其实都是利用二维数组的坐标思想来完成的,从左到右为1 - m,从上到下为1 - m
求每行数字之和就是行不变,每列相加;求每列数字之和就是列不变,每行相加;(在实际操作中只需把二维数组中的 i 和 j 互换就可以达到效果)
求两个对角线之和也是相同道理,主对角线就是(0,0) , (1,1) , (2,2)等等,一个for循环可以解决;辅对角线就是(0,m-1) , (1,m-2) , (2,m-3)等等,因此需要 i 和 j 两个变量来定位,一个for循环就可以解决,而判断条件只需要限制 i<m 就行

<3>将四组数据填入同一个数组中:

	for(i=0;i<m;i++)
	{
		b[i]=sum1[i];
	}
	for(j=0;j<m;j++)
	{
		b[i]=sum2[j];
		i++;
	}
	b[2*m]=sum3;
	b[2*m+1]=sum4;

分析: 这个难度不大,只需要分析好数组中的总数据量即可

<4>冒泡排序:

	for(i=0;i<2*m+1;i++)
	{
		for(j=0;j<2*m+1-i;j++)
		{
			if(b[j]<b[j+1])
			{
				temp=b[j];
				b[j]=b[j+1];
				b[j+1]=temp;	
			}	
		}
	}

分析: 这个排序和其他冒泡排序一样,唯一的差别就在于其中的总数据量不是 m 而是2*m+2个

二、数字排序(二)

问题描述:
给定N个不同的整数,要求对这N个整数按如下规则排序并输出。
规则一:所有的偶数排在奇数前面。
规则二:在规则一的前提下按照从大到小的顺序排序。

输入说明 :
数据由两行构成,第一行为整数n(n<=100),表示待排序整数的数量。第二行是n个整数,每个整数的取值区间都为[-32768~32767],整数之间以空格间隔。

输出说明 :
在一行输出排好序的整数,整数之间以空格间隔。

输入样例 :
5
1 2 3 4 5

输出样例 :
4 2 5 3 1

#include<stdio.h>
int main()
{
	int n,i,j,temp;
	int a[100]={0};
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(i=0;i<n-1;i++)
	{
		for(j=0;j<n-1-i;j++)
		{
			if((a[j]%2!=0&&a[j+1]%2==0)||((a[j]+a[j+1])%2==0&&a[j]<a[j+1]))
			{
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		printf("%d ",a[i]);
	}
	
	return 0;
 }     

算法总结:
升级版冒泡排序(增加奇偶排序功能):

for(i=0;i<n-1;i++)
	{
		for(j=0;j<n-1-i;j++)
		{
			if((a[j]%2!=0&&a[j+1]%2==0)||((a[j]+a[j+1])%2==0&&a[j]<a[j+1]))
			{
				temp=a[j];
				a[j]=a[j+1];
				a[j+1]=temp;
			}
		}
	}

基本框架是不变的,唯一变化的是if语句中判断条件的改变,因为要增加奇偶排序的功能。
分析:一共有两个要求
要求一: 所有的偶数排在奇数前面。

a[j]%2!=0&&a[j+1]%2==0

如果前面是奇数后面是偶数那就交换位置
要求二: 在规则一的前提下按照从大到小的顺序排序。(奇偶优先级更高)

a[j]+a[j+1])%2==0&&a[j]<a[j+1]

如果相邻的两个数都是奇数或者偶数并且前者小于后者就交换位置,这样就在奇偶排好顺序的前提下把大小顺序排好了。
补充说明:两个条件之间用或(||)连接
就是满足其中任何一条件就交换位置也就是进行排序。


三、字符统计

问题描述 :
给出一个字符C和一行文字S,统计在这行文字S中字符C出现的次数。
程序还需要支持大小写敏感选项:
当选项打开时,表示同一个字母的大写和小写看作不同的字符;
当选项关闭时,表示同一个字母的大写和小写看作相同的字符。

输入说明 :
输入数据由两行构成。
第一行包含一个字符C和一个数字n。字符C为大写或小写英文字母。数字n表示大小写敏感选项,当数字n为0时表示大小写不敏感,当数字n为1时表示大小写敏感。字符C和数字n之间用空格分隔。
第二行为一个字符串S,字符串由大小写英文字母组成,不含空格和其他字符。字符串S长度不超过100。

输出说明 :
输出字符C在字符串S中出现的次数。

输入样例:
样例1输入
L 1
HELLOWorld
样例2输入
L 0
HELLOWorld

输出样例:
样例1输出
2
样例2输出
3

#include<stdio.h>
int main()
{
	char a,c[100];
	int b,d,n=0,i;
	scanf("%c %d\n",&a,&b);
    gets(c);
	if(b==1)
	{
		for(d=0;c[d]!='\0';d++)
		{
			if(a==c[d])
			n=n+1;
		}
		printf("%d",n);
	}
	if(b==0)
	{ 
		if(a>=97)
		{
			a=a-32;
		}
		for(d=0;c[d]!='\0';d++)
		{
			if(c[d]>=97&&c[d]<=122)
			c[d]=c[d]-32;
		}
		for(d=0;c[d]!='\0';d++)
		{
			if(a==c[d])
			n=n+1;
		}
	  	printf("%d",n);
	}
	return 0;
}

算法总结:
(1)大小写敏感选项:
这个看似高级,其实用一个 if-else 语句即可完成此功能。而在其中的要点是,大小写敏感代表着可以识别出大小写,即大写和小写是不同的;相反,大小写不敏感代表着识别不出大小写,即大写和小写是相同的。因此,可以利用大小写的ASCII码相差32来解决,通过判断来加减32进行大小写的转换
(2)gets( )函数的使用:
可以直接输入字符串,空格等等,更加简便,快捷


这就是今天的全部内容了,谢谢大家的观看,不要忘了给一个免费的赞哦!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

✿小瑞同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值