【C语言答案】第九次练习(第三次月考)---递归

以下题目是由老师布置的《 谭浩强C程序设计(第四版)》的oj练习题,共五道
使用软件是Devc++5.11。

希望大家抄了作业顺手点个赞,谢谢,爱宁。要好好学习呀!C语言挺简单的。

C语言_ex19_20

题目描述
现有序列: s = 1* 2^2 + 2*3^2 + …+n * (n+1)^2
​​
请写出递归求s的程序。

输入只有一行,为一个正整数,代表n(0<n)
输出也只有一行,为此情况下s的值。(测试用例保证所有整数可以用 int存储)。

注意:此题要求递归求解,其他方式不得分
输入样例
1
输出样例
4
题目分析:
什么是递归?递归就是自己调用自己。(老套娃了)递归复习
或者看看这里的解释。

https://www.zhihu.com/question/20507130

对于本题来说,用递归可以从后往前算,是最后一项+前一项,前一项又等于自己+前前项······

#include <stdio.h>
int main()
{
	int n=0;
	int plus();		//函数在main里用的时候要声明。用Dev的话不声明也能运行。 
	scanf("%d",&n);
	printf("%d",plus(n));
}
int plus(int n)
{
	if(n==1) 
	return 4;
	else
	return n*(n+1)*(n+1)+plus(n-1);
}

实验7_12_设计函数

题目描述
void InsertSort(int a[],int n); 使用插入排序算法,将数组a的前n个元素按照升序的方式排序。
插入排序算法描述如下:
初始序列:49 38 65 97 76 13 27 49
将元素(38) 插入合适位置: [38 49] 65 97 76 13 27 49
将元素(65) 插入合适位置: [38 49 65] 97 76 13 27 49
将元素(97) 插入合适位置: [38 49 65 97] 76 13 27 49
将元素(76) 插入合适位置: [38 49 65 76 97] 13 27 49
将元素(13) 插入合适位置: [13 38 49 65 76 97] 27 49
将元素(27) 插入合适位置: [13 27 38 49 65 76 97] 49
将元素(49) 插入合适位置: [13 27 38 49 49 65 76 97]
输入与输出要求:首先输入一个整数n(1<=n<=1000),代表待排序元素的个数。然后输入n个整数,每个整数不会超过int型的存储范围。输出为n-1行,依次为1到n-1趟排序后数组内各个元素。每行输出的顺序为a[0]至a[n-1],数与数之间用空格分开,注意第n个数后没有空格而是换行符。
输入样例
8
49 38 65 97 76 13 27 49
输出样例
38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 76 97 13 27 49
13 38 49 65 76 97 27 49
13 27 38 49 65 76 97 49
13 27 38 49 49 65 76 97
题目分析
默认看我帖子的人应该没学数据结构。所以这道题挺难的,要在很短时间里理解插入排序,然后把它们全打印出来。
插入排序就是把第i个数字放在前面已经排好的序列里面,从头到尾重复一遍,这个数组就排完了,不要害怕这么长的题目描述。
按着老师的思路来走,老师在题目中用变量名的方式给了我们很多提示,如void InsertSort(int a[],int n);是把a数组中的第n个与前面的进行比较。

#include <stdio.h>
#include <string.h>
/* 函数声明 */
void InsertSort( int a[],int n);
//把数组a的第n个数字,插入到前n-1个数的序列中。“返回值”就是排好序的数列 
void InsertSort(int*a ,int n) 
{		//一般在函数这个括号这里用*数组名,函数里面正常用数组a【i】
	int i=1,temp=0;
	for(i=0;i<n;i++)
	{
		if(a[n]<a[i])//将a[n]与前面的数作对比,0比到n-1 
		{
			temp=a[i];//temp是临时量,用于转换。 
			a[i]=a[n];
			a[n]=temp;
		}
	}
}
int main()				//主函数 
{
	int n=0,i=0,j=0;
	int a[1020]={0};
		 scanf("%d",&n);//输入 
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]);//在某个数前面加个&表示取地址,可以理解为问你家门牌号是多少。
	}//所以这个输入循环可以理解为,一排键盘输入的数字挨个住进门牌号是a【i】的房子里。
		if(n==1)			//只有一个数就直接输出,不要比来比去。 
	printf("%d",a[0]);
	else
	{	
		for(i=1;i<n;i++)	//大于一个数的情况,按照要求比两个、三个,分别输出 
		{					//总之就是要输出的行数比数组少一个 ,i对应输出的行数 
			InsertSort(a,i);//注意这里用a不要写*!!!!
			for(j=0;j<n;j++) //j是用来一行行输出的,和排序那套没关系 
			printf(" %d",a[j]);
			printf("\n");
		}
	 }
	 return 0; 
}

C. C语言_ex19_22

题目描述
输入一个字符串,请统计每个字符出现的次数。

输入:
为一个长度不超过100000且只包含小写字母的字符串。

输出:
若干行,如果某个字符的出现次数大于0,则输出该字母及其出现的次数,具体格式看输出样例。输出顺序为字典序。
输入样例
helloworld
输出样例
d:1
e:1
h:1
l:3
o:2
r:1
w:1
题目分析
提个问题,马上回答我:知不知道a的asc2码是多少?
······我永远也记不住,所以在考场上也没办法查,就用这种方式做了~
看到题目要求字典树,就是按字母顺序的意思,在考场上没时间想详细的判断规则,每分每秒都要用来写代码,所以直接全部字母都数,输出时候再判断!!我就是考试钻牛角尖,结果没能及时ac,记忆犹新······

#include <stdio.h>
#include <string.h>
/* 函数声明 */
int CountNum(char *a,char n);

int main()
{
	char a[100020];//记得数组开大一点 
	scanf("%s",a); //注意这里不用写*,直接用名字就OK
	
	int answer[10000],j=0;
	char i;
	for (i='a',j=0;i<='z';i++,j++)	//简单粗暴的循环字母们~ 
	{
		answer[j]=CountNum(a,i); //注意这里使用a的时候也不用写*或者【】!!!
		
		if(answer[j]!=0)
		printf("%c:%d\n",i,answer[j]);
	} 
	
 } 
 
 int CountNum( char *a,char j)//用来给全部字母排序的函数
 {
 	int i,ans=0;
 //	for(j='a';i<='z';i++)	我保留了一开始写的痕迹,本来想把字母循环写这里的,发现return字符串太麻烦,就放回main里了。考试时候也不要纠结,用自己会的方式。
 		for(i=0;a[i]!='\0';i++)//循环整个数组,数组结束标志是\0 
		 {
		 	if(a[i]==j)
		 	ans++;
		  }
	return ans; 
 }

D. C语言_ex19_24

题目描述
输入
第一行为一个字符c(只可能是大写字符或小写字符)
第二行为一个整数n(1<n<20),代表测试数据组数。
后边是n行,每行一个字符串(字符串中只包含大写字母或小写字母,且长度小于60),为n组测试数据。
输出:
若干行(至少一行),每行对应输入的n行字符串,如果c在该行字符串中出现过两次或两次以上(无论大写或小写只要字母一样就算出现一次),则该字符串被输出,否则该字符串不能被输出。如果输出的字符串超过一个,则每个字符串占一行且后输入的先输出。

输入样例
c
2
TaNgvFRLJUvgnLjdKvaacumgGtOl
dcaLySkOWzYyAYKBOyfIIxOZCi
输出样例
dcaLySkOWzYyAYKBOyfIIxOZCi
题目分析
在做这道题的过程中,我学到了测试用例的妙用。他用来比较的字母是c,如果一直答案错误的话可以把c换成其他字母测试。比如出现了很多次的o和a。

#include <stdio.h>
#include <string.h>
/* 函数声明 */
int CountNum(char *a,char n);

int main()
{
	char c,a[100][1000]; 
	int n,i,ans[100]={0};
	scanf("%c %d",&c,&n);
	for(i=0;i<n;i++)
	{
		scanf("%s",a[i]);
		ans[i]=CountNum(a[i],c);
//		if(ans[i]>=2) 
//		puts(a[i]);		注意题目要求,里面有一句话是后输入的先输出,所以要分开写输出 
	}
	for(i=n-1;i>=0;i--)
	{
		if(ans[i]>=2)
		{
			puts(a[i]);//用puts不用再换行了 
		 } 
	}
	
	return 0;
}	
int CountNum( char *a,char c)	//整个复制上一道题的那个函数 ,但是这道题出现了大写的 
 {
 	int i,ans=0;
 		for(i=0;a[i]!='\0';i++)//循环整个数组,数组结束标志是\0 
		 {
		 	if((a[i]==c)||a[i]==c+32||a[i]==c-32)//如果有其他字符,要考虑到大小写边界问题,这个题就不用了 
		 	ans++;
		  }
	return ans; 
 }
	

E. C语言_ex19_26

题目描述
有一个字符串均由数字组成,我们规定该字符串的校验和的计算方法为,首先把每一位上的数字都乘以一个权值,然后把所得到的这些乘积再加起来,得到一个和,最后用这个和模除13即得到了校验和。其中各位的权值为:从高位向低位数,假设某位为第n位,则当n模除11为0时,权值为21, 当n模除11为1时,权值为7, 当n模除11为2时,权值为16, 当n模除11为3时,权值为29, 当n模除11为4时,权值为24, 当n模除11为5时,权值为2, 当n模除11为6时,权值为23, 当n模除11为7时,权值为8,当n模除11为8时,权值为 6, 当n模除11为9时,权值为14, 当n模除11为10时,权值为19。先请你写一段程序来计算这个校验和。

输入:
只有一行,为一个长度不超过1000且仅包含数字的字符串。

输出:
为上述规则下该字符串的校验和。测试用例保证所有整数可以用 int存储。

输入样例
90372186209
输出样例
12

题目分析

  • 快来做阅读题···题目里面说所有整数都可以用int存储,那就直接设置int数组,但是没有给终止条件,如果直接往int数组里放,会都挤在a[0]这个格子里,所以就先用char字符串做输入跳板,然后转换成整形数组再做逻辑运算。

  • 有大量的一对一规则,函数里面用switch case比较方便,考试时候如果这个用不好,if也没关系的。

  • 取模运算是%!!!我写的时候用了/,看了半天愣是没看出来。不要害怕,很简单的。

#include <stdio.h>
#include <string.h>

 int qz(int input);	//“权值”函数声明 
	
int main()
{
	int i,j,a[10000]={0},ans=0;	//a是整形数组 
	char b[10000];				//b是跳板字符串 
	
	scanf("%s",b);				//输入字符串 
	
	for(i=0;b[i]!='\0';i++)		//把他拆掉,变成整形数组 
	{	
		a[i]=b[i]-'0';		
		ans+=a[i]*qz(i+1);	//计算位*权值再取13的模 
	}
	printf("%d",ans%13);//注意这个13不要除的太早,放在这里比较方便。
 } 
 
 int qz(int input)//计算权值的函数 
 {
 	int output=0; 
 	 
 	switch(input%11) 	//对11取模,然后选一个权值输出到output 
 	{
 		case 0:output=21;break; 
 		case 1:output=7;break; 
 		case 2:output=16;break; 
 		case 3:output=29;break; 
 		case 4:output=24;break;
		case 5:output=2;break;  
		case 6:output=23;break; 
		case 7:output=8;break; 
		case 8:output=6;break; 
		case 9:output=14;break; 
		case 10:output=19;break; 
	
	 }
	 return output;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值