从石头剪刀布浅谈算法的做用

       刚开始学习C语言的时候,经常听到前辈说,C语言的核心就是算法。可是对于小白来讲,经常一脸懵逼,搞不懂啥叫算法?算法有什么用?个人if-else语句照样能够走天下。可是做为小白来讲虽然不懂可是也不敢问,只能把这个疑问消灭在萌芽状态。算法

  那么算法到底意味着什么?为何算法如此重要,那么今天就经过一个简单的石头剪刀布的游戏来粗略的谈一下算法的造成缘由和做用?markdown

  好比如今要写一个两我的玩石头剪刀布的程序,要如何实现。对于小白来讲,这简单if-else语句就搞定了。学习

代码以下:优化

if(本身==石头 && 对方==石头) 平局;
else if(本身==石头 && 对方==剪刀) 本身赢;
else if(本身==石头 && 对方==布) 对方赢;

if(本身==剪刀 && 对方==石头) 对方赢;
else if(本身==剪刀 && 对方==剪刀) 平局;
else if(本身==剪刀 && 对方==布) 本身赢;

if(本身==布 && 对方==石头) 本身赢;
else if(本身==布 && 对方==剪刀) 对方赢;
else if(本身==布 && 对方==布) 平局;
复制代码

固然这个代码还能够优化一下spa

if(本身==石头)
{
    if(对方==石头) 平局;
    else if(对方==剪刀) 本身赢;
    else if(对方==布) 对方赢;
}

if(本身==剪刀)
{
    if(对方==石头) 对方赢;
    else if(对方==剪刀) 平局;
    else if(对方==布) 本身赢;
}

if(本身==布)
{
    if(对方==石头) 本身赢;
    else if(对方==剪刀) 对方赢;
    else if(对方==布) 平局;
}
复制代码

    这个结构看起来更加清晰明了,也可使用switch语句来实现,无论用什么语句来实现,这里核心思想就是将全部的状况列出来,而后逐一去判断,没有任何算法可言。若是按照这个思路去实现,那么假如要比较的是几十种状况,难道还能逐一去列举判断吗?那几千种几万种比较呢?光列举出全部的状况估计都要累死了。code

    那么这个时候就须要用一个方法来抽象这种状况,让程序判断起来更加方便。逻辑上更容易实现。石头剪刀布的核心相似于比较大小,那么能不能将石头剪刀布转换为数字大小的比较。orm

   这里假设 石头 = 3  剪刀 = 2 布 = 1 ,而后将石头剪刀布的逻辑转换为 数字  石头 >  剪刀  对应 3 > 2,  剪刀 > 布 对应  2 > 1, 布 > 石头 对应 1 > 3, 显然前两个逻辑成立,最后一个逻辑不成立,游戏

那么就不能直接经过比较大小来判断,经过观察发现,凡是逻辑成立的两个数字之间相差1,最后一个逻辑不成立,数字之间相差2。那么是否能够将比较大小转换为数学的减法运算。数学

当本身的数字 - 对方的数字 结果等于1时,本身获胜。结果等于2时,对方获胜,结果等于0时,平局。这样分析以后貌似能够实现。那么将全部的状况转换为用减法来实现时时代码逻辑以下:it

石头 = 3  剪刀 = 2 布 = 1 

if(本身==石头 && 对方==石头) 平局;          对应算式为 3-3 = 0
else if(本身==石头 && 对方==剪刀) 本身赢;    对应算式为 3-1 = 1
else if(本身==石头 && 对方==布) 对方赢;      对应算式为 3-1 = 2

if(本身==剪刀 && 对方==石头) 对方赢;        对应算式为 2-3 = -1
else if(本身==剪刀 && 对方==剪刀) 平局;      对应算式为 2-2 = 0
else if(本身==剪刀 && 对方==布) 本身赢;      对应算式为 2-1 = 1

if(本身==布 && 对方==石头) 本身赢;         对应算式为 1-3 = -2
else if(本身==布 && 对方==剪刀) 对方赢;     对应算式为 1-2 = -1
else if(本身==布 && 对方==布) 平局;        对应算式为 1-1 = 0
复制代码

经过对比算式的结果能够发现   当本身 - 对方的结果等于0时为平局,本身 - 对方的结果为1或者-2时 本身赢。当本身 - 对方的结果为2或者-1 时对方的赢。

那个根据这个就能够将上面的算法抽象为3类,本身赢,平局,对方赢。这样代码实现起来就更加简洁了,实现方法以下

/* 石头 = 3  剪刀 = 2 布 = 1 */

结果 =  本身 - 对方;

if(结果 == 0)  平局;
else if(结果 == 1 || 结果 == -2) 本身赢;
else if(结果 == -1 || 结果 == 2) 对方赢 ;
复制代码

这样直接经过3条语句就直接实现了石头剪刀布的逻辑判断,并且程序写起来更加的简洁,逻辑更加清晰。可见在代码逻辑实现的过程当中有了算法的加持,程序发生了质的变化。

一个简单的例子就能够看出算法在程序中举足轻重的做用,因此说写代码不只仅上是逻辑上把功能实现了就能够了,但实现功能的同时,还须要考虑效率的问题。

下面在举一个简单的例子来演示一下算法的应用。

      这里有15瓶水,其中有1瓶是剧毒,小白鼠只要喝上一滴,过一天后就会死亡,那么如何用最少的小白鼠,在最短的时间内找出哪一个瓶子里面有毒药?

      直接能够想到的办法就是找15只小白鼠,一只小白鼠喝对应编号的一瓶水就行。这种方法虽然最简单,可是浪费的小白鼠倒是最多的。确定不是最好的办法。可让一个小白鼠喝好几个瓶子的水,而后经过交叉排除的方法筛选出来那个瓶子有毒。这个能够经过二进制的思惟来实现。

     首先将这15个瓶子标上号码,从1到15,而后将这些数字转换为二进制。

                                   

能够看到15个瓶子,经过二进制数表示的话,须要4位,那么1只小白鼠表明1位的话,用4个小白鼠就能够表示1---15,顺着这个思路就能够经过一个小白鼠喝好几瓶混合的水,来筛选出有毒的那瓶水。

将15瓶水分为4组,第一组黄色的就是二进制数最低位为1的编号,也就是将二进制字最右边那个数字为1对应的那瓶水混合在一块儿,而后将混合后的水给第1只小白鼠喝。

至关于第一只小白鼠喝的是一、三、五、七、九、十一、1三、15这几个编号混合起来的水,按照一样的方法,将二进制数字右边第二位为1的水混合起来,给第二只小白鼠喝。

至关于第二只小白鼠喝的是二、三、六、七、十、十一、1四、15这几个编号混合起来的水,按照一样的方法,将二进制数字左边第二位为1的水混合起来,给第三只小白鼠喝。

至关于第三只小白鼠喝的是四、五、六、七、十二、1三、1四、15这几个编号混合起来的水,按照一样的方法,将二进制数字最左边为1的水混合起来,给第四只小白鼠喝。

至关于第四只小白鼠喝的是八、九、十、十一、十二、1三、1四、15这几个编号混合起来的水。

第一天将这些混合起来的水,分别给四只小白鼠喝,而后次日观察结果就能够知道哪瓶水有毒了?

假如次日,第一只和第三只小白鼠死了,说明对应的二进制数字第一位和第三位是1,对应的二进制数字就是 0101,这样就能够根据二进制数直接算出来有毒的是5号瓶。

假如次日,一、三、4只小白鼠死了,说明对应的二进制数字就是1101,那么瓶子对应的编号就是13号。

这样用4只小白鼠,在次日就能够找出有毒的那瓶水了。

经过转换一个思惟,用另外一种方法去解决问题,就能够轻松的将复杂的问题简单化,能够看出一个好多算法在实际应用中能够起到一两拨千金的做用。

经过上面的两个简单的例子,我想如今应该能够明白了,在程序中为何要研究算法,算法为何对于程序来讲这么重要了! 

相关文章
相关标签/搜索