本以为在看完了C语言的基础视频后,入学测试便可信手可得。不过拿到手试题后,接踵而来的问题不是C各种函数,循环,数据,结构体的用法。可是它们综合在一起外加上算法后,便很难了。程序员最重要的一点是思想,要不一直敲打无意义的代码成,代码会变得毫无含金量。有些看似实质性的问题,有的人能一行代码解决,有的人则需要花上几百行,并且性能优化上还没有上一个一行代码的来的好。思想,数据结构,解决问题的思路和对数学的理解,这些都是学计算机需要掌握的。哪怕是后来的OC面向对象,重要的也是思想,办什么事,就去相应的类里找。解决这件事的办法,这些思想综合起来才能进行独立的开发和综合的对于技能的掌握。
于是乎目前的任务,我决定就是完成视频内容,虽然看了忘忘了看,但是还是要“坚毅”的走完报名流程。然后如果有幸融入“黑马”,我重新巩固自己算法这方面的不足,可以买一本数据结构,买一本OC入门详解,或者网上下载C经典例题100道拿来做做。代码这东西,怎么看都是别人的,只有自己想的多了,才是自己的。我缺少的,恰恰是实践和付诸实践的时间。不过虽然C算法“临幸”的较少,不过在少数的我碰到的例题中,也学到了不少思维。
下面这两个算法是C中比较经典的解决问题实例。特记录下来,以后若有指的分析的,必也会纳入博客,成为自己知识的一部分。
(一)冒泡排序:
冒泡排序(Bubble Sort)是一种能力较为底下的排序方法,用于升序或者降序排列一个数组中的数。不过因为是两两比较,依次循环,所以性能较为低下,再次旨在提供一种思想。因为C语言关乎排序的算法非常之多,这也算一个经典思想了。
排序为两两进行比较,第一轮会把最大值沉到最后一位,然后第二轮遍历只需遍历前面的数组进行排序,找出第二大的即可。
代码实现:
#include <stdio.h>
void BubbleSort(int array[],int n);
int main()
{
int array[] = {10,99,88,77,43,422,10,11};
BubbleSort(array, sizeof(array)/sizeof(int));
for (int a =0;a<sizeof(array)/sizeof(int);a++)
{
printf("%d,",array[a]);
}
}
// 冒泡排序算法需要传入整个数组和数组数组元素个数
void BubbleSort(int array[],int n)
{
int temp = 0;
//外圈循环,用于计算整个遍历的次数,10个元素,那么就要遍历9次
for (int i =0;i<n-1;i++)
{
//内圈循环,用于计算每一次遍历应进行的比较数,第一次外循环已经把最大值沉淀到最底部了
for (int j =0;j<n-1-i;j++)
{
if (array[j]>array[j+1])
{
// 交换数字(也可以不用temp)
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
下面是我遇到的入学测试题:(记忆犹新)
/*从键盘输入一大堆字符串,统计A、B、C、D的出现次数,最后出现次数由高到低输出字母和出现次数。(C语言)
*/
#include <stdio.h>
int main()
{
// statistics函数声明,实现输出功能
void statistics(char *str);
//从键盘输入一串字符串,并传入name数组
char name[1000];
printf("请输入一串字符串\n");
scanf("%s",name);
// statistics函数调用
statistics(name);
return 0;
}
// statistics函数定义
void statistics(char *str)
{
// 定义四个int类型用来存储A,B,C,D出现的次数
int atimes=0;
int btimes=0;
int ctimes=0;
int dtimes=0;
//循环遍历整个字符串,取出ABCD的个数
for (int i=0;str[i]!=0;i++)
{
if (str[i] =='A')
{
atimes++;
}else if (str[i] =='B')
{
btimes++;
}else if (str[i] =='C')
{
ctimes++;
}else if (str[i] =='D')
{
dtimes++;
}
}
//此时取出刚才ABCD出现的次数,并且按照顺序依次放入到ArraYTimes数组中
int ArrayTimes[4] ={atimes,btimes,ctimes,dtimes};
// 定义一个char类型数组依次存放字符'A','B','C','D'
char num[4] = {'A','B','C','D'};
//解题思路:现在'A','B','C','D'和其对应的数值依次储存在两个数组中,可是'A','B','C','D'的数值排序是乱序,下面要进行ArrayTimes[]数组的降序排列,并且num[]数组也相应的对应修改。以达到顺序是降序,数字和'A','B','C','D'还是一一对应。百度方法后,查找到一个两两比较,交换空间的方法,叫做“冒泡排序”
// (sizeof(ArrayTimes)/sizeof(int))-1计算出数组内元素个数,根据个数判断循环应为n-1
for (int i =0; i<(sizeof(ArrayTimes)/sizeof(int))-1; i++)
{
// 判断循环,n-1-j
for(int j =0;j<(sizeof(ArrayTimes)/sizeof(int))-1-i;j++)
{
//如果前面的值小于后面的,则交换他们的位置,改变排序
if (ArrayTimes[j] < ArrayTimes[j+1])
{
// 交换ArrayTimes[j]和ArrayTimes[j+1]的值
int changeArray = ArrayTimes[j];
ArrayTimes[j] = ArrayTimes[j+1];
ArrayTimes[j+1] = changeArray;
// 由于ArrayTimes数组和num数组的出现次数和'A','B','C','D'是依次对应的,所以同样的方法交换num数组的值
char changeNum=num[j];
num[j]=num[j+1];
num[j+1]=changeNum;
}
}
} //到此,冒泡排序执行完毕,此时ArrayTimes[]应该是降序排列,并且对应的num[]里面的字符也一一对应
//遍历循环输出出现次数,并打印出来
for (int s=0;s<(sizeof(ArrayTimes)/sizeof(int));s++)
{
printf("%c出现了%d次\n",num[s],ArrayTimes[s]);
}
}
(二)约瑟夫循环
约瑟夫循环是一个数学应用问题,在C语言中难想到的就是如何组成一个圆,让人数越来越少的新环继续循环起来。题目如下:
/* 耶稣有15个门徒,其中有一个就是出卖耶稣的叛徒,请用排除法找出这位叛徒:15人围坐一圈,从第一个开始报号:1,2,3,1,2,3……,凡是报到“3”就退出圈子,最后留在圈内的人就是出卖耶稣的叛徒,请找出它原来的序号。(C语言)
*/
#include <stdio.h>
int main()
{
//首先定义一个数组用来存放15个人,并依次赋值
int person[15]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
// 定义人数num=15,喊到num=0,i用于遍历整个person[15]数组
int dao = 0;
int i = 0;
int num = 15;
//循环思路:当喊到3,这个人就剔除,这个人对应的位置值为0,当执行一圈后,终点15处定义新的起点,重新从person[0]处再次喊到,直到循环到只剩一个人
while (num>1)
{
// person[i]初始赋值成功后,其!=0表示此处有人,那么喊到加1
if (person[i] !=0)
{
dao ++;
}
//如果喊到等于3,那么重新从1喊,并且此处的人剔除(表现为数组中这个位置值为0,总人数减1
if (3 == dao)
{
dao = 0;
person[i] = 0;
num -= 1;
}
//遍历下一个人,用于进入下一次循环判定时候喊到
i++;
//经由黑马论坛传授精妙“圈”解法,巧妙的把15和0重叠,实现了围坐一圈的效果
if (15 ==i)
{
i =0;
}
}
//循环遍历重新赋值后的person[i],其值不得0得那个人就是最后剩下的
for (int a =0;a<15;a++)
{
if (person[a] !=0)
{
printf("15个人中叛徒是:%d\n",person[a]);
}
}
return 0;
}
if (15 ==i)
{
i =0;
}
i的定义是为了给15个人编号,当0-14全部while循环完毕,说明15个人完全喊了一圈了,数组中是没有i= 15,16的。所以当全部喊完重新开始时,下一个人15的编号,的数组改成0,这样就恰巧模拟了他们做一圈的形态。i只是用来剔除人的,当person[i]等于0后,下次吼到就不会再顾及这个人,因为已经被剔除了。所以i在 if判定外。每一次循环都需要+1遍历每一人。整体来说,目前只能弄懂这些比较精妙的解法,如果遇到新的问题或者类似的问题,即便不能解,也许也会有一定的思路。算法多靠的是思考。和积累。对于没怎么接触过数据结构,所以感觉略难。