跟着简单问题学算法

210 阅读8分钟
原文链接: mp.weixin.qq.com

孙欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

自尼古拉斯·沃斯提出著名的公式“程序=算法+数据结构 ”后,“算法”这一名词被提升空前的重要地位,这个公式告诉了我们计算机程序的本质是什么,为我们前行指明了方向。无论对于从事计算机科学研究的科研人员,还是从事软件技术开发的工程师,都无一不把算法列为个人最为重要的核心能力之一。而算法的学习因其抽象程度较高、知识量较大、对数学的要求较高等容易导致很多同学学习途中轻易放弃,另外算法学习的最终目的是为了解决实际问题,因此在学习中 不仅需要关注算法本身内容的学习,而且更应该培养一种分析问题、解决问题的能力,掌握算法思维方式。

计算机领域中,无论是解决简单的问题还是解决复杂的问题,都是对算法思维的一种训练。如果简单的问题能够反映算法的本质,那为什么不去了解简单的问题呢?所以平时大家看到的一些厉害的人都会用简单的现象来帮助你理解复杂的道理。同样的一个客观事实,不同的人悟出的道理也是不一样的。

本系列博客将选取1到100求和这样一个耳熟能详、非常简答的问题作为出发点,为大家介绍其背后反映的一些算法思维,切记我们的目的不是解决1到100求和问题, 而是选取这样的一个问题,来揭示算法思维的一些规律。

问题描述

 

1到100求和问题即1+2+...+100=?这个问题是小学时候大家在认识自然数,了解加法运算后都会接触到的一个问题。

接下来将介绍,如何利用计算机的编程语言来编程实现解决这个问题,示例的编程语言为c语言,并揭示算法思维的本质。

解决方案

解法一:

首先将问题简化一下,只求1+2=?相信每位同学都能很快的写出c语言的程序。按照第一讲的思路,我们先写程序模板,然后在指定的地方编写代码即可。

#include <stdio.h>

 

int main(){

            int a1 = 1;

            int a2 = 2;

 

            int sum =a1 + a2;

 

            return 0;

}

 

是不是很快就写出了程序代码,既然1+2能求,那么1+2+...+100也是同样的道理,于是很快写出了下面代码。

#include <stdio.h>

int main(){

            int a1 = 1;

            int a2 = 2;

            ···                         

            int a100 =100;

 

            int sum =a1 + a2+···+a100;

 

            return 0;

}

(上面的代码并不是完整的代码,其中的省略号部分需要大家自己补全。)

上面的代码虽然能够解决问题,但是却有很大的问题,代码的行数达到100多行,而且很多都是形式上重复的代码。分析以上代码存在的问题,主要在于定义了101个整型变量,其中100个a1, a2,..., a100还有一个sum。那么 是否可以减少变量定义的个数呢?如果能够减少变量定义的个数,那么将在很大程度上解决问题。

解法二:  

定义变量a1, a2,..., a100的目的是为了保存1,2,...,100这100个整数,是否可以只定义一个变量就可以保存这一百个连续的整数呢?即只定义一个变量i,就可以实现保存1,2,...,100。

 

在经过一番分析之后,发现可以利用c语言的循环结构来实现。

int i = 0;

for( i = 1; i <= 100; i++)

上面的代码是不是就可以实现只使用一个变量i就能保存1,2,...,100。

以前需要100个变量来保存1,2,...,100,现在只需要1个变量就可以了,是不是进步了很多。

 

变量定义的个数减少了,但是如何实现求和呢?

sum = a1 + a2 + ··· + a100;

这是一种一次性加的算法即一次性将所有的变量加上去,是否可以使用分步加 的算法呢?即一次只加一个数,示例代码如下:

sum = sum + a1;

sum = sum + a2;

···

sum = sum + a100;

修改成分步加的算法之后,由于现在只用一个变量i来保存一百个连续整数,因此其可进一步修改为:

sum = sum + i; // i = 1

sum = sum + i; // i =2

···

sum = sum + i; // i = 100

此时发现有一百行重复的代码sum = sum + i;利用循环结构可以消除代码重复的特点,结合上面减少变量定义个数的做法,得出进一步修改的代码为:

int i = 0;

int sum = 0;

 

for(i = 1; i <= 100; i++){

            sum = sum +i;

}

以上代码已经非常简洁了,是不是还有更好的解法呢?

解法三:  

其实著名的大数学家高斯在十岁的时候,就已经给出了这个问题的最简洁的解法,那就是大家比较熟知的数学公式:

其代码实现为:

int sum = (1+100)*100 / 2;

 

直接一行代码就可以得到答案,这就是数学的魅力哈!

结语

面对复杂的问题,可以先从简单的问题开始尝试解决,如本题要求1+2+···+100这一百个连续整数的求和,对于初学者代码较为困难,因此可以尝试解决1+2的问题,然后采用类比法来求解更复杂的问题。

利用算法解决问题的时候,不要一开始就寻求复杂的算法来求解,而应该从简单的、易于理解的思路开始入手解决问题,然后逐步的发现并提出该方案存在的问题。如果不能发现问题就意味着不能改进方案,不能改进方案就意味着不会有更好的解决方案,因此发现问题远比解决问题更重要 。而大多数的初学者在学习的时候往往会忽视这一点,大多只是从表面上掌握了这个知识,而没有深入理解这个知识背后的道理。

1到100求和为大家展示了本题的算法进化之路,揭示了算法思维的一些规律,还有没有其他的解法呢?还能够揭示哪些算法思维呢?欲知后事如何,欢迎持续关注微信公众号“算法与编程之美”,跟着简答的问题学算法。

更多精彩文章

聊一聊编程的本质

windows神器推荐 TreeSize

什么是机器学习

关于网页首页设计的一点思考

新手小白应该如何学习MUI

聊一聊where2go团队做什么

聊一聊编程的本质

深入理解浏览器内核 - 概述

深入理解浏览器内核 - 浏览器内核介绍

深入理解浏览器内核 - 浏览器内核依赖关系

python快速求解不定积分和定积分

AI告诉你张无忌最爱的竟是...

Jupyter快速编辑高大上数学公式 泰勒展开式

Jupyter快速编辑高大上数学公式 常见希腊字母

基本初等函数 指数函数

基本初等函数 指数函数 代码篇

聊一聊JavaWeb面试

聊一聊单片机和服务器

50行代码实现简单的网站服务器

50行代码实现网站服务器 2

50行代码实现网站服务器 3

Tomcat源码分析之 doGet方法(一)

Tomcat源码分析之 doGet方法(二)

Tomcat源码分析之 doGet方法(三)

Tomcat源码分析之 doGet方法(四)

Tomcat源码分析之中文乱码(一)

一种基于状态机的 DOM 树生成技术(1)

一种基于状态机的 DOM 树生成技术(2)

 where2go 团队


   

微信号:算法与编程之美          

长按识别二维码关注我们!

温馨提示:点击页面右下角 “写留言”发表评论,期待您的参与!期待您的转发!