c语言网络教室第十章、第十一章答案
第十章:
10-1. 偶数分解
成绩: 10 / 折扣: 0.8
编写程序,输入若干个大于2的正整数,如果是偶数,则将其分解为两个素数并输出;如果输入的奇数,则输出“××× is odd number!” ;输入为0时程序结束。只有1和它本身这两个因数的自然数叫做素数,0和1既不是素数也不是和数。
输入:整数序列,0
输出:偶数1 = 素数A + 素数B (当输入是偶数时)
奇数1 is odd number! (当输入是奇数时)
#include"stdio.h"
int main()
{int x,i,j,p;
scanf("%d",&x);
while(x>0)
{if(x%2==0)
for(i=2;i<=x/2;i++)
{p=0;
for(j=2;j<i;j++) if(i%j==0) p=1;
for(j=2;j<x-i;j++) if((x-i)%j==0) p=1;
if(p==0) {printf("%d=%d+%d\n",x,i,x-i); break;}}
if(x%2==1) printf("%d is odd number!\n",x);
scanf("%d",&x);}
}
10-2 求数列的第N项(递归)
成绩: 10 / 折扣: 0.8
c语言编写递归函数已知整数数列第一项和第二项是1,该数列从第三项开始,如果该项是奇数项,则它是前两项之和,如果该项是偶数项,则它是前两项之差,即:
f( n ) = 1 当 n = 1 或 2 时,
f( n ) = f( n-1 ) - f( n-2 ) 当n是偶数时,
f( n ) = f( n-1 ) + f( n-2 ) 当n是奇数时,
编写一个递归函数,求数列的第N项。
#include"stdio.h"
int main()
{int a[100],n,i;
scanf("%d",&n);
a[1]=a[2]=1;
for(i=3;i<=n;i++)
{if(i%2==1) a[i]=a[i-1]+a[i-2];
else a[i]=a[i-1]-a[i-2];}
printf("%d\n",a[n]);
}
10-3. 求最大公约数(递归)
成绩: 10 / 折扣: 0.8
请使用递归算法计算正整数n和m的最大公约数GCD(n,m)。
= m 当 m<=n 且 n mod m =0(mod 表示求余)
GCD(N,M) = GCD(m,n) 当n<m时
=GCD(m, n mod m) 其他
输入: n和m
输出: n和m的最大公约数
#include"stdio.h"
int main()
{int m,n,i,j,k;
scanf("%d %d",&m,&n);
if(m>n) {i=m; m=n; n=i;}
k=n%m;
if(k==0) printf("%d\n",m);
else for(j=k;j>=1;j--)
if(k%j==0&&m%j==0) {printf("%d\n",j); break;}
}
第十一章:
11-1. 子串反向(递归)
成绩: 10 / 折扣: 0.8
请编写一个递归函数 reverse(char str[], int start, int end ) ,该函数的功能是将串 str 中下标从 start 开始到 end 结束的字符颠倒顺序。假设 start 和 end 都在合理的取值范围。
例如:
执行前:str[]="0123456";start=1 ;end=4
执行后:strr[]="0432156"
要求在该函数中不使用新的数组,没有循环。
注意:只需要编写递归函数 reverse,系统中已经设置好了main函数。
预设代码
strover.c
reverse(char str[],int x,int y)
{char k;
if(y-x==1) {k=str[y];str[y]=str[x];str[x]=k;}
else if(y>=2&&y>x) {k=str[y];str[y]=str[x];str[x]=k; reverse(str,x+1,y-1);}
}
11-2. 字符串的减法
成绩: 10 / 折扣: 0.8
输入
字符串s和t(串长不超过80个字符),将在字符串s中出现,但未在字符串t中出现的字符组成一个新的字符串放在u中,u中字符按原字符串中字符顺序排列,不去掉重复字符,输出u。
例如:当s="12345678",t="2468"时,u="1357"。
输入:第一行为串s
第二行为串t
输出:串u
#include"stdio.h"
#include"string.h"
main()
{char s[80],t[80],u[80];
int i,j,k=0,m,n,p;
gets(s);
gets(t);
m=strlen(s);
n=strlen(t);
for(i=0;i<m;i++)
{p=0;
for(j=0;j<n;j++) if(s[i]==t[j]) p=1;
if(p==0) {u[k]=s[i]; k++;}
if(i==m-1) break;}
for(i=0;i<k;i++) printf("%c",u[i]);
printf("\n");
}
11-3. 折半插入排序
成绩: 10 / 折扣: 0.8
排序是程序设计中的重要内容之一,据不完全统计,在一般的数据处理程序中,排序占去了处理机时间的四分之一,而在典型的安装程序中,一半以上的时间用在对表的排序上。
折半查法的思路:
先取有序数组的中间元素与查值相比较。
如果相等则查成功:
如果查值大于中间元素,
则再取高半部的中间元素与查值相比较。
如查值小于中间元素,
则再取低半部的中间元素与查值相比较。
如果如查值等于中间元素,则因为相同数值仅保存一次,故不再插入。
如此重复直到查成功或最终未到该数为止。
在折半插入排序算法中,由于进行关键字比较的次数比较少,所以算法的效率就比较高。
例如:有序列10,90,80,30,20,15。我们进行折半插入排序的过程如下:
初始(第1趟):有序子序列为空。待排序数据为10,则不需要进行关键字比较,直接插入。
第2趟:有序子序列为“10”,待排序数据为90,进行1次比较就可以确定插入位置,得到长度+1的有序子序列“10,90”。此时比较次数为 1 。
第3趟:有序子序列为“10,90”。待排序数据为80,取有序序列中间(取整)的元素10进行第 1 次比较,80大;则应该从“90”这个子序列中进行折半插入80,进行第 2 次比较,定位应该的插入位置,得到有序序列“10,80,90”。此趟比较次数为 2。
第4趟:有序子序列为“10,80,90”。待排序数据为30,取有序序列中间的元素80进行第 1 次比较,30小;则应该从“10”这个子序列中进行折半插入30,进行第 2 次比较,可以定位应该插入的位置,得到新的长度+1的有序子序列。此趟比较次数为 2。
第5趟:有序子序列为“10,30,80,90”。待排序数据为20,取有序序列中间的元素30进行第 1 次比较,2
0小;则应该从“10”这个子序列中进行折半插入20,进行第 2 次比较,可以确定应该插入的位置。此趟比较次数为 2。
第6趟:有序子序列为“10,20,30,80,90”。待排序数据为15,取有序序列中间的元素30进行第 1 次比较,15小;则应该从“10,20”这个子序列中进行折半插入15,取子序列中间的元素10,进行第 2 次比较,15大,则应该从“20”这个子序列中进行折半插入排序,再进行 1 次比较就可以确定应该插入的位置。此趟比较次数为 3。
此时,完成排序,得到升序序列“10,15,20,30,80,90”。在整个排序过程中进行关键字比较的总次数 = 0+1+2+2+2+3 = 10。
输入:数列中元素个数(元素数量<=100)
数列
输出:使用折半插入排序后的有序升序数列
说明:输出数列之间用空格分隔。
#include"stdio.h"
int main()
{int n,m=1,i=0,j,x,y,a[30],b[30];
scanf("%d",&n);
for(i=0;i<n;i++)
{scanf("%d",&a[i]);
if(i==0) b[0]=a[0];
else
{x=0; y=m-1;
while(y-x>1)
{if(a[i]>b[(x+y)/2]) x=(x+y)/2;
if(a[i]<b[(x+y)/2])
{if((x+y)%2==1) y=(x+y)/2+1;
else y=(x+y)/2;}}
if(a[i]>b[x]&&a[i]<b[y])
{for(j=m-1;j>=y;j--) b[j+1]=b[j];
b[y]=a[i]; m++;}
if(a[i]<b[x])
{for(j=m-1;j>=x;j--) b[j+1]=b[j];
b[x]=a[i]; m++;}
if(a[i]>b[y])
{b[y+1]=a[i]; m++;}}}
for(j=0;j<m-1;j++) printf("%d ",b[j]);
printf("%d\n",b[m-1]);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论