第十一周作业

本周作业头

这次作业属于哪个课程C语言程序设计ll
这个作业要求在哪里https://edu.cnblogs.com/campus/zswxy/software-engineering-class1-2018/homework/3202
我在这个课程的目标是学习递归函数以及初步了解大型程序的结构
这个作业在哪个具体方面帮助我实现目标使用递归函数编程
参考文献教科书

一、基础作业

选择题

1581846-20190510175455403-1180446872.jpg

题目1.汉诺塔问题*
汉诺塔是一个源于印度古老传说的益智玩具。据说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘,大梵天命令僧侣把圆盘移到另一根柱子上,并且规定:在小圆盘上不能放大圆盘,每次只能移动一个圆盘。当所有圆盘都移到另一根柱子上时,世界就会毁灭。
1581846-20190510161425185-324936210.png
请编写程序,输入汉诺塔圆片的数量,输出移动汉诺塔的步骤。

输入格式

圆盘数 起始柱 目的柱 过度柱

输出格式

移动汉诺塔的步骤
每行显示一步操作,具体格式为:
盘片号: 起始柱 -> 目的柱
其中盘片号从 1 开始由小到大顺序编号。

输入样例

3
a c b

输出样例

1: a -> c
2: a -> b
1: c -> b
3: a -> c
1: b -> a
2: b -> c
1: a -> c

1).实验代码

#include<stdio.h>
void hanio (int n,char a,char b,char c);
int main()
{
    int n;
    char a,b,c;
    scanf("%d\n",&n);
    scanf("%c %c %c",&a,&b,&c);
    hanio(n,a,b,c);
    
    return 0;
}

   /*搬动n个盘,从a到b,c为中间过渡*/ 
void hanio (int n,char a,char b,char c)
{
    if(n==1)
    {
    printf("%d: %c -> %c\n",n,a,b);
    }
    else{
        hanio (n-1,a,c,b);
        printf("%d: %c -> %c\n",n,a,b);
        hanio(n-1,c,b,a);
        }
}

2).设计思路
1581846-20190510174018963-189747863.jpg
3).调试过程中遇到的问题和解决方法
要是书上没有这个原题,不然我是根本就写不出来的......
还有就是要记得单独定义字符型数据不然编译通不过。
4).运行结果截图
1581846-20190510165129611-1244620624.png

题目2.估值一亿的AI核心代码
1581846-20190510161703865-264649691.png
以上图片来自新浪微博。

本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

无论用户说什么,首先把对方说的话在一行中原样打印出来;
消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
把原文中所有大写英文字母变成小写,除了 I;
把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;
把原文中所有独立的 I 和 me 换成 you;
把原文中所有的问号 ? 换成惊叹号 !;
在一行中输出替换后的句子作为 AI 的回答。

输入格式:

输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

输出格式:

按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

输入样例:

6
Hello ?
 Good to chat   with you
can   you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know

输出样例:

Hello ?
AI: hello!
 Good to chat   with you
AI: good to chat with you
can   you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know

1).实验代码
太难了吧......完全就是看都看不懂啊......

预习作业

1.数组指针
转载自:https://www.cnblogs.com/mq0036/p/3382732.html
数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:

int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。
2.指针数组
函数指针数组中,存放的一定要是相同返回值类型,以及相同参数列表的函数指针,这样数组可以通过下标来调用不同的函数,省去了使用大量的判断语句。下面举个例子:

假设你要看电影,下面有4种类型的,动作,浪漫,卡通,搞笑,然后再输入电影名观看。按照以前我可能就会是一堆if else或者switch case来判断 ,但现在可以这样:

#include<stdio.h>
 
void watch_action(char* name)
{
    printf("Action movie  <%s> starts\n",name);
}
 
void watch_funny(char* name)
{
    printf("Funny movie  <%s> starts\n",name);
}
 
void watch_romantic(char* name)
{
    printf("Romantic movie <%s> starts\n",name);
}
 
void watch_cartoon(char* name)
{
    printf("cartoon <%s> starts\n",name);
}
 
int main(int argc, char const *argv[])
{
    void (*watch[4])(char* name)={watch_action,watch_funny,watch_romantic,watch_cartoon};
    printf("what kinds of movie would you want\n");
    int num;
    scanf("%d",&num);
    printf("please input the movie name of this kinds\n");
    char movie_name[128];
    scanf("%s",movie_name);
    watch[num](movie_name);
    return 0;
}

 通过num来调用不同的函数,省去了一堆判断语句,感觉还是方便蛮多的。
转载自:https://blog.csdn.net/Canger_/article/details/80547235
3.指针函数
转载自:http://nevel.cnblogs.com/p/6370264.html
指针函数是指带指针的函数,即本质是一个函数,函数返回类型是某一类型的指针。

类型标识符 *函数名(参数表)

int *f(x,y);

首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。

表示:

float *fun();
float *p;
p = fun(a);

当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。
格式:
类型说明符 * 函数名(参数)
当然了,由于返回的是一个地址,所以类型说明符一般都是int。
例如:

int *GetDate();
int * aaa(int,int);

函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。

int * GetDate(int wk,int dy);
main()
{
  int wk,dy;
   do{
   printf(Enter week(1-5)day(1-7)\n);
   scanf(%d%d,&wk,&dy);
   }
   while(wk<1||wk>5||dy<1||dy>7);
   printf(%d\n,*GetDate(wk,dy));
 }
 
 int * GetDate(int wk,int dy)
 {
   static int calendar[5][7]=
   {
     {1,2,3,4,5,6,7},
     {8,9,10,11,12,13,14},
     {15,16,17,18,19,20,21},
     {22,23,24,25,26,27,28},
     {29,30,31,-1}
   };
   return &calendar[wk-1][dy-1];
 }

子函数返回的是数组某元素的地址。输出的是这个地址里的值。
4.函数指针
转载自:http://nevel.cnblogs.com/p/6370264.html
函数指针是指向函数的指针变量,即本质是一个指针变量。

    int (*f) (int x); /*声明一个函数指针 */

   f=func; /* 将func函数的首地址赋给指针f */

指向函数的指针包含了函数的地址的入口地址,可以通过它来调用函数。声明格式如下:
类型说明符 (*函数名) (参数)
其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明笔削和它指向函数的声明保持一致。
指针名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。
例如:

void (*fptr)();

把函数的地址赋值给函数指针,可以采用下面两种形式:

fptr=&Function;
fptr=Function;

取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。
可以采用如下两种方式来通过指针调用函数:

x=(*fptr)();
x=fptr();
第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。

下面举一个例子:

  void (*funcp)();
  void FileFunc(),EditFunc();
  
  main()
  {
    funcp=FileFunc;
    (*funcp)();
    funcp=EditFunc;
    (*funcp)();
 }

 void FileFunc()
 {
   printf(FileFunc\n);
 }
 
 void EditFunc()
 {
   printf(EditFunc\n);
 }

程序输出为:

FileFunc
EditFunc

主要的区别是一个是指针变量,一个是函数。在使用是必要要搞清楚才能正确使用

5.二级指针

#include <stdio.h>
int main(int argc, char const *argv[])
{
    char* num[9]={"one","two","three","four","five","six","seven","eight","nine"};
    char** p;
    p = &num[0];
    int number;
    scanf("%d",&number);
    printf("English Number is %s\n",*(p+number-1));
    return 0;
}

定义一个指针数组num,输入阿拉伯数字转换成英文数字。这里如果单单只有一级指针是不够的,一级指针只能找到字符串所在的位置,但是找不到其首地址,导致无法输出。所以需要二级指针二级寻址来输出。
转载自:https://blog.csdn.net/Canger_/article/details/80547235
6.单向链表
转载自:https://blog.51cto.com/6306331/2073431
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
链表的数据的数据结构

typedef struct node
{
        int data;                                           //数据域
        struct node *next;                          //指针域
}NODE_t;

有删减

二、学习进度条

周/日期这周所花的时间代码行学到的知识点简介目前比较疑惑的问题
3/4-3/102天38行定义文件指针和文件数据的简单处理对于文件数据的使用很手生
3/11-3/151天24行二维数组的定义和引用强烈要求老师把这几次的题都讲解一下太多问题了
3/16-3/221天37行一些数组的简单算法不知道二分法、选择排序法以及冒泡排序法的具体区别
3/23-3/291天20行复习了文件和字符型函数以及学习用字符串编程文件使用的还不熟练敲代码的过程中老是出错还有不知道怎么表示字符串的长度
3/30-4/56h88行复习自定义函数,指针变量的定义,指针变量的基本运算指针与数组的关系
4/6-4/123h46行将指针与数组结合运用到编程里边代码稍微复杂点就不知道怎么使用指针了
4/13-4/198h38行将指针数组字符串字符串函数结合使用到编程里边,预习了结构尝试着照着书上面的程序做了预习题还是没有完全掌握冒泡排序算法
4/20-4/265h120行将结构运用到编程里面结构指针数组老是会混淆
5/6-5/104h26行递归函数的使用递归函数到底有什么用

三、学习感悟

这作业也太难了吧,一点都不简单......

四、结对编程总结

感觉我们都好菜啊,题目也太难了吧,根本就不会做

五、表格和折线图

代码行数博客字数
第一周45行536
第二周38行496
第三周24行757
第四周37行1239
第五周20行1179
第六周88行1688
第七周46行1528
第八周38行2091
第九周120行3744
第十一周26行3062

1581846-20190510205723245-1390609148.png

转载于:https://www.cnblogs.com/huangxuannn/p/10843614.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值