Python实战 - 小试牛刀

背景

 

如果说PHP是世界上最美丽的语言,那么python一定是最简单,最强大,最容易的语言!重点是,这两门语言我都不懂!随着人工智能领域的风生水起,python的热度也是持续飙升,作为当下最热门的语言,怎么能不让人心动呢!

 

趁着过年这段时间,补充了一下python相关的基础知识,可以说是简单的入门了,如果有一点代码基础,入门python可以说是非常容易,但是,并非入门了python就意味着你可以拿着简历到处招摇撞骗了,入门虽然容易,但是还需要很多项目实战,类库的学习沉淀,你才可以在python的世界里面风风火火玩起来!

 

早两天看到了这样一道推理题,可以称得上是变态。题目如下:

Python实战 - 小试牛刀_第1张图片

第一题就足够虎住大部分人,仔细分析,这些题目有一个特点,信息量大,计算量大。这种任务,给计算机来做事最合适不过的了!那就拿python来练练手吧!

 

项目分析

 

任务共分为10道题,有10个答案,每道题之间有一定的联系,而且关系也比较复杂,但比较明确。方案分为两种:

  • 模拟法:即模拟人的解题行为,找到10题中的突破口,尝试推出下一题,并以此为跳板,推出下一题,一旦出错,从头开始尝试,直到推出所有答案

  • 穷举法:这是一种非常规的解题方法,目的是利用计算机的计算优势,枚举可能的所有答案组合,逐个验证每题的正确性,直到所有题目都验证通过。

很显然,穷举法的复杂度要明显低于模拟法,但是执行时间要远高于模拟法。但模拟法的业务复杂度较穷举法要高很多,开发难度较大。考虑到本题的特性,10道题,每题4个选项,复杂度最大为4的10次方共计1,048,576次,对于计算机来说,最大执行时间可以控制在10分钟之内。

 

设计

 

本次联系共需要以下三个模块,结构如下图:

 

  • 数据器 - 用来组织生成各道题的答案组合

  • 过滤器 - 在对数据进行验证之前,进行必要的处理

  • 验证器 - 验证每组答案的正确性

 

数据构造

 

数据器完成了数据的管理功能,目的是把10道题和ABCD这4个选项进行一次排列组合,共计4^10=1,048,576个,我们采用了类进制法来进行全排列的处理。即一个10位的序列,从AAAAAAAAAA开始,到DDDDDDDDDD结束,从第一位开始每次加1,每位逢D+1进一位,本位变A,则可以动态生成全排列序列。由于要进行加1运算,因此我们这里进行一些简单的编码,即将ABCD分别用数字1234表示,方便后续的算术运算,代码如下:

def increase(index):

    if(index == 10):

        return False

    r[index] += 1

    if(r[index] == 5):

        r[index] = 1

        return increase(index+1)

    returnTrue

当然,我们也会直观的想到先将所有的数据都先生成,存储起来,最开始我也是这么做的,直观的使用list存储了结果,最终内存不够了,而且生成这部分数据本身就很慢,再仔细分析,虽然我们的时间复杂度为4^10,但是,我们的最终答案一定不会到DDDDDDDDDD,所以,实际执行时间肯定要小于这个时间,因此,如果加入这种处理之后,实际执行时间必定大于最大执行时间,因此这种方案最终被优化掉了。生成数据采用的是完全不同的另外一种思路,有兴趣可以参考:

rlist = []

def createResult():

    for i in range(10):

        if(len(rlist) == 0):

            ro = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

            for j in range(4):

                ro = copy.deepcopy(ro)

                ro[i] = j+1

                rlist.append(ro)

        else:

            for ro in rlist:

                for j in range(4):

                    ro = copy.deepcopy(ro)

                    if(ro[i] == j+1):

                        continue

                    ro[i] = j+1

                    rlist.append(ro)

    return rlist

上例中的rlist换成文件读取写入效果可能会好点,由于是遗弃代码,这里不再详细讨论。

 

数据存储

 

不得不承认,python中目前感觉最好用的数据格式莫过于list了,无类型加上索引操作,万物皆对象的想法,真的是让list变得无所不能!我们关于10道题的答案建立了一个长度为10的列表来存储答案组,后续所有的验证即更新全部都在这个列表中进行,在各个模块之间起到桥梁的作用。

 

过滤器

 

过滤器在本次项目中并非必选项,加这个模块只是为了代码的结构清晰,功能明确。我们针对不同的题目可以设置不同的过滤器,如第三题,我们要验证每个选项之前,我们需要先确定,选项之间的关系,这里我们设置一个过滤器,免得第三题的验证器内容过于臃肿,代码如下:

def q3_1(index):

    indexlist = [2,5,1,3]

    for i in indexlist:

        if(index == i):

            continue

        elif(r[index] ==  r[i]):

            return False

    return True

验证器

验证器的目的为验证生成的答案是否全部都为正确答案,他的功能是根据不同的题目不同的,因此,必须为每一道题设置一个验证器,但也有例外,比如第一题,无论我们的答案是什么,这道题永远都是对的,因此,第一题不需要验证器。我们以第二题为例,先看代码:

def q2():

    if(r[1] == 1 and r[4] == 3):

        return True

    elif(r[1] == 2 and r[4] == 4):

        return True

    elif(r[1] == 3 and r[4] == 1):

        return True

    elif(r[1] == 4 and r[4] == 2):

        returnTrue

    else:

        return False

第二题的答案的意思大概是这样的:如果第二题的答案是A(即r[1]=1)时,第五题的答案为C(即r[4]=3),如果如果第二题的答案是B(即r[1]=2)时,第五题的答案为D(即r[4]=4),以此类推。故当我们可以通过判断第二题与第五题的答案关系来验证第二题的答案是否正确,如果有一项不满足,就验证失败。即答案错误

 

后记

 

到这里,我们的这次实战也就告一段落了。通过本次实战,巩固了这段时间学习的大部分知识,同时也发现了很多python的优点,感触良多:

 

  • python更像是为解决问题设计的

大部分程序语言都是开发者根据使用者提出的需求来完成编码,交付项目,然后让使用者使用这套工具来完成他们的任务,任何一段代码,如果不使用几次,我们总感觉缺少点什么。但是在使用python时完全没有这样的感觉,哪怕是删掉了,重新写一套,也很快很容易。

  • 在这个各种平台,开源类库横行的年代,基本功还是要扎实 

别人给你的只能是锅,铲子,食物和调料。而如何做出美味的饭菜,还得靠你自己去搭配。编程思想,实现方案才是各种编程语言通用的东西,而这些也是一个IT从业人员最宝贵的财富,在遇到问题的时候,多一套方案,你就离成功更近一步!

 

总之,代码的世界就是要多练多练再多练,多想多想再多想!同时也欢迎大家关注我的微信公众号:毛毛虫的烂笔头,一起交流,一起成长!

Python实战 - 小试牛刀_第2张图片

 

转载于:https://www.cnblogs.com/kolamu/p/8520574.html

你可能感兴趣的:(Python实战 - 小试牛刀)