第十一周作业
本周作业头
这个作业属于那个课程 | C语言程序设计II |
这个作业要求在哪里 | https://edu.cnblogs.com/campus/zswxy/MS/homework/3206 |
我在这个课程的目标是 | 对相对复杂的问题,合理定义程序的多函数结构 |
这个作业在那个具体方面帮助我实现目标 | 使用递归函数进行编程;掌握宏的基本用法;掌握编译预处理的概念 |
参考文献 | C语言程序设计(第3版) |
基础作业
宏定义“#define DIV(a, b) a/b”,经DIV(x + 5, y - 5) 引用,替换展开后是()。 (1分)
定义带参数的宏“#define JH(a,b,t) t = a; a = b; b = t”,对两个参数a、b的值进行交换,下列表述中正确的是()。 (1分)
如果所有的变量按照下面的程序进行定义和声明,那么在main()函数中所有可用的变量为 ()。 (2分)
void fun(int x)
{
static int y;
……
return;
}
int z;
void main( )
{
int a,b;
fun(a);
……
}
如果一个变量在整个程序运行期间都存在,但是仅在说明它的函数内是可见的,这个变量的存储类型应该被说明为( )。 (1分)
下面说法中正确的是()。 (1分)
凡是函数中未指定存储类别的局部变量,其隐含的存储类型为( )。 (1分)
在一个C源程序文件中,若要定义一个只允许本源文件中所有函数使用的全局变量,则该变量需要使用的存储类别是。 (1分)
将一个函数说明为static后,该函数将 ( )。(1分)
PTA:1.编程题:汉诺塔问题
汉诺塔是一个源于印度古老传说的益智玩具。据说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘,大梵天命令僧侣把圆盘移到另一根柱子上,并且规定:在小圆盘上不能放大圆盘,每次只能移动一个圆盘。当所有圆盘都移到另一根柱子上时,世界就会毁灭。
请编写程序,输入汉诺塔圆片的数量,输出移动汉诺塔的步骤。
输入格式
圆盘数 起始柱 目的柱 过度柱
输出格式
移动汉诺塔的步骤
每行显示一步操作,具体格式为:
盘片号: 起始柱 -> 目的柱
其中盘片号从 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
实验代码
#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; } 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); } }
设计思路:
就是我在百度的过程中学到了(
我们在利用计算机求汉诺塔问题时,必不可少的一步是对整个实现求解进行算法分析。到目前为止,求解汉诺塔问题最简单的算法还是同过递归来求,至于是什么是递归,递归实现的机制是什么,我们说的简单点就是自己是一个方法或者说是函数,但是在自己这个函数里有调用自己这个函数的语句,而这个调用怎么才能调用结束呢?,这里还必须有一个结束点,或者具体的说是在调用到某一次后函数能返回一个确定的值,接着倒数第二个就能返回一个确定的值,一直到第一次调用的这个函数能返回一个确定的值。
实现这个算法可以简单分为三个步骤:
(1) 把n-1个盘子由A 移到 B;
(2) 把第n个盘子由 A移到 C;
(3) 把n-1个盘子由B 移到 C;
从这里入手,在加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步:
(1)中间的一步是把最大的一个盘子由A移到C上去;
(2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
(3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;
)
遇到的问题
本次的作业我一开始是没有思路的,后来看了杨浩诚同学给的汉诺塔视屏,有了一点思路,就是https://blog.csdn.net/xb2355404/article/details/79144451,后来又在网上看来这位博主的文章,大致懂了,但是,我不敢保证自己全懂
正确截图
2.编程题:估值一亿的AI核心代码
以上图片来自新浪微博。
本题要求你实现一个稍微更值钱一点的 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
实验代码
#include <stdio.h> #include <string.h> int iszf(char a){ if(a>='0' && a<='9'){ return 1; } if(a>='a' && a<='z'){ return 1; } if(a>='A' && a<='Z'){ return 1; } return 0; } char zxxx(char a){ if(a>='A' && a<='Z'){ if(a=='I'){ return 'I'; }else{ return a+32; } } return a; } int main(){ int n; scanf("%d\n",&n); while(n--){ char a[1010],b[1010]; int la=0,lb=0; gets(a); printf("%s\n",a); la=strlen(a); int lk=0; int ff=0; for(int i=0;i<la;i++){ if(a[i]==' '){ lk++; }else if(!iszf(a[i])){ lk=0; ff=1; b[lb++]=zxxx(a[i]); }else{ if(lk>0 && ff){ b[lb++]=' '; } lk=0; ff=1; b[lb++]=zxxx(a[i]); } } b[lb]=0; printf("AI: "); for(int i=0;i<lb;i++){ if( (b[i]=='I')&& (i==0||!iszf(b[i-1]))&& (!iszf(b[i+1])) ){ printf("you"); }else if( (b[i]=='m'&&b[i+1]=='e')&& (i==0||!iszf(b[i-1]))&& (!iszf(b[i+2])) ){ printf("you"); i+=1; }else if(b[i]=='?'){ printf("!"); }else if( (b[i]=='c'&&b[i+1]=='a'&&b[i+2]=='n'&&b[i+3]==' '&&b[i+4]=='y'&&b[i+5]=='o'&&b[i+6]=='u')&& (i==0||!iszf(b[i-1]))&& (!iszf(b[i+7])) ){ printf("I can"); i+=6; }else if( (b[i]=='c'&&b[i+1]=='o'&&b[i+2]=='u'&&b[i+3]=='l'&&b[i+4]=='d'&&b[i+5]==' '&&b[i+6]=='y'&&b[i+7]=='o'&&b[i+8]=='u')&& (i==0||!iszf(b[i-1]))&& (!iszf(b[i+9])) ){ printf("I could"); i+=8; } else{ printf("%c",b[i]); } } printf("\n"); } return 0; }
设计思路
看了李代传同学的思路,太复杂了!
我做到后面崩溃啊,实在写不出来。。后来借鉴了https://blog.csdn.net/qq_26122455/article/details/88930794
不想写了
预习作业
第十二周的教学内容是:第十一章 指针进阶
数组指针:详细题解请看https://www.cnblogs.com/anwcq/p/p_shuzuzhizhen.html
指针数组:详细题解请看https://baike.so.com/doc/6776799-6992543.html
指针函数:
(1) 基本概念
指针函数:顾名思义就是带有指针的函数,即其本质是一个函数,只不过这种函数返回的是一个对应类型的地址。
(2) 定义式
type *func (type , type)
如:int *max(int x, int y)
(3) 例子详解
#include <iostream> using namespace std; int *GetNum(int x); //指针函数声明形式 void main(void) { cout<<"===============start================"<<endl; int num; cout<<"Please enter the number between 0 and 6: "; cin>>num; cout<<"result is:"<<*GetNum(num)<<endl; //输出返回地址块中的值 } int *GetNum(int x) { static int num[]={0,1,2,3,4,5,6}; return &num[x]; //返回一个地址 } 总结:从上面的小例子我们可以看出子函数返回的是数组中某一元素所在的地址值,输出的是这一地址中存储的数。
详情请看https://blog.csdn.net/u014131641/article/details/51104808
函数指针:详细题解请看https://www.cnblogs.com/uniqueliu/archive/2011/07/27/2118619.html
二级指针:详情请看https://baike.so.com/doc/6960278-7182789.html
单向链表:详情请看https://baike.so.com/doc/1739084-1838554.html
学习进度条
周 | 这周所花的时间 | 代码行数 | 学到的知识简介 | 目前较为迷惑的问题 |
1 | 7 d | 80 | 读取文件 | 为什么读取文件这样复杂 |
2 | 7d | 100 | 数组 | 二维数组不太懂 |
3 | 7d | 150 | 指针 | 指针不太会 |
4 | 7d | 156 | 学到了指针的基本用法,还有用指针做自定义函数的形参用法 | 指针不太熟 |
5 | 7d | 240 | 自定义函数 | 指针的拓展不会使用 |
6 | 7d | 170 | 动态分布函数 | pta老是错 |
7 | 7d | 175 | 结构体函数 | 指针 没完全掌握 |
8 | 7d | 230 | 学习了结构体 | 递归函数 |
9 | 7d | 189 | 学习了结构体 | 递归函数 |
10 | 7d | 0 | 刘未鹏的三篇文章,递归函数,链表 | 递归函数 |
11 | 7d | 230 | 递归函数,指针函数,函数指针 | 递归函数 |
累计代码行数和博客字数
学习感悟
1)对于递归函数我觉得是本学期的难点,尤其是本次pta上老师布置的几个题目,还是很有趣的。
2)疑惑:就是有时候写题目感觉有更简洁的方法写出来吧,但是目前有时候我无法实现。很无奈。
3)继续努力吧,实在不会也没关系,没准下次就会了。
结对编程
过程:就是互相交流自己的思路和想法吧。把队友不知道的知识捋了一次。
优点:学习完了指针和结构体之后,我觉得自己的代码更简洁了。但是我希望自己可以有更多的好的思路来使代码更简洁而规范
缺点:我这次遇到的队友水平在我之下,没给我分享他的收获。