Рекурсивная функция в Java - N вложенных циклов с изменяющимися признаками - PullRequest
1 голос
/ 22 февраля 2010

Аналогично этому: Есть ли способ сделать n-уровневые вложенные циклы в Java?

Я хочу создать рекурсивную функцию, которая генерирует N вложенных циклов, , где показатели зависят от глубины цикла . В общем, я хочу сделать это рекурсивно:

// N = 3, so we want three nested loops

for(int i1 = 0; i1 < max; i1++){
    for(int i2 = i1+1; i2 < max; i2++){
        for(int i3 = i2+1; i3 < max; i3++){
            int value1 = getValue(i1);
            int value2 = getValue(i2);
            int value3 = getValue(i3);
            doSomethingWithTheValues( ... );
        }
    }
}

Я посмотрел ответы на другой вопрос и попытался изменить ответ (oel.neely), но безуспешно. Я предполагаю, что для этого нужна лишь небольшая модификация, но сейчас я просто запутываюсь!

1 Ответ

2 голосов
/ 22 февраля 2010

Это C #, но его легко конвертировать в Java:

class ImmutableStack<T>
{
    public readonly T Head;
    public readonly ImmutableStack<T> Tail;

    public ImmutableStack(T head, ImmutableStack<T> tail)
    {
        this.Head = head;
        this.Tail = tail;
    }

    public static ImmutableStack<T> Cons(T head, ImmutableStack<T> tail)
    {
        return new ImmutableStack<T>(head, tail);
    }

    public static ImmutableStack<T> Reverse(ImmutableStack<T> s)
    {
        ImmutableStack<T> res = null;
        while (s != null)
        {
            res = Cons(s.Head, res);
            s = s.Tail;
        }
        return res;
    }
}

class Program
{
    static void AwesomeRecursion(int toDepth, int start, int max, ImmutableStack<int> indices)
    {
        if (toDepth < 0)
        {
            throw new ArgumentException("toDepth should be >= 0");
        }
        else if (toDepth == 0)
        {
            Console.Write("indices: ");
            indices = ImmutableStack<int>.Reverse(indices);
            while (indices != null)
            {
                Console.Write("{0}, ", indices.Head);
                indices = indices.Tail;
            }
            Console.WriteLine();
        }
        else
        {
            for (int i = start; i < max; i++)
            {
                AwesomeRecursion(toDepth - 1, i + 1, max, ImmutableStack<int>.Cons(i, indices));
            }
        }
    }


    static void Main(string[] args)
    {
        AwesomeRecursion(4, 1, 10, null);
        Console.WriteLine("Done");
        Console.ReadKey(true);
    }
}

Мы сохраняем индексы в неизменяемом стеке, поскольку это делает возврат намного проще, чем изменяемые стеки или очереди.

...