структура «повторить» в Java - PullRequest
4 голосов
/ 14 января 2012

Я преподаю программирование для начинающих (начиная с 12-15 лет), и один из вариантов, который мы сделали (потому что это было естественно в Python), - научить понятию «повторять действие» перед понятием переменных .

Мы пели в Python с

for loop in range(10):

не говоря о переменных массивов и в C ++ с

#define repeat(nb) for(int _loop = 0 ; _loop < (nb) ; _loop++)

Идея заключалась в том, чтобы скрыть сложность классического цикла, чтобы настаивать на «повторной» части. Мы не скрываем от студентов тот факт, что «repeat (10)» не является частью C ++, это просто способ упростить обучение.

В Паскале мы не можем сделать намного больше, чем

for loop := 1 to 10 do

но это нормально, потому что это не так сложно запомнить.

Я искал что-то похожее в 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");
    }
    }
}

The

for (int loop : Range.size(10))

все еще легче запомнить, чем

for(int loop = 0 ; loop < 10 ; loop++)

но есть две проблемы:

  • две переменные необходимы для создания циклов for: я не думаю, что мы сможем с этим многое сделать
  • у нас есть предупреждения, потому что переменная loop не используется

Видите ли вы лучшее решение, чем у нас?

Еще раз, мы только хотим предоставить некоторый «инструмент» на начальном этапе, чтобы ученики могли «повторить» действия, прежде чем узнавать что-либо о «переменных». Мы не прячемся от них, которых нет в языке, и после нескольких упражнений (~ 80-100) мы просим их использовать настоящий синтаксис.

<ч /> У нас есть около 20 упражнений, прежде чем вводить переменные: некоторые о печати текстов, но в основном мы предоставляем одну библиотеку с объектами, которыми вы можете манипулировать (следовательно, переменные скрыты в состоянии объекта). Вы можете думать о «логотипе-черепахе», например. Таким образом, понятием «цикл» можно манипулировать и «видеть», прежде чем вводить явные переменные, и вы можете быстро выполнять интересные упражнения.

Один пример, в 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()

Это упражнение не так просто, но синтаксис действительно прост и позволяет ученику сосредоточиться на «алгоритмической» части, а не на «языковой». После нескольких упражнений студенты начинают интересоваться, и мы можем ввести больше синтаксиса и более сложные понятия, такие как переменные.

Ответы [ 5 ]

5 голосов
/ 14 января 2012

Вам действительно нужно использовать 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

Вот полный исходный код.Метод 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;
        }
    }
}

Но я бы предпочел использовать некоторый язык, который поддерживает это естественным образом.

3 голосов
/ 14 января 2012

Я бы всегда сначала вводил переменные. Что вы собираетесь делать внутри цикла без знания переменных?

Кроме этого, возможно, было бы проще использовать цикл while. Глава цикла while намного проще и не требует определения переменных. Это очень просто понять:

while (do_the_loop){
   //this is repeated
}
1 голос
/ 14 января 2012

Это не совсем то, что вы ищете, но вот мое мнение и то, как я бы этому научил.(Осторожно, я совсем не учитель: D)

Нет ли для этого двух разных курсов: Алгоритмы и Программирование?В программировании вы действительно должны начать с обучения их переменным.Это совсем не сложно.И я не думаю, что 20 упражнений по алгоритмам будут для них такими интересными.Я думаю, что их больше привлекает сила вычисления чего-либо, чем написания циклов внутри друг друга.Написание простой программы, которая вычисляет некоторые суммирования и умножения и так далее, поможет внедрить идею примитивных переменных.Тогда я бы представил цикл for.Продемонстрируйте, напечатав 10 раз какой-нибудь текст в сочетании с переменной, используемой в цикле for:

for (int i = 0; i < 10; ++i)
    // Tell them that the 'i' is a variable as you explained before.
{
    System.out.println("This is line " + i);
}

Тогда, мне кажется, будет интересно написать приложение, которое вычисляет факториал с жестко закодированным числом.Таким образом, большинство из них, надеюсь, получат представление о работе с переменными.Затем попытайтесь объяснить сферу применения.

int number = 5;
int factorial = 1;
for (int i = 1; i <= number; ++i)
{
    factorial = factorial * i;
}
System.out.println(number + "! = " +  factorial);
1 голос
/ 14 января 2012

Java на самом деле не подходит для такого рода задач, поскольку не позволяет передавать функции.

Единственный способ сделать это без переменных - использовать интерфейс:

private static void repeat(int times, DoStuff what) {
    for (int i = 0; i < times; i++) {
        what.doIt();
    }
}
private interface DoStuff {
    public void doIt();
}

А затем используйте это так:

repeat(5, new DoStuff() { public void doIt() {
            System.out.println("xx"); // whatever needs to be done
        }});

Что было бы без переменных, но довольно запутанно в начале.

0 голосов
/ 28 января 2012

если у вас есть определенный лимит, вы должны использовать структуру while

while (myval

// сделать что-то

myval ++; }

но когда предел неизвестен, вы должны использовать для или для каждого

для (int i = 0; i

} из объектов

для каждого (String myString: myStringArray) {

}

Saludos

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...