Ⅰ 算法怎么就这么难
广大码农同学们大多都有个共识,认为算法是个硬骨头,很难啃,悲剧的是啃完了还未必有用——除了面试的时候。实际工程中一般都是用现成的模块,一般只需了解算法的目的和时空复杂度即可。
不过话说回来,面试的时候面算法,包括面项目中几乎不大可能用到的算法,其实并不能说是毫无道理的。算法往往是对学习和理解能力的一块试金石,难的都能掌握,往往容易的事情不在话下。志于高者得于中。反之则不成立。另一方面,虽说教科书算法大多数都是那些即便用到也是直接拿模块用的,但不幸的是,我们这群搬砖头的有时候还非得做些发明家的事情:要么是得把算法当白盒加以改进以满足手头的特定需求;要么干脆就是要发明轮子。所以,虽说面试的算法本身未必用得到,但熟悉各种算法的人通常更可能熟悉算法的思想,从而更可能具备这里说的两种能力。
那么,为什么说算法很难呢?这个问题只有两种可能的原因:
算法本身就很难。也就是说,算法这个东西对于人类的大脑来说本身就是个困难的事儿。
讲得太烂。
下面会说明,算法之所以被绝大多数人认为很难,以上两个原因兼具。
我们说算法难的时候,有两种情况:一种是学算法难。第二种是设计算法难。对于前者,大多数人(至少我当年如此)学习算法几乎是在背算法,就跟背菜谱似的(“Cookbook”是深受广大码农喜爱的一类书),然而算法和菜谱的区别在于,算法包含的细节复杂度是菜谱的无数倍,算法的问题描述千变万化,逻辑过程百转千回,往往看得人愁肠百结,而相较之下任何菜谱涉及到的基本元素也就那么些(所以程序员肯定都具有成为好厨师的潜力:D)注意,即便你看了算法的证明,某种程度上还是“背”(为什么这么说,后面会详述)。我自己遇到新算法基本是会看证明的,但是发现没多久还是会忘掉,这是死记硬背的标准症状。如果你也啃过算法书,我相信很大可能性你会有同感:为什么当时明明懂了,但没多久就忘掉了呢?为什么当时明明非常理解其证明,但没过多久想要自己去证明时却发现怎么都没法补上证明中缺失的一环呢?
初中学习几何证明的时候,你会不会傻到去背一个定理的证明?不会。你只会背结论。为什么?一方面,因为证明过程包含大量的细节。另一方面,证明的过程环环相扣,往往只需要注意其中关键的一两步,便能够自行推导出来。算法逻辑描述就好比定理,算法的证明的过程就好比定理的证明过程。但不幸的是,与数学里面大量简洁的基本结论不同,算法这个“结论”可不是那么好背的,许多时候,算法本身的逻辑就几乎包含了与其证明过程等同的信息量,甚至算法逻辑本身就是证明过程(随便翻开一本经典的算法书,看几个经典的教科书算法,你会发现算法逻辑和算法证明的联系有多紧密)。于是我们又回到刚才那个问题:你会去背数学证明么?既然没人会傻到去背整个证明,又为什么要生硬地去背算法呢?
那么,不背就不背,去理解算法的证明如何?理解了算法的证明过程,便更有可能记住算法的逻辑细节,理解记忆嘛。然而,仍然不幸的是,绝大多数算法书在这方面做的实在糟糕,证明倒是给全了,逻辑也倒是挺严谨的,可是似乎没有作者能真正还原算法发明者本身如何得到算法以及算法证明的思维过程,按理说,证明的过程应该反映了这个思维过程,但是在下文关于霍夫曼编码的例子中你会看到,其实饱受赞誉的CLRS和《Algorithms》不仅没能还原这个过程,反而掩盖了这个过程。
必须说明的是,没有哪位作者是故意这样做的,但任何人在讲解一个自己已经理解了的东西的时候,往往会无意识地对自己的讲解进行“线性化”,例如证明题,如果你回忆一下高中做平面几何证明题的经历,就会意识到,其实证明的过程是一个充满了试错,联想,反推,特例,修改问题条件,穷举等等一干“非线性”思维的,混乱不堪的过程,而并不像写在课本上那样——引理1,引理2,定理1,定理2,一口气直到最终结论。这样的证明过程也许容易理解,但绝对不容易记忆。过几天你就会忘记其中一个或几个引理,其中的一步或几步关键的手法,然后当你想要回过头来自己试着去证明的时候,就会发现卡在某个关键的地方,为什么会这样?因为证明当中并没有告诉你为什么作者当时会想到证明算法需要那么一个引理或手法,所以,虽说看完证明之后,对算法这个结论而言你是知其所以然了,但对于算法的证明过程你却还没知其所以然。在我们大脑的记忆系统当中,新的知识必须要和既有的知识建立联系,才容易被回忆起来(《如何有效地学习与记忆》),联系越多,越容易回忆,而一个天外飞仙似地引理,和我们既有的知识没有半毛钱联系,没娘的孩子没人疼,自然容易被遗忘。(为什么还原思维过程如此困难呢?我曾经在知其所以然(一)里详述)
正因为绝大多数算法书上悲剧的算法证明过程,很多人发现证明本身也不好记,于是宁可选择直接记结论。当年我在数学系,考试会考证明过程,但似乎计算机系的考试考算法证明过程就是荒谬的?作为“工程”性质的程序设计,似乎更注重使用和结果。但是如果是你需要在项目中自己设计一个算法呢?这种时候最起码需要做的就是证明算法的正确性吧。我们面试的时候往往都会遇到一些算法设计问题,我总是会让应聘者去证明算法的正确性,因为即便是一个“看上去”正确的算法,真正需要证明起来往往发现并不是那么容易。
所以说,绝大多数算法书在作为培养算法设计者的角度来说是失败的,比数学教育更失败。大多数人学完了初中平面几何都会做证明题(数学书不会要求你记住几何所有的定理),但很多人看完了一本算法书还是一团浆糊,不会证明一些起码的算法,我们背了一坨又一坨结论,非但这些结论许多根本用不上,就连用上的那些也不会证明。为什么会出现这样的差异?因为数学教育的理想目的是为了让你成为能够发现新定理的科学家,而码农系的算法教育的目的却更现实,是为了让你成为能够使用算法做事情的工程师。然而,事情真的如此简单么?如果真是这样的话干脆连算法结论都不要背了,只要知道算法做的是什么事情,时空复杂度各是多少即可。
如果说以上提到的算法难度(讲解和记忆的难度)属于Accidental Complexity的话,算法的另一个难处便是Essential Complexity了:算法设计。还是拿数学证明来类比(如果你看过《Introction to Algorithms:A Creative Approach》就知道算法和数学证明是多么类似。),与单单只需证明相比,设计算法的难处在于,定理和证明都需要你去探索,尤其是前者——你需要去自行发现关键的那(几)个定理,跟证明已知结论相比(已经确定知道结论是正确的了,你只需要用逻辑来连接结论和条件),这件事情的复杂度往往又难上一个数量级。
一个有趣的事实是,算法的探索过程往往蕴含算法的证明过程,理想的算法书应该通过还原算法的探索过程,从而让读者不仅能够自行推导出证明过程,同时还能够具备探索新算法的能力。之所以这么说,皆因为我是个懒人,懒人总梦想学点东西能够实现以下两个目的:
一劳永逸:程序员都知道“一次编写到处运行”的好处,多省事啊。学了就忘,忘了又得学,翻来覆去浪费生命。为什么不能看了一遍就再也不会忘掉呢?到底是教的不好,还是学得不好?
事半功倍:事实上,程序员不仅讲究一次编写到处运行,更讲究“一次编写到处使用”(也就是俗称的“复用”)。如果学一个算法所得到的经验可以到处使用,学一当十,推而广之,时间的利用效率便会大大提高。究竟怎样学习,才能够使得经验的外推(extrapolate)效率达到最大呢?
想要做到这两点就必须尽量从知识树的“根节点”入手,虽然这是一个美梦,例如数学界寻找“根节点”的美梦由来已久(《跟波利亚学解题》的“一点历史”小节),但哥德尔一个证明就让美梦成了泡影(《永恒的金色对角线》));但是,这并不阻止我们去寻找更高层的节点——更具普适性的解题原则和方法。所以,理想的算法书或者算法讲解应该是从最具一般性的思维法则开始,顺理成章地推导出算法,这个过程应该尽量还原一个”普通人“思考的过程,而不是让人看了之后觉得”这怎么可能想到呢?
以本文上篇提到的霍夫曼编码为例,第一遍看霍夫曼编码的时候是在本科,只看了算法描述,觉得挺直观的,过了两年,忘了,因为不知道为什么要把两个节点的频率加在一起看做单个节点——一件事情不知道“为什么”就会记不牢,知道了“为什么”的话便给这件事情提供了必然性。不知道“为什么”这件事情便可此可彼,我们的大脑对于可此可彼的事情经常会弄混,它更容易记住有理有据的事情(从信息论的角度来说,一件必然的事情概率为1,信息量为0,而一件可此可彼的事情信息量则是大于0的)。第二遍看是在工作之后,终于知道要看证明了,拿出着名的《Algorithms》来看,边看边点头,觉得讲得真好,一看就理解了为什么要那样来构造最优编码树。可是没多久,又给忘了!这次忘了倒不是忘了要把两个节点的频率加起来算一个,而是忘了为什么要这么做,因为当时没有弄清霍夫曼为什么能够想到为什么应该那样来构造最优编码树。结果只知其一不知其二。
必须说明的是,如果只关心算法的结论(即算法逻辑),那么理解算法的证明就够了,光背算法逻辑难记住,理解了证明会容易记忆得多。但如果也想不忘算法的证明,那么不仅要理解证明,还要理解证明背后的思维,也就是为什么背后的为什么。后者一般很难在书和资料上找到,唯有自己多加揣摩。为什么要费这个神?只要不会忘记结论不就结了吗?取决于你想做什么,如果你想真正弄清算法设计背后的思想,不去揣摩算法原作者是怎么想出来的是不行的。
Ⅱ 算法难学么
真正的算法学习起来,存在一定的难度的,坚持很重要,毕竟里面的东西的学习,需要耐心去看不能只是三分钟的热度基本学不会,毕竟算法的学习需要注意力高度集中,不停的烧脑学习。不适合学习一段时间就轻易放弃的人,所以没点毅力根本就学不好算法,更加谈不上学习编程了。
以上资料仅供参考。
Ⅲ c语言高难度算法,菜鸟勿进! ^_^
//我做出来了。
//输入:A1,A3,A2,A8,A7,A6,A5,A4
//输出:A1,A2,A3,A4,A5,A6,A7,A8
//只是对输入的字串长度限制在100以内。
#include "stdio.h"
int main( )
{
char str1[100];
//输入字符串
printf("请输入字符串:");
scanf("%s",str1);
//对字符串分组
char str[50][3];
char *p=str1;
int i=0,j=0;
for(;*p!='\0';p++)
{
if(*p!=',')
{
str[i][j]=*p;
j++;
}
else
{
str[i][j]='\0';
i++;
j=0;
}
}
str[i][j]='\0';
i++;
j=0;
//对字串排序
for(j=0;j<i;j++)
for(int k=j+1;k<i;k++)
{
if(str[j][1]>str[k][1])
{
char temp;
temp=str[j][0];
str[j][0]=str[k][0];
str[k][0]=temp;
temp=str[j][1];
str[j][1]=str[k][1];
str[k][1]=temp;
}
}
//复制排序好的字串
p=str1;
for(j=0;j<i;j++)
{
*p=str[j][0];
p++;
*p=str[j][1];
p++;
if(j<i-1)
{
*p=',';
p++;
}
}
*p='\0';
//输出排序好的字串
printf("排序后的符串:%s",str1);
printf("\n");
}
Ⅳ 学算法很难么
这个不好说的,就看你自己的学习能力和接受能力了,你可以先找点算法的书籍看下,看看难度系数怎么样的。反正对于我来说是比较难的,当年学的不是很好。
Ⅳ 一种算法用硬件实现的难易程度主要看什么或者说用什么来衡量
我个人觉得要看这种算法和硬件的匹配度
举个简单的例子,cpu内部有做好的加法器有现成的加法指令,所以完成加法就很简单,也很快,如果你的算法有很多除法,但CPU内部又没有除法结构也没有相关指令,你完成除法这个算法就需要自己通过其他方式来完成,这就是难易度的体现。
Ⅵ 决策树算法和神经网络算法哪个难
不是很清楚题主所说的难具体指什么
如果题主指应用算法解决实际问题的话 决策树要简单一些 有很多封装的很好的decision tree的包,比如CART,C4.5等等 而神经网络(NN)一般有大量参数需要手工设置和调节
如果题主指算法推导的难度的话 两个差不多吧 决策树的分裂方法可能稍微简单一下 NN的话用BP或者SGD的话都需要用chain rule求导
Ⅶ 算法分析难不难
算法分析设计是很难的。要把离散数学、数据结构、编译原理学好,其实编译原理更难。
Ⅷ 转帖:算法好学吗——《大话数据结构》读者书评
om/?p=739作者:陈钢摸着键盘写这篇东西的直接动力是给程杰刚刚出版的大作《大话数据结构》写个书评,外加利用我这微乎其微的影响力做做广告怎么说程杰同学也送了我一本亲笔签名的繁体版《大话数据结构》。不过,今天早上看到了刘未鹏的新文章,知其所以然(三):为什么算法这么难?,我觉得光写书评不太爽,写点我学算法的失败经历吧,顺带说说程杰同学的这本新书。 说实话,本文的标题是个伪命题。算法是否好学,或者说是否容易学,完全取决于你的学习目标,是要应付下个月的考试,还是准备考个研究生,或者是想搞定二三流公司的笔试,还是想去微软当科学家当然,不排除有人的目标是图灵奖。不动脑子都能知道,只是应付考试的学习应该是难度最低的,真正在复杂的业务流程中合理的设计和应用高效的算法的难度无疑要高出一截,至于图灵奖我也不知道,那玩意太遥远。 目标的不同导致了所需的学习资料是完全不同的,《大话数据结构》的封底是这样描述它的目标读者的:《大话数据结构》适合学过一门编程语言的如下读者: 在读的大中专计算机专业学生; 想转行做开发的非科班人员; 想考计算机专业研究生的应届或在职人员; 工作后想重温数据结构和算法的程序员; 显然,从目标读者就能看出,这本书不是给高手看的。我曾经扮演过其中的一种角色,想考计算机专业研究生的应届或在职人员,不过我那时候读的是一本经典的教材,严蔚敏老师的《数据结构》(其实在《大话》前言中也提及了这本书)。因为所学的专业跟计算机搭界不多,所以在考研前所有的计算机知识来自于三门包罗万象却连点到即止就算不上的课程:计算机导论、计算机软件设计、计算机硬件设计。当时的学习方法就是刘未鹏说的背,不管算法和各种数据结构的来龙去脉,也无论能否理解,一律背下来。反正当时的目标就是考研究生。 但我也发现,本为考研究生而短期恶补的知识,应付一般的企业笔试和面试也勉强够了。考研复习其实挺枯燥的,每天重复几乎类似的生活。有天同学说,传说中的华为来学校宣讲。为了调剂一下生活,捏着一页纸的简历就跑去应聘软件开发职位。一轮笔试,几轮面试下来,凭着我两个月恶补的那点数据结构知识,我竟然全部通过了。体验完签约仪式注意,只是体验了一下,然后回到教室继续备考。 最后,考研的专业课也得了个还不错的成绩。从这方面看,算法、数据结构之类的东西学起来似乎并不难,短时间抱着死板的教材就能应付考试,应付企业的笔试面试。如果能读读《大话》这样通俗易懂的读物,达到这样的目的应该是更加容易。我当时真正的水平怎么样?啥都不会,动态规划都写不完整,分治法之类的东西就更不懂了。NP-complete理论?没听说过。光是背了几篇经典小说的人,看过小说背景介绍的人是写不出什么好东西的。必须要了解别人作品的前前后后方方面面,自己不停地写,不停地想,才有可能真的写出好东西。算法也是如此,弄清楚每个数据结构、算法的每个细节的缘由,才能设计出自己的好算法。但市面上能像刘未鹏的知其所以然(三):为什么算法这么难?这样解析算法的书是没有的。即使是刘未鹏写了几篇,要等他攒出一本完整的书,也需要漫长的等待。而且全书每个算法的解析是否都能到这个水平也是个疑问。 但如果搞计算机的人都停留在《大话》所要达到的水平,那无疑是一种悲哀。我学算法的经历之所以失败,正是因为如此。为了考试而啃完严蔚敏老师的《数据结构》和一两本考试参考书之后,我再也没有读完一本算法的书,也没有自己写过稍有难度的算法。所以,水平也就一直停留在看看文档,调调函数的水平上。 希望有人能以《大话》为起点,而不是以读完此书为终点;也期望程杰兄能创作出更高水平的佳作。 陈钢同学是我的朋友,在我写作时给予了我很多帮助。此评论写得相当客观,并没有夸大地说好话,而是强调了《大话数据结构》仅仅只是数据结构与算法学习的起步而已。我转帖出来,也是希望读者可以了解,算法要学好,可真不是几日之功。我们都需要不断努力!
Ⅸ 计算机算法有多难
不算太难,好好学就能学会,就是需要多复习,不然就忘了
Ⅹ 阅读、电影和音乐的推荐算法,哪一个更难做
“阅读、电影和音乐的推荐算法,哪一个更难做?为什么?”关于这一问题,小编从诸多网友的回复中为你筛选了最用心、最高赞的回答!快来看看吧~
来看看网名为“幸运的ZLT0502”的网友是怎么说的:
电影---音乐----阅读!从我的经验来看,阅读是最难做到的,其次是音乐,最简单的就是电影。当然,是在有很多数据的前提下。从几个领域的特点来看:1.电影的item数量相对较少,好的电影有很长的生命周期,加上电影社区的用户行为,视频网站或预订网站,都很好获得,所以特别适合合作过滤。即使这不是一部大热门电影,你也可以根据导演、类型、明星等制作内容。这些都是结构化的信息,所以没有难度。音乐的item比电影要多一些,生命周期也非常不同,但它也可以用于基于用户行为的协同过滤。该算法如何表达和更新用户的兴趣?如何根据兴趣标签计算推荐结果?至少我没有看到特别成功的推荐阅读应用程序。算法上,都各有难度,但阅读类的,由于分类太多,在算法上自然要更加复杂。
来看看网名为“派网友”的网友是怎么说的:
个人认为无论是基于用户行为(协同过滤),还是基于内容相似度的推荐算法,难度从高到底都依次是:音乐-阅读-电影。
对于ID为“楼船吹笛雨潇潇”网友的精彩回答,大家纷纷点赞支持,他是这么说的:
我觉得是各有所难,并不能说哪个难,哪个容易。推荐的成功率:公共决策对推荐的影响:判断价值的建议:三者各有难度,但是个人在长期的习惯中可以对其中一种或者多种情景中加以选择和实践,但这也不是一蹴而就的事情,慢慢来吧。
你赞同哪位网友的观点呢?