Java中的"重复"结构

Loï*_*ier 4 java loops

我正在向初学者教授编程(从12-15岁开始),我们做出的选择之一(因为在Python中很自然)是在变量概念之前教授"重复动作"的概念.

我们用Python搞砸了

for loop in range(10):
Run Code Online (Sandbox Code Playgroud)

没有谈论数组的变量和在C++中

#define repeat(nb) for(int _loop = 0 ; _loop < (nb) ; _loop++)
Run Code Online (Sandbox Code Playgroud)

我们的想法是隐藏经典循环的复杂性,以便坚持"重复"部分.我们并没有向学生隐瞒"repeat(10)"不是C++的一部分这一事实,它只是简化学习的一种方式.

在Pascal,我们做不了多少

for loop := 1 to 10 do
Run Code Online (Sandbox Code Playgroud)

但这没关系,因为它并不难记住.

我在Java中寻找类似的东西,我发现:

import java.util.List;
import java.util.AbstractList;

class Range {
    public static List<Integer> size(final int end) {
        return new AbstractList<Integer>() {
            @Override
            public Integer get(int index) {
                return 0 + index;
            }
            @Override
            public int size() {
                return end;
            }
        };
    };
}

public class Main {
     public static void main(String[] argv) {
    for (int loop : Range.size(10)) {
        System.out.println("xx");
    }
    }
}
Run Code Online (Sandbox Code Playgroud)

for (int loop : Range.size(10))
Run Code Online (Sandbox Code Playgroud)

仍然比较容易记住

for(int loop = 0 ; loop < 10 ; loop++)
Run Code Online (Sandbox Code Playgroud)

但有两个问题:

  • imcoicated for循环需要两个变量:我不认为我们可以做很多事情
  • 我们有警告,因为loop没有使用变量

您是否看到了我们拥有的更好的解决方案?

再一次,我们只想在开始阶段提供一些"工具",以便学生在了解"变量"之前"重复"动作.我们并没有躲避那些不在语言中的人,经过一些练习(~80-100)之后,我们要求他们使用真正的语法.


在引入变量之前我们有大约20个练习:一些关于打印文本但是我们主要为一个库提供可以操作的对象(因此变量隐藏在对象状态中).你可以想到"logo-turtle".这样,"循环"的概念可以在引入显式变量之前被操纵和"看到",并且您可以非常快速地进行实习.

一个例子,在Python中,你想要访问10x10表的每个案例一次,然后只返回一个然后回到你的起点(左下角):

from robot import *

top()
for loop in range(4):
   for loop in range(8):
      top()
   right()
   for loop in range(8):
      bottom()
   right()
for loop in range(8):
   top()
right()
for loop in range(9):
   bottom()
for loop in range(9):
   left()
Run Code Online (Sandbox Code Playgroud)

这个练习并不容易,但语法非常简单,让学生专注于"算法"部分,而不是"语言"部分.经过一些练习后,学生们会受到关注,我们可以引入更多语法和更难的概念,比如变量.

Arn*_*cek 5

你真的需要在这些练习中使用Java吗?如果其他语言适合您,那么为什么不使用它们呢?当学生知道变量等基础知识时,您总是可以转到Java.

我同意变量可能会让初学者感到困惑 - 特别是它们的价值可能一直在变化,而不是人们从代数中使用的东西,一旦"分配",值就不会改变.

如果你想使用Java,你可以使用while循环,这似乎更合适.如何避免使用变量的一个肮脏技巧是遵循代码 - 它使用StackTraceElement而不是变量.

它打印

Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Run Code Online (Sandbox Code Playgroud)

这是完整的来源.main(Strinng [] args)方法是带循环的代码,其余是支持代码.

import java.util.HashMap;
import java.util.Map;

public class Repeater {

    public static void main(String[] args) {
        while(range(3)) {
            System.out.println("Hello A");
            while (range(2)) {
                System.out.println("Hello B");
                while (range(3)) {
                    System.out.println("Hello C");
                }
            }
        }
    }

    public static boolean range(int size) {
        return Range.range(size);
    }


    public static class Range {

        static Map<StackTraceElement, RangePosition> ranges = new HashMap<StackTraceElement, RangePosition>();

        public static boolean range(int size) {
            final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3];
            //System.out.println(stackTraceElement);
            RangePosition position = ranges.get(stackTraceElement);
            if (position == null) {
                position = new RangePosition();
                position.size = size;
                ranges.put(stackTraceElement, position);
            }

            final boolean next = position.next();
            if (!next) {
                ranges.remove(stackTraceElement);
            }
            return next;
        }

     }

    public static class RangePosition {
        int current,size;
        boolean next() {
            current++;
            return current <= size;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我更喜欢使用一些自然支持这种语言的语言.