关于算法:基本编程/算法概念

Basic programming/algorithmic concepts

我准备(和其他程序员一起)在我的高中开一家编程和算法俱乐部。选择的语言是C++——很抱歉,我不能改变这一点。我们可以假设学生在上述主题上几乎没有经验。

你认为我应该关注的最基本的概念是什么?

我知道教我已经很明显的东西不是一件容易的事情。我意识到第一次会议应该给予极大的关注——不要把学生吓跑——所以我问你。

编辑:我注意到程序员和初学者之间的主要区别可能是"程序员的思维方式"——我的意思是,概念化问题,如,你知道的,算法。我知道这只是一个实践问题,但是你知道有什么样的练习/概念/事情可以刺激这方面的发展吗?


让编程变得有趣!

可能要讨论的事情是你的俱乐部可以自己举办或者可以在当地参加的节目比赛。我参加的是大学(ACM)级别的编程比赛,我知道他们的水平也较低。

这类活动真的能激发出一些竞争精神,使俱乐部成员更亲近。

事情也不一定总是与编程有关。也许建议举办一个局域网聚会,在那里你玩游戏,讨论编程等也是一个好主意。

就要讨论的与编程/算法相关的实际主题而言,我建议作为一个小组,尝试在本次编程竞争初级读物"编程挑战"中的一些编程问题:Amazon Link

它们从相当基本的编程问题开始,慢慢地发展为需要各种数据结构的问题,如:

  • 堆栈
  • 队列
  • 辞典

大多数问题是在C++中给出的。

最后,他们发展到更高级的问题,涉及图遍历和流行的图算法(dijkstra's等),组合问题等。每个问题都是有趣的,以类似"故事"的小格式给出。不过,请注意,其中有些很难做到!

编辑:披萨和苏打水在让人们参加你的俱乐部会议时也不会有任何伤害。我们的ACM俱乐部每个会议都有披萨(每月一次)。即使我们大多数人仍然会出现,这是一个很好的破冰。特别是对于新的俱乐部或会员。


把它拆下来

对我来说,编程的独特之处在于需要将任务分解成足够小的步骤,以供计算机使用。这因语言而异,但要想数到100就必须编写一个"for循环",这一事实需要习惯。

"自上而下"的方法可能有助于这个概念。首先为程序创建一个主函数,如

1
filterItemsByCriteria();

您不知道这将如何工作,因此您将其分解为以下步骤:

(注:我不知道C++,所以这只是一个通用的例子)

1
2
3
4
5
filterItemsByCritera() {
  makeCriteriaList();
  lookAtItems();
  removeNonMatchingItems();
}

然后你把每一个都进一步分解。很快你就可以定义所有的小步骤,它需要做你的标准列表,等等。当所有的小功能工作时,大功能将工作。

这有点像孩子们玩的游戏,他们一直在问"为什么?"在你说了所有的话之后,除了你必须一直问"怎么做?"


链表-一个经典的面试问题,有充分的理由。


我会尝试使用C子集,而不是从OO开始。这可以在他们了解一些基础知识之后介绍。


问候语!

我认为你在强制使用一种特定的语言、研究特定的主题和课程方面已经领先了很多。听起来你(和一些响应者)把"建议编程俱乐部"和"领导编程课"混淆了。它们是非常不同的东西。

我会让团队团结起来,团队应该决定他们到底想从俱乐部得到什么。本质上,为俱乐部制定一个"章程"。然后(并且只有在那时)你才能做出决定,例如首选语言/平台、会面频率、会议上会发生什么等。

可能会发现,最好的方法是"调查",在那里探索不同的语言/平台。或者,最好的方法可能是"主题化"的方法,即定期改变主题(如图书俱乐部)(本月是指针,下个月是排序,下面是递归等),然后用各种语言进行示例和讨论。

作为旁白,我会考虑俱乐部的"语言不可知论"定位。鼓励孩子们探索不同的语言和平台。

祝你好运,干得好!


嗯,这是一个编程俱乐部,所以应该很有趣!所以我想说,马上就开始动手体验吧。首先解释什么是main()方法,然后让学生编写一个hello world程序。逐步改进hello world程序,使其具有功能并打印出用户输入。

我不会说初学者的算法太快,让他们先玩C++。


  • 解释"煎蛋"的故事。询问听觉,他们会做什么来让自己做煎蛋。让他们记下他们考虑的步骤。您可能会收到少于5步的算法。然后向他们解释如果我们想教一台电脑煎鸡蛋,应该写下多少步骤。类似:
  • 1
    2
    3
    4
    5
    6
    7
    1) Go to the Fridge
    2) Open the fridge door
    3) Search for eggs
    4) If there are no eggs - go to the shop to buy eggs ( this is another function ;) )
    5) If there are eggs - calculate how many do you need to fry
    6) Close the fridge door
    7) e.t.c. :)
  • 从C语法语义E.T.C的基本知识开始,并与之并行解释气泡排序等非常基本的算法。
  • 在听觉熟悉结构化编程(这可能需要几个星期或几个月,取决于你经常做的功课),你可以前进到C++和OOP。

  • 上面提到过,"让编程变得有趣"。今天有趣的是,人们不为了学习而学习。大多数人想要即时的满足。

    用编程来教一点逻辑。这有助于解决问题。我脑子里的那个分类游戏是猜谜游戏。

    • 让他们制作一个程序来猜测0到100之间的数字。
    • 让他们复制一个黑杰克…我基本上做过:-(

    做书面说明。


    DeTEL和Deitel的C++编程中的内容是一个体面的介绍,并且在每章末尾提出的练习都是很好的玩具问题。

    基本上,你说的是:-控制结构-函数数组-指针和字符串

    你可能想接着介绍一下STL("好吧,既然我们已经用了很难的方法……这是一个更简单的选择。)


    首先让他们理解一个问题,比如排序。这是非常基本的,他们应该能够很快地联系起来。一旦他们看到问题,就向他们展示解决问题的工具/解决方案。

    我记得当我第一次展示一个合并排序的例子时的感觉。我可以遵循所有的步骤,但我到底是为了什么?让他们渴望一个问题的解决方案,他们会更好地理解这个工具和解决方案。


    从一个简单的"你好世界"程序开始。这介绍了一些基本原理,如变量、写入流和程序流。

    然后从中添加复杂性(链接列表、文件IO、获取用户输入等)。

    我之所以说"从你好世界开始",是因为孩子会很快看到一个正在运行的程序。这几乎是即时反馈,因为他们从一开始就写了一个运行中的程序。


    在我看来,big-o是初学者学习的重要概念之一。


    参加调试比赛。提供包含错误的代码示例。参加比赛,看看谁能找到最快或最快的。

    有一本优秀的书,如何不在C++中编程,你可以开始使用它。

    你总是从错误中吸取教训,我更喜欢从别人的错误中吸取教训。

    它还可以让那些没有经验的人通过看到代码来学习,即使代码几乎可以工作。


    除了这个问题的答案外,还有一些重要的话题要讨论。下面是一个例子,说明如何构造课程。

    第一课:术语和语法

    要涵盖的术语:变量、运算符、循环(迭代)、方法、保留字、数据类型、类

    要涵盖的语法:赋值、操作、if/then/else、for循环、while循环、select、输入/输出

    第二课:基本算法构建

    介绍一些简单的算法,包括一些输入,可能是for或while循环。

    第三课:更高级的算法主题

    这适用于递归、矩阵操作和更高层次的数学。你不必过于复杂的主题,但要引入足够的复杂性,以便在真正的项目中有用。

    最后一课:小组项目

    做一个小组可以参与的项目。

    这些不必是一天的课程。您可以在多天内传播这些主题。


    伪代码应该是第一个。

    编辑:如果他们是完全编程的初学者,那么我会做上半部分关于编程。一旦你达到了一个谈论算法的水平,那么伪代码就非常重要了。


    仅仅因为你熟悉算法并不意味着你可以实现它们,仅仅因为你可以编程并不意味着你可以实现算法。

    从每个主题开始(保持编程与设计算法分开)。一旦他们掌握了每个概念,就慢慢地开始将这两个概念结合起来。


    你们可以从"C++标准库"从头开始构建TyyPIM项目,然后,当它工作时,开始设计自己的扩展。


    真的。C++是最糟糕的可能语言之一,就你所需要的无关的垃圾数量而言(Java可能会稍微差一点,我猜)。

    当在一个繁琐的环境中教授初学者时,通常从"这是一个简单的C程序"开始。我们稍后将讨论文件顶部的这些垃圾是什么,但现在,集中讨论"int main(void)"和"return"语句之间的行,这是完成所有有用工作的地方。

    一旦您超过了这一点,要涵盖的基本概念包括基本数据结构(数组、链接列表、树和字典)和基本算法(排序、搜索等)。


    让你的俱乐部通过教授构建软件的概念来学习如何用任何语言进行实际编程。学生使用编译器、生成系统、源文件、对象和库来将C代码转换为程序,而不是为Visual Studio购买12个许可证。我觉得这真的是一个开始,实际上让这些孩子能够理解如何在任何平台上制作软件,而不需要许多教育机构喜欢依赖的拐杖。


    至于选择的语言——祝贺——你会发现C++非常丰富,让你想到数学捷径和数以百万计的方式让你的代码执行得更好(或者实现花式模式)。

    问题是:当我请求编程时,我总是试图将一个现实生活中的问题分解成几个步骤,然后当我看到任务或数据之间的相似性时,我总是试图找到一种更懒惰、更简单、更卑鄙的方法来实现它。

    当学习模式和真正的算法时,优雅就随之而来。


    Hank:大O????你的意思是告诉初学者他们的代码是O(n^2),而你的代码是N logn??


    我可以看到一些不同的方法:

    1)基本编程构建块。什么是条件语句,例如switch和if/else?什么是重复语句,例如for和while循环?我们如何将这些结合起来,使程序成为我们想要的步骤序列?你可以做一些简单的事情,比如把杂货账单加起来,或者把温度或者距离从公制换算成英制,或者反过来。什么是基本变量类型,如字符串、整数或double?在这里,你可以有一个高级思想的布尔代数,或者可能教你如何在2或16的基础上做算术,有些人会觉得容易,有些人会觉得难。

    2)算法上什么是相似的构建基块。排序是一个非常简单的话题,可以广泛讨论和分析,试图找出如何比仅仅交换那些看起来不正常的元素更快,如果你学会了冒泡,这是大脑中最死板的方式。

    3)编译和运行时元素。什么是调用堆栈?什么是堆?如何处理内存以运行程序,例如代码块和数据块?如何打开和操作文件?什么是编译和链接?什么是生成文件?其中有些很简单,但也可以让人大开眼界,看看事情是如何运作的,这可能是俱乐部大部分时间都在做的事情。

    接下来的2个更具挑战性,但可能很有趣:

    4)讨论算法背后的各种想法,例如:1)分而治之,2)动态编程,3)蛮力,4)创建数据结构,5)将问题简化为已解决的类似问题,例如斐波那契数是给初学者的一个经典递归问题,以及6)贪婪的想法,就像在制作一个举个例子,如果你在一个硬币面值为A、B和C的国家,如果你想要一些异国情调的东西,你也可以进入一些图表理论的例子,比如最小重量生成树,或者旅游销售人员想要一些容易描述但很难解决的东西。

    5)数学函数。你将如何编程一个阶乘,它是从1到n的所有数字的乘积?你将如何计算各种算术或几何级数的和?或者从一组n中计算r元素的组合数或排列数?给定一组点,近似满足此要求的多项式,例如,在一个称为x和y的二维平面上,你可以给出2个点,如果你已经解出了一对线性方程,让人们知道什么是斜率和y截距。

    6)可以使用链表和数组实现的列表。哪一种比较适合各种情况?如何实现诸如插入、删除、查找和排序等基本功能?

    7)抽象数据结构。什么是堆栈和队列?如何构建和测试类?

    8)指针。这只会导致大量的主题,比如如何分配/取消分配内存,什么是内存泄漏?

    这些是我对各种起点的建议。我认为,如果你能让几个不介意一周又一周谈论同一主题的人聚在一起,开始讨论可能会带来一些有趣的地方,因为如果你想深入到更细微的问题上,排序可能是一个需要很好涵盖的大主题。


    谢谢你的回复!

    你将如何教他们解决实际问题?

    我认识一群知道C++语法和一些基本算法的学生,但是他们不能应用他们在解决实际问题时所知道的知识——他们不知道方法,把他们的思想转录成一套严格的步骤。我不讨论"高级"方法,如动态编程、贪婪等,而是讨论基本的算法思维。

    我想这只是因为他们所经历的糟糕的学习过程。在其他科学中——比如数学——他们真的很聪明。