近期一系列个人做题反复记不住以及思路不清晰问题的总结
目录:
1.前言
2.喝汽水问题
3.打印菱形以及各种图形(正方形,X形)
4.水仙花数
5.杨辉三角
6.求字符串中的字母个数,数字个数,空格个数以及其他符号个数
1.前言:最近刚刚疯狂肝完C语言全部内容,成就感满满的同时觉得自己已经完全掌握了C语言,于是飘飘然的我被一道又一道题目打败,伴随着挫败感和不甘心,我总结了一下近期我遇到的一些第一眼思路就很混乱和书写代码过程中思路很混乱的题型,也希望大家能从中学到一些东西,避免跳坑
2.喝汽水问题:
a.题目:
b.思路分析:在做这种题目的时候,书写程序不是最关键的,我认为首先要理清楚我们自己的思路:倘若我们真的去喝汽水,我们常规的方法是什么,我想我会折磨去喝:首先喝20瓶后,用20空瓶去兑换10瓶汽水,然后用10个空瓶再去换5瓶汽水
,然后再去用5个空瓶再去换2瓶汽水,再用2个空瓶去换1瓶汽水,再用第三次剩下的1个空瓶喝我们最后换的空瓶再去换1瓶汽水,把前面的瓶数加一起是:20+10+5+2+1+1=39瓶(当然,我这里不考虑跟老板借一瓶汽水再换的情况),在这个过程中,我们注意到,可以换的汽水来源于两个方面:上一次喝掉的汽水和上上次没法兑换剩下的空瓶,借着换汽水这个思路出发,我们可以这样去书写程序:
c.代码解析:
int main() { int total=20;//我们定义初始的能喝到的汽水瓶数为20,后续就用这个量累计 int s=0;//s为每次k余下的不能换的空瓶数 int k=20;//定义初始的k为空瓶数 while(k>=1) { k=k+s;//重新判断目前的总空瓶数为接下来累计喝掉的汽水做准备 total+=k/2;//这就是我写的核心部分,每一次喝到的汽水也就是兑换的汽水就是剩余的没换的空瓶和兑换的空瓶之和/2 s=k%2;//每一次都要看一看兑换时有无遗漏的情况 k/=2;//对空瓶数/2看能兑换多少瓶汽水喝掉成为下一次累计的空瓶数 } printf("%d\n",total); return 0; }
当然,这只是其中一种思路,你也可以用递归去考虑。
``
3.打印菱形及其各种图形(正方形,X形)
a.题目
我这里以打印菱形为例子:
b.思路分析:打印图形我们的方法有很多种,很多人可能往往会选择最无脑也是最麻烦的一行一行打印的方法,但是那样的方法适用于小规模的构造,假如是构造一个100000行的菱形呢?所以,我们要采取更为普适的方法,我在这里首先想到了利用一个拟二维数组的形式去实现。
上半部分:首先观察图形,我发现我可以将其看作上下两部分,上半部分直到最中间的一行,然后开始下半部分。首先观察上半部分,我们发现:这个三角形的空白部分是随着行数的增加在依次递减直到没有的,所以我们这里先打印出空白部分,这里在打印的时候,我们要充分考虑好i与j的关系,比如随着i的变化,j要打印的空白个数与i的关系就是j<7-i-1,同理,我们在打印完空格后随即要打印*,也考虑i与j的关系,这里我们发现j<2i+1,同时注意每一次i循环都要换行,这样,我们上半部分就完成了。
下半部分:观察图形,首先常规打印空白部分,其打印规律为,常规的随着i增大j也增大。然后观察部分,同理,发现其规律为j<26-1-2*i,按循环打出即可。
c.代码解析:
int main() { //上行: int i=0; for(i=0;i<7;i++) { int j=0; for(j=0;j<7-i-1;j++) { printf(" "); } for(j=0;j<2*i+1;j++) { printf("*"); } printf("\n"); } //下行: for(i=0;i<6;i++) { int j=0; for(j=0;j<i+1;j++) { printf(" "); } for(j=0;j<2*6-1-2*i;j++) { printf("*"); } printf("\n"); } return 0; }
后面还有两道题,在这里我就不写具体解法了,我们要总结这类题的特点都是利用你创建的两个循环的变量的关系去让其进行各种排列,按照这种思路去求解即可。
4.水仙花数
a.题目:
b.思路分析:遇到这种特性数字的问题,我们一定要分析好其特点,后面的杨辉三角也是同理,首先水仙花数,我们由153得到,水仙花数满足每一位的位数次方之和等于其本身,所以,我们首先要知道它是几位数,然后我们用一个变量接受这个数据作为平方数,后续即可判断什么是水仙花数
c.代码解析:
int main() { int i=0; for(i=0;i<100000;i++) { int count=0;//首先利用count判断为几位数 int j=i; while(j) { j/=10; count++; } j=i;//恢复j等于i,为下一步做准备 int sum=0; while(j) { sum+=pow(j%10,count); j/=10;//注意,j要及时变位为下一位 } if(i==sum) { printf("%d ",i); } } return 0; }
5.杨辉三角
a.题目:打印杨辉三角:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
………………………………
b.思路分析:首先我们要分析杨辉三角的这个图形的特点,我们可以很清楚的看到杨辉三角上一行相邻两个数的加和等于下一行对应的数,由这个特点我们引进思路,观察图形,我这里把杨辉三角写成了这种方式,其目的是为了什么?没错,二维数组,我这样的写法完全可以把杨辉三角带入成一个二维数组,观察此二维数组,我们看到,其第一列和斜线方向都是1,联想到前面打印菱形的思路,我们说过那道题我建立了一个拟二维数组,既然那里我们运用了行列关系,在这里我们就更应该应用自如了,所以首先打印出全部的1,然后,运用我们分析的杨辉三角的数的规律去打印1内部的数字,利用坐标的关系去打印即可。
c.代码详解:
int main() { int arr[10][10]={0}; int i=0; for(i=0;i<10;i++) { int j=0; for(j=0;j<i;j++) { if(i==j||j==0) { arr[i][j]=1; } if(i>=2&&j>=1) { arr[i][j]=arr[i-1][j-1]+arr[i-1][j]; } } } for(i=0;i<10;i++) { int j=0; for(j=0;j<i;j++) { printf("%3d",arr[i][j]); } printf("\n"); } return 0; }
注意细节:1.j不要超过i,否则就会把其他的0打印出来,就会出错。
2.注意一定要初始化,否则会打印出一堆数字的地址。
6.求字符串中的字母个数,数字个数,空格个数以及其他符号个数
a.题目:
编写一个函数void StatCharCount(char str[]),该函数接收一个字符串作为参数,请统计该字符串中字母、数字、空格和其他字符的个数,在main函数调用该函数,分别打印字母、数字、空格 和 其他字符的出现次数。
返回提示:一个函数只能返回一个值,此处的统计结果有4个,因此返回结果可以使用全局变量带出来。
b.思路分析:看到题目要求以及提示,我直接想到的ASCII值表,显而易见啊!这里就是利用ASCII表去进行判断操作,其次题目里提供了一种当函数只能返回一个值但我们需要四个值的时候的方式,即全局变量,当然我觉得定义一个结构体其实也可以。
c.代码详解:
int a = 0;//利用定义的全局变量把值带回来,很好的一个方法,积累一手 int b = 0; int c = 0; int d = 0; void StatCharCount(char srt[]) { int sz = strlen(srt); int i = 0; for (i = 0; i < sz; i++) { if (srt[i] == 32)//空格在ASCII中代表值为32 { c++; } if (srt[i] >= '0' && srt[i] <= '9')//0到9依次排列,在这里要注意是数字字符而不是数字 { b++; } if ((srt[i] >= 'A' && srt[i] <= 'Z') || (srt[i] >= 'a' && srt[i] <= 'z'))//字母同理 { a++; } else//剩下的就是其他符号了,直接else即可 { d++; } } } int main() { char str[] = { "zpw my man god!!!!1314" }; StatCharCount(str); printf("a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d); return 0; }