C语言学习笔记
C语言也学习了一个多月了,从最开始的什么都不会到现在能简单写一些简单代码,感觉收获很多,也来总结一下最近遇到的一些题目吧。
数组的删除
[问题描述]
有5个整型数据存储在数组中,再输入一个数值key,删除数组中第1个等于key的元素,并将剩余的4个数据输出。如果key不是数组中的元素,则显示not found。
分析
本题中查找第一个重复元素并删除它,显然我们不能直接删除数组中的某个元素,但可以移动它,把目标移动到数组末尾,最后的输出不输出它即可。
代码
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
| #include<stdio.h> int main() { int a[5],k,i,j,temp,index=0; for(i=0;i<5;i++) { scanf("%d",&a[i]); } scanf("%d",&k); for(i=0;i<5;i++) { if(a[i]==k) { for(j=i;j<5;j++) { a[j]=a[j+1]; index=-1; } break; } } if(index==0) printf("not found"); else for(i=0;i<4;i++) printf("%d ",a[i]); return 0; }
|
斐波拉契数列(数组)
[问题描述]
如果1对兔子第三月开始每月能生一对小兔子,而每对小兔子在它出生后的第3个月开始,又能生1对小兔子,假定在不发生死亡的情况下,n个月后有多少对兔子? n值通过键盘输入。
[输入输出示例]
输出在一行,每个数字占6位宽度。
分析
根据问题描述可知斐波拉契数列a1=a2=1,a3=2 a4=3 a5=5 a6=8……
经观察易得,从第三项起,每一项是前两项之和,即a3=a2+a1,a4=a3+a2,a5=a4+a3,根据这个规律即可用数组写出本题。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include<stdio.h> int main() { int n,i; scanf("%d",&n); int a[100]; a[0]=a[1]=1;
{ for(i=2; i<n; i++) { a[i]=a[i-2]+a[i-1]; } for(i=0;i<n;i++) { printf("%6d ",a[i]); } } return 0; }
|
查找数组的最大值与最小值
分析
想要找出数组中最大值最小值我们可以先将max,min赋值成任意数组内一个数,然后进入循环开始比较每一项,如果任意一项大于等于max,则重新将此时的数赋值给max,min同理直到比较完数组最后一个数时退出循环。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<stdio.h> int main() { int a[10],i,max,min; for(i=0;i<10;i++) scanf("%d",&a[i]); max=min=a[0]; for(i=0;i<10;i++) { if(max<=a[i]) max=a[i]; if(min>=a[i]) min=a[i]; } printf("max=%d\nmin=%d",max,min) return 0; }
|
约瑟夫问题
[问题描述]
模拟这个游戏。有n个人围成一圈,从第一个人开始沿顺时针方向报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号的那个人?
分析
本题需要一个”计数”变量来计数,我们考虑用计数到3时把此时的a[i]赋值成0,下次计数时跳过0,不断循环直到数组中只有一个非零数时,该数的下标就是我们需要的。
代码
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 32 33 34
| #include<stdio.h> int main() { int n,a[100],i,count=0,x; scanf("%d",&n); x=n; for(i=1; i<=n; i++) { a[i]=i; } while(x>1) { for(i=1; i<=n; i++) {
if(a[i]!=0) count++; if(count==3) { a[i]=0; count=0; x--; } }
} for(i=1; i<=n; i++) { if(a[i]!=0) printf("%d",i); } return 0; }
|
选择排序法(升序)
交换排序发顾名思义就是不断交换从而排序
分析
若干个数,若想排序我们可以只考虑相邻两个数的大小,如果所有相邻的俩个数都是小数在前大数在后那么整个数组都是按照升序排列了。
代码
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
| #include<stdio.h> int main() { int a[10],i,j,temp; for(i=0;i<10;i++) { scanf("%d",&a[i]); } for(i=0;i<10;i++) { for(j=i+1;j<10;j++) { if(a[i]>a[j]) { temp=a[j]; a[j]=a[i]; a[i]=temp; } } } for(i=0;i<10;i++) { printf("%d ",a[i]); } return 0; }
|
冒泡排序法
待补充
快速排序法
待补充
杨辉三角(二维数组)
杨辉三角在我们高中时已经学习过,我们都知道它是个类金字塔型,但为了简单化我们将其变形为等腰直角三角形,此时的图形如下图所示。
分析
观察可知,这个等腰直角三角形的竖直的腰和斜边都是1,剩下的数总是它上方的及上方左边数之和,根据次规律考虑使用二维数组来进行编程。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include<stdio.h> int main() { int a[100][100],n,i,j; scanf("%d",&n); for(i=0;i<n;i++) { for(j=0;j<=i;j++) { if(i==j||j==0) a[i][j]=1; else a[i][j]=a[i-1][j]+a[i-1][j-1]; } } for(i=0;i<n;i++) { for(j=0;j<=i;j++) printf("%4d",a[i][j]); printf("\n"); } return 0; }
|
九九乘法表
小学我们一定背过九九乘法表,我们用已学知识将其打印出来也是件非常有意思的事情。
分析
观察上图可知竖列从1X1一直到1x9,横列从1xa一直到aXa.
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<stdio.h> int main() { int a[9],i,j,s,n; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { s=i*j; printf("%d*%d=%d",j,i,s); if(j!=i) printf(" "); } if(i!=n) printf("\n"); } }
|
顺序查找法
在含有10个数的数列{11,22,5,16,8,3,19,20,23,52}中查找key值,若找到key则输出其在数组中对应的下标,否则输出not found
分析
顺序查找顾名思义就是按照顺序挨个查找数组中的每一个元素,直到找到时输出即可,若找完整个数组还没找到就是not found。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<stdio.h> int main() { int a[10]={11,22,5,16,8,3,19,20,23,52},i,k,index=-1; scanf("%d",&k); for(i=0;i<10;i++) { if(a[i]==k) { printf("%d",i); index=0; break; } } if(index!=0) printf("not found"); return 0; }
|
二分(折半)查找法
接着我们学习了效率更高的二分(折半)查找法,假如有1,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,56这么一组数,我们尝试使用该方法查找。注意,二分查找只能用于有序的数组进行查找。这里用升序数组举例,降序也是一个道理。
二分查找原理用文字很难讲清楚,我引用网络上的一张动图方便理解,也可以对比一下顺序查找和二分查找效率。
图片来源于水印,仅用于学习交流,不用于商业用途,如侵权请联系我删除。
分析
按照动图为例查找37;刚开始不确定37在哪,所以整个数组都是查找区,low=0,high=16,mid=8;因为8对应的a[8]=23<37,所以37在a[8]右边,此时low=mid+1=9,查找区由整个数组变为a[9]-a[16];mid=12*(mid为整型)*,a[12]=41>37;所以high变成了11;查找区也变成了a[9]-a[11];mid=10;a[10]=31<37,low=11,mid=11,a[11]=37,,于是我们就找到了查找数37.处于数组11号。
代码
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
| #include<stdio.h> int main() { int a[17]= {1,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,56},k,low,mid,high,index; scanf("%d",&k); low = 0; high = 15; index = -1; while(low<=high) { mid=(low+high) / 2; if (a[mid]==k) { index = mid; break; } if (a[mid]>k) high = mid - 1; if (a[mid]<k) low = mid + 1; } if (index!=-1) printf("%d",mid); else printf("not found"); return 0;
}
|