计算机导论第十周课后作业

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44201830/article/details/128069821