编程体会:有效的流程很关键

写程序的时候,正确合适的工作流程能够确保高效地完成工作目标,这篇文章将主要介绍从头到尾解决编程问题的策略,与各位在编程之路上共勉。应用这一结构化的流程能尽可能地缩减令人沮丧地调试过程,在更少的时间里写成更清晰更正确的代码。

一步步介绍

给出一个示例练习题用来说明。
问题:给定两个字符串sourceString和searchString,返回searchString出现在sourceString中的第一个索引。如果searchString未在sourceString中出现,则返回-1。

第一步:画出来

直接从写代码开始实际上是一个荒谬又懒惰的思路。在写一篇文章之前,你首先会搞清楚你的假设和证据,以确保你的论证是合理的。如果你不这样做,后面当你发现写的内容整体无法合适地组织起来时,你又要重新开始,这就浪费了很多时间。写代码也是这样,甚至可能更糟,就像把洗发水揉进眼睛里。

通常而言,一个问题的解决方案并不是浅显直观的,即使乍看起来很简单。在纸上琢磨一下能让你找到解决方案并验证该方案在一些不同场景中的效果。所有这些工作都应该在写下任何一行代码之前完成。

所以,先不要写代码。甚至不要去想代码。后面会有足够的时间去添加分号和括号。现在你只需要搞清楚你作为一台人体计算机,会如何解决这个问题。

画图。使用箭头。在小方框里填写数字。只要能让你可视化这个问题,那就去做吧。你的目标是解决问题,你能用纸张和笔去尽情发挥,而不受限于键盘。

首先找一些简单的输入。例如,假设你的函数是取一个字符串abc。搞清楚正确的结果是什么,然后去想如何解决这个问题以及所涉及到的步骤。

我们假设我们的字符串有以下值:

sourceString = "sahjfansjd"
searchString = "fan"

我的想法是像下面这样展开的:

好吧,我看到sourceString包含searchString。但我是怎么看出来的呢?额,首先我从sourceString的开头开始阅读,检查每3个字符构成的片段是否与词fan匹配,直到结束。比如,我看到了sah、ahj、hjf等组合,当我看到索引4时,我找到了fan,所以我确定找到了匹配并且是从索引4开始。

当我们写下我们的算法时,需要确保我们表达了一切并能够处理所有可能的情况。当我们确实找到匹配时,返回正确的答案当然很好,当我们也需要在没找到匹配的时候同样能返回正确答案。

我们再以另一对字符串为例:

sourceString = "sahjfasjd"
searchString = "fan"

这里,我们同样首先从sourceString的开头开始阅读,检查每3个字符构成的片段是否与词fan匹配,直到结束,字符串末尾,最后我们确定其中没有匹配,因此返回==-1==。

我们已经确定了解决这个问题的一系列步骤(在编程领域,我们称之为算法),也已经尝试了一些不同的场景,每一步都得到了正确的结果。现在,我们已经相信我们的算法有效了,是时候形式化这个算法了,这就是下一个步骤。

第二步:写成普通话

想想第一步确定的算法,然后用平实易懂的语言把它写下来。这能使这些步骤显得具体,让我们在写代码时能够回顾参考。

  1. 从字符串开头开始检查
  2. 检查每3个字符构成的片段
  3. 如果其中有任何片段等于searchString,就返回当前索引
  4. 如果直到该字符串结束也没找到任何匹配,就返回== -1==

看起来,还不错哟!

第三步:写伪代码

伪代码并不是真正的代码,但却模仿了代码的结构。下面是为上面的算法写的伪代码:

for each index in sourceString:
    N = len(searchString)
    match = sourceString[index, index + N]
    if match == searchString:
        return index
return -1

伪代码与代码的接近程度完全由我们自己决定,慢慢地练习,会发现最适合自己的风格。

第四步:将你能做到的部分翻译成代码

对于更简单的问题,这个步骤可以和上一步一起完成。

这是整个流程中,我们第一次必须考虑句法、函数参数和语法规则。也许没法写出所有的一切,但没有关系,把我们能写出来的部分先写出来。

def myfunc(sourceString, searchString):
    n = len(searchString)
    for index in range(len(sourceString)):
        match = sourceString[index: index + n]
        if match == searchString:
            return index
    return -1
    
myfunc(sourceString, searchString)

在写下上面这段代码的时候,我们已经开始调动我们的编程知识,将能运行的代码写出来了,中间肯定会有报错和调试的过程。

第五步:不要猜测

代码新人常会犯一个错误:在互联网上找一下写着可能有效的东西,然后不加测试地将其插入到自己地程序中。你的程序中你不理解地片段越多,就越不可能得到最后正确的解决方案。

每增加一个你不确定的东西,你的程序可能出错的方式都会翻一倍。对某事不确定?ok—如果代码无效,那么这里可能就是问题所在。

你的程序可能出错的方式遵循梅森序列: a ( n ) = 2 n − 1 {a(n)=2^n-1} a(n)=2n1

首先测试你的新代码。在网上找东西是可以的,但是在将其插入你的程序之前应该在另一个单独的小空间里测试一下它,以确保其工作方式和你所想的一样。

在前一步写正式代码的时候,我忘记字符切片是怎么做的了,所以第一次运行的时候报了错,好在找到了想起来怎么做了,把问题解决了就ok了。

如果你读到了这里,我现在只想说:试试这种策略。回到你上周因为受挫而搁置一旁的编程问题。保证你能立马看到效果。祝好运,编程快乐。

===========================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值