6-1. 猴子吃桃-递归
首先要清楚题目需要函数干什么——返回第day天吃的桃子数量。
根据题目的描述,第1天的桃子数可用第2天的桃子数确定,第x天的桃子可用第x+1天的桃子数确定,直到第n天,桃子剩余1个。
因此终止条件为day=n的时候,只剩一个桃子。
递归公式根据题目可归纳得出。f(x)/2-1 = f(x+1),f(x)是我们想知道的第x天的桃子数,f(x+1)是猴子吃了一次桃子之后的桃子数。
int Peach(int day){
if(day==n){//终止条件,第n天只有一个桃子
return 1;
}
else{
return (Peach(day+1)+1)*2;
}
}
6-2 奇妙的定律-递归
根据题目描述,确定终止条件和递归方式。
- 终止条件:n=1的时候,说明跌打到了最后一次,输出1,结束递归;
- 递归公式:根据n的奇偶性分为两种递归。偶数则不断除2,奇数则乘3再加1。
题目要求输出迭代过程,因此每一次递归函数中都应该输出当前的参数来显示最终过程。
void F(int n){
if(n==1){//终止条件
printf("1\n");
return 1;
}
else if(n%2==0){//偶数
printf("%d ",n);
return F(n/2);
}
else {//奇数
printf("%d ",n);
return F(n*3+1);
}
}
6-3 回文
本题的回文串判断使用的方式是比较首尾相对的字符是否相等,一直比较到字符串的中间位置。
思路上比较简单,递归终止条件是比较到字符串中间位置,对于长度为偶数的字符串来说start>end,对于长度为奇数的字符串来说start=end。
在比较的过程中如果出现不相等的情况,说明不是回文数,没必要接着比较下去,直接返回0;如果字符相等,则需要接着向下比较,两个指针分别向中间移动一位。
难点(扩展知识点):运算符
char*
表示的是字符指针,指向一个字符,char* start
中start存储的是一个字符的地址。
对于指针变量,使用运算符获得所指向的地址内部的元素值。指针变量的移动可用+1、-1来移动,表示移动若干字节(和指针所指向的元素类型对应,char指针移动1字节,int指针移动4字节)
int testPalindrome ( char *start, char *end)
{
if(start >= end)//递归终止条件
return 1;
else if(*start != *end)//递归之前先判断此次函数的结果,如果两个字符不相等则表示不是回文。
return 0;
else//如果本次递归函数的两个字符相等,接着比较下一对字符。
return testPalindrome((start+1), (end-1));
}
7-36 实验7_1_平均成绩
读入数组的同时进行总分统计,之后进行均值计算即可。
注意数据类型的统一。
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
int grade[n];
int i;
double sum=0;
for(i=0;i<n;i++){
scanf("%d",&grade[i]);
sum+=grade[i];
}
printf("%.2lf\n",sum/n);
return 0;
}
7-37 实验7_2_数组查找
输入两个数组,遍历数组2,在数组1中从头查找数组2的元素。
注意输出的时候需要考虑数组下标的位置对输出的影响。
#include <stdio.h>
int main()
{
int n = 0, m = 0;
scanf("%d", &n);
int nums[n];
//数组1输入
for (int i = 0; i < n; i++) {
scanf("%d", &nums[i]);
}
scanf("%d", &m);
int querys[m];
//数组2输入
for (int j = 0; j < m; j++) {
scanf("%d", &querys[j]);
}
for (int j = 0; j < m; j++) {
int i = 0;
for (i = 0; i < n; i++) {//在数组1中查找数组2的元素query[j]
if (nums[i] == querys[j]) {
if (i - 1 >= 0 && i + 1 < n)//一般情况
printf("%d %d\n", nums[i - 1], nums[i + 1]);
else if (i - 1 >= 0)//i+1>=n,查找的元素在数组的右边界
printf("%d\n", nums[i - 1]);
else if (i + 1 < n)i-1<n,查找的元素在数组的左边界
printf("%d\n", nums[i + 1]);
else//i-1<0且i+1>=n,表示数组长度为1的特殊情况
printf("NULL\n");
break;
}
}
if (i == n) printf("NULL\n");//查找失败的情况
}
}
7-38 实验7_3_奇数偶数
这一题考查两数组之间的数值移动,因为主要看的是数组输出的结果,因此思路比较多。
- 解法1:将原始数据存入数组1,第一次遍历数组1查找偶数元素放入数组2中,第二次遍历数组1查找奇数元素放入数组2中,输出数组2的元素;
- 解法2:将原始数据存入数组1,第一次遍历数组1查找偶数元素直接输出,第二次遍历数组1查找奇数元素直接输出。
- 解法3:输入数据的时候定义两个数组,奇数偶数分别放入不同的数组,之后将奇数元素挪入偶数数组中,输出偶数数组;
- 解法4:输入数据的时候定义两个数组,奇数偶数分别放入不同的数组,之后遍历偶数数组和奇数数组,输出元素。
- 解法5:输入数据的时候,遇到偶数直接输出,遇到奇数存入数组中,遍历数组输出全部奇数。
- ……
如下代码使用解法3的思路。
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
int old[n],result[n];
int i=0;
int old_index=0,re_index=0;
for(i=0;i<n;i++){
int number;
scanf("%d",&number);
if(number%2==0){//偶数直接写入结果数组中
result[re_index]=number;
re_index++;
}
else{//奇数写入原数组,等待后面挪用
old[old_index]=number;
old_index++;
}
}
//将old中的元素按照顺序放入结果数组中。放入位置根据re_index和old_index的值来确定
for(i=0;i<old_index;i++){
result[re_index]=old[i];
re_index++;
}
for(i=0;i<n-1;i++){//前n-1个数
printf("%d ",result[i]);
}
printf("%d\n",result[i]);//第n个数
return 0;
}