算法和函数分解与 Honey Boo Boo





5.00/5 (3投票s)
如何编写算法,然后根据该算法创建可工作的 Java 代码
在上一篇文章中,我介绍了算法和函数分解。在这里,我们将探讨如何编写算法,然后根据该算法创建可运行的 Java 代码。本文的目的并非呈现一个现实的计算机程序。此外,本文省略了许多基本的编程主题。但这些省略是出于设计考虑。请暂且搁置怀疑,专注于将一个任务转化为计算机程序骨架的简单过程。在这里,我们使用函数分解,从一个通用的现实世界任务开始,逐步构建计算机程序的雏形。*(参见下文)*
意面 - 红脖子肉酱
我记得童年时的一道菜,意面,在 Mama June 在 Learning Channel 的节目《Here Comes Honey Boo Boo》中制作意面时走红。这道菜很简单:意大利面、牛肉糜、番茄酱和黄油。让 Mama June 来演示吧。
Mama June 制作意面的方法是:煎牛肉糜、煮意大利面、在碗中用微波炉加热番茄酱和人造黄油的混合物,然后(在倒掉煮面水后)将所有食材放入煮面的锅中混合。
观察到算法
当你有一个想转化为计算机程序的流程时,不要一开始就编写代码。你应该先将涉及的任务形式化。从写出制作意面所需的步骤开始。关注大的步骤,而不是细节。
- 准备食材
- 煮面
- 煎牛肉糜
- 混合食材
- 微波酱料混合物
- 混合食材
- 盛盘享用
这是我从观察 Mama June 制作意面中得到的七个步骤。但是,这些步骤太宽泛了。因此,让我们将这些步骤分解成更详细的子步骤。由于我是一名红脖子,我想让它尽可能贴近现实——所以我们从碗碟架上拿碗碟,而不是从橱柜里。哦,还有,是冰箱而不是冷藏室——细节很重要。
- 准备食材
- 从冰箱里拿出牛肉糜
- 从橱柜里拿出意面
- 从架子上拿出锅
- 从架子上拿出平底锅
- 从架子上拿出可微波加热的碗
- 从冰箱里拿出番茄酱
- 从冰箱里拿出黄油
- 煮面
- 在锅里加水
- 将水烧开
- 加入意面
- 煮面
- 把意面(任意三根)扔到橱柜上
- 沥干意面
- 煎牛肉糜
- 将肉糜放入平底锅
- 煎肉糜
- 沥掉油脂(可选)
- 制作酱料
- 将人造黄油放入碗中
- 将番茄酱放入碗中
- 搅拌
- 微波加热酱料
- 混合食材
- 将肉糜加入意面
- 将酱料加入意面
- 搅拌
这样,你就得到了一个详细说明制作意面的顶层大纲。我们现在可以利用这个大纲来创建可运行的 Java 程序。
算法到 Java 代码
现在,让我们使用上面的大纲来编写一个简单的 Java 程序的骨架,该程序使用不返回值但执行简单任务的方法。同样,请暂时搁置怀疑,这里的目的是演示如何将大纲转化为一个简单的程序。
首先,我创建一个名为 Sketti
的简单类,其中包含一个 main 方法。
public class Sketti {
public static void main(String[] args) {
}
}
然后,我根据顶层大纲中的方法来创建方法。请注意,我没有添加任何逻辑来执行这些任务。
public class Sketti {
public static void main(String[] args) {
}
public static void gatherIngredients(){
}
public static void boilNoodles(){
}
public static void fryHamburger(){
}
public static void makeSauce(){
}
public static void combineIngredients(){
}
}
现在,我个人的一个“痛点”是,不应该在 main
方法中放置任何逻辑。main
方法是程序的入口点,不应用于任何逻辑。因此,我添加了一个名为 makeSketti
的顶层方法。这个方法将协调制作意面的任务。
public class Sketti {
public static void main(String[] args) {
}
public static void gatherIngredients(){
}
public static void boilNoodles(){
}
public static void fryHamburger(){
}
public static void makeSauce(){
}
public static void combineIngredients(){
}
public static void makeSketti(){
}
}
现在我有了主要任务,我可以协调这些任务来制作 sketti
。
public class Sketti {
public static void main(String[] args) {
makeSketti();
}
public static void gatherIngredients(){
}
public static void boilNoodles(){
}
public static void fryHamburger(){
}
public static void makeSauce(){
}
public static void combineIngredients(){
}
public static void makeSketti(){
gatherIngredients();
boilNoodles();
fryHamburger();
makeSauce();
combineIngredients();
}
}
我喜欢从一个可运行的程序开始,无论它多么简单,因此让我们在每个函数中添加 println
语句。
public class Sketti {
public static void main(String[] args) {
makeSketti();
}
public static void gatherIngredients(){
System.out.println("gatherIngredients");
}
public static void boilNoodles(){
System.out.println("boilNoodles");
}
public static void fryHamburger(){
System.out.println("fryHamburger");
}
public static void makeSauce(){
System.out.println("makeSauce");
}
public static void combineIngredients(){
System.out.println("combineIngredients");
}
public static void makeSketti(){
System.out.println("making sketti");
gatherIngredients();
boilNoodles();
fryHamburger();
makeSauce();
combineIngredients();
System.out.println("done making sketti");
}
}
运行后,程序将输出以下内容:
making sketti
gatherIngredients
boilNoodles
fryHamburger
makeSauce
combineIngredients
done making sketti
现在,为收集食材中的每个子步骤创建方法。然后让 gatheringIngredients
方法协调其子步骤。以下代码说明了这一点:
public static void gatherIngredients(){
System.out.println("gatherIngredients");
getBurger();
getNoodles();
getPot();
getPan();
getKetchup();
getButter();
}
public static void getBurger(){
System.out.println("\tgetBurger");
}
public static void getNoodles(){
System.out.println("\tgetNoodles");
}
public static void getPot(){
System.out.println("\tgetPot");
}
public static void getPan(){
System.out.println("\tgetPan");
}
public static void getKetchup(){
System.out.println("\tgetKetchup");
}
public static void getButter(){
System.out.println("\tgetButter");
}
对每个主要步骤重复创建子步骤和协调。
public class Sketti {
public static void main(String[] args) {
makeSketti();
}
public static void gatherIngredients(){
System.out.println("gatherIngredients");
getBurger();
getNoodles();
getPot();
getPan();
getKetchup();
getButter();
}
public static void getBurger(){
System.out.println("\tgetBurger");
}
public static void getNoodles(){
System.out.println("\tgetNoodles");
}
public static void getPot(){
System.out.println("\tgetPot");
}
public static void getPan(){
System.out.println("\tgetPan");
}
public static void getKetchup(){
System.out.println("\tgetKetchup");
}
public static void getButter(){
System.out.println("\tgetButter");
}
public static void boilNoodles(){
System.out.println("boilNoodles");
pourWater();
boilWater();
addNoodles();
cookNoodles();
throwNoodles();
drainNoodles();
}
public static void pourWater(){
System.out.println("\tpourWater");
}
public static void boilWater(){
System.out.println("\tgetButter");
}
public static void addNoodles(){
System.out.println("\taddNoodles");
}
public static void cookNoodles(){
System.out.println("\tcookNoodles");
}
public static void throwNoodles(){
System.out.println("\tthrowNoodles");
}
public static void drainNoodles(){
System.out.println("\tdrainNoodles");
}
public static void fryHamburger(){
System.out.println("fryHamburger");
placeMeat();
fryMeat();
drainFat();
}
public static void placeMeat(){
System.out.println("\tplaceMeats");
}
public static void fryMeat(){
System.out.println("\tfryMeat");
}
public static void drainFat(){
System.out.println("\tdrainFat");
}
public static void makeSauce(){
System.out.println("makeSauce");
addMargarine();
addKetchup();
mix();
microwaveSauce();
}
public static void addMargarine(){
System.out.println("\taddMargarine");
}
public static void addKetchup(){
System.out.println("\taddKetchup");
}
public static void mix(){
System.out.println("\tmix");
}
public static void microwaveSauce(){
System.out.println("\tmicrowave");
}
public static void combineIngredients(){
System.out.println("combineIngredients");
addMeat();
addSauce();
stir();
}
public static void addMeat(){
System.out.println("\taddMeat");
}
public static void addSauce(){
System.out.println("\taddSauce");
}
public static void stir(){
System.out.println("\tstir");
}
public static void makeSketti(){
System.out.println("Mama June's making sketti");
System.out.println("=========================");
gatherIngredients();
boilNoodles();
fryHamburger();
makeSauce();
combineIngredients();
System.out.println("done making sketti");
}
}
运行程序时,将获得以下输出:
Mama June's making sketti
=========================
gatherIngredients
getBurger
getNoodles
getPot
getPan
getKetchup
getButter
boilNoodles
pourWater
getButter
addNoodles
cookNoodles
throwNoodles
drainNoodles
fryHamburger
placeMeats
fryMeat
drainFat
makeSauce
addMargarine
addKetchup
mix
microwave
combineIngredients
addMeat
addSauce
stir
done making sketti
这样,你就学会了使用函数分解来编写一个简单的制作意面的程序。不可否认,这不是一个现实的程序。但它说明了函数分解。
结论
计算机编程就是解决问题。计算机需要指令来做任何有趣的事情。这些指令必须详细。将编写计算机程序执行某项任务与写学期论文进行比较。在写作之前,你会将论文的主题分解成大纲。该大纲将成为你学期论文的结构。编程也是如此。编程时,你的大纲将成为你程序的骨架。如果从编写计算机程序的所有其他任务中剥离函数分解,那么编写一个相当详细的算法就会变得非常简单。以前,编写算法被认为是基本的编程技能,这是众所周知的。但不知何故,这项技能已在新一代程序员和教授语法而非编程的各种编码训练营中逐渐消失。但如果你学会了这项简单的技能,你就会跻身顶尖程序员的行列。你在其他方面的解决问题能力和系统性思维也会得到提升。你甚至可能开始将算法思维应用到你的日常生活中。
- 这篇文章是为阅读《Think Java》前四章的学生准备的。文章特意避免了面向对象设计、变量传递和其他主题,以便完全专注于函数分解。