算法笔记课后题总结

学了将近一年的计算机专业,懵懵懂懂的第一学期,完全不知道方向,然后是渐渐有感觉的第二学期。到了大三,相比之前,自己的方向更加的明了和清晰,同时在学习了这么多以后发现,算法才是计算机的核心,编程能力是计算机的基础,独立解决问题的能力是计算机领域的基本要求,保持对新鲜技术和事物的兴趣是计算机这一新兴领域的基本素质。这篇博客是在做算法笔记课后题时的一点感悟和总结,会保持不断的更新。这样做,一是时刻总结让自己温习,同时也希望这些问题和总结能帮到其他的人。

<1>_getch(),不用在控制台上显示即可读取输入,在控制台中,与getchar()区别是,不用点击回车就能将输入读入变量中。

<2>单引号括字符,双引号括字符串。

<3>当要判断”==”号的情况时,最好将常量写在左边,变量写在右边,这样的好处是当你出现笔误少写一个”=”号时,编译器会自动报错,这样便于发现错误,反之,编译器不会报错这样就很难发现错误。

<4>字符串的赋值一定要用strcpy()函数,因为字符串变量表示的首地址,没有值的含义,顾不能直接用”=”号赋值。

<5>strcmp(str1,str2)返回值的情况是,当str1=str2时,返回值是0;当str1>str2时,返回的是正数,返回的是str1比str2究竟大多少;当str1 < str2时字符串返回负数,反映的是str1比str2小多少。所以要知道的是并不是返回的是正数和零,所以在使用if(strcmp(str1,str2))时一定要加上”>=0” or “<=0”的判断。

<6>union 的用法:共用体,也叫做联合体,在一个“联合”内可以定义多种不同类型的数据类型,一个被声明为该“联合”类型的变量中,允许装入该联合体中所定义的任何一种数据,这些数据共享一段内存,以达到节省空间的目的。union变量所占用的内存长度等于最长的成员的内存长度。共用体内由于使用同样的地址,固采用的是覆盖技术。所以形如&a.mark,&a.num,&a.score的值都一样,但是不能直接用共用体变量a输出共用体内的值,一定要带上对象那个名,这样才知道调用的是哪一种存储类型的值。union里面的东西共享内存,所不能定义静态引用类型变量。所以union内不允许有放带有构造函数,析构函数和复制构造函数等的类的对象。

<7>当题目要求未给出明确的循环次数的限定时,用while(scanf(“%x”,&x)!=EOF);即当scanf没有检测到输入值时,即结束循环,内容在《算法笔记》P81。

<8>long long 型能表示的范围是-2^63~2^63-1,大致范围是-910^18~910^18。在算法竞赛中,遇到大数问题时,可用字符串的形式输入,然后再转换成long long类型进行计算。如果要进行更大的数的运算,就只能全程用字符串形式计算了。代码中有收集。

<9>在题目越来越的练习中,一定要注意输入和输出的格式问题。特别是输入时的空格和换行符的问题。在scanf(“%c”,&x)或scanf(“%s”,x)时,如果前面有另一个scanf时,就会产生一个换行符和一个空格,这时就需要用getchar()将空格和换行符吸收掉,否则的话会影响到随后的输入输出。

<10>当遇到一些题目时会要多思考是否可以用逻辑更简单的算法解决问题。比如说,用空间换时间。比如第三章练习的第一节的第一题,在长L的马路上,每个整数点指数一课,现在去掉给出区间段上的树,区间段可能会有重复,问剩下树木的棵树。在解决这道题时,可能的第一想法是利用贪心算法解决问题,类似于用人脑的方式解决问题,但是仔细思考可以用利用计算机用空间换时间的的思想解决这一个问题,用hash表的类似方法建立每棵树对应的表格,记录其状态,这样虽然时间复杂度没有多大变化但是逻辑思路更简单,实现起来更简单了。

<11>在计算机中,中文字节占用两个字节,所以在C和C++的编译器中,由于char中只有一个字节,要存储中文必须要定义char类字符串用于存储中文字节,两个char字符存储存储一个中文字符。但在Java虚拟机中,char类型占2个字节,顾可以用一个char类型存储一个中文字符。

<12>在输出格式为,01,02······09等情况时,可以用”%02d”的格式,不足两位时数字前用0补齐。

<13>算法题的错误最有可能出现在输出格式错误的问题上,比如要求输出2012-01-01这种格式,最容易想到的是后两组数字不足2位要前面要用0补齐,但第一组数字就很难发现不足四位时也要用0补齐,所以就很容易出错,因此一定要仔细分析输出格式的问题(这里的分析是要根据已有经验分析不要胡乱凭空猜想)。

<14>自定义一个可以返回数组的函数时,这时就要借用数组指针来完成,通过返回数组的首地址的方式来返回整个数组。具体的定义方式这里有一个很详细的博客对此问题进行了详细的讲解。
如何通过函数对数组进行操作

<15>long型和long int型等价,格式符都为”%ld”格式。

<16>进制间转换的通用思路是,先转换成十进制然后再转化成其他进制。

<17>字符串的结束符是”\0”的ASCII码是0,即空字符NULL,占用一个字符位,因此开字符串的时候千万要记得字符数组的长度一定要比实际存储字符串的长度至少多1。注意:int型组的末尾不需要加\0,只有char型数组需要。还需要注意\0跟空格不是同一个东西,空格的ASCII码是32,切勿混淆。

<18>如果不使用scanf函数的%s格式或gets函数输入字符串(例如使用getchar),一定要在输入的每个字符串后加入”\0”,否则printf和puts输出字符串会因为无法识别字符串末尾而输出一大堆乱码。(例题见第三章第六节第一题)

<19>对于字符串的输入,有了两种方式一个是scanf(“%s”,str)另一个是gets(str)的形式,对于这两种形式,其不同之处是,scanf形式当检测到输入字符串有空格时就会停止输入,但是gets是识别到换行符\n才会结束输入,所以gets可以用来输入带有空格的字符串,在题目文章或句子格式变换时使用,同时使用gets形式需要注意的是,当gets前面有一个scanf形式是,要用getchar接受scanf后面的换行符,这样才不会出现输入异常。puts用来输出一行字符串,即将一维数组(或二维数组的一维)在界面上输出,并紧跟一个换行符。

<20>接上,对于输入字符串来说,要判断输入是否结束有scanf和gets两种方式

1
2
3
4
5
6
7
8
while(scanf("%s",str)!=EOF)
{
...
}
while(gets(str)!=NULL)
{
...
}

注意二者的返回结束标志不同。