| /******************************************************************************* |
| * Copyright (c) 2010 University of Illinois at Urbana-Champaign and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * UIUC - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.rephraserengine.testing.combinatorial; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.rephraserengine.core.util.Pair; |
| |
| /** |
| * |
| * @author Jeff Overbey |
| * |
| * @since 2.0 |
| */ |
| public class ForEach |
| { |
| private ForEach() {;} |
| |
| public static <T> Iterable<List<T>> combinationOf(List<T> list) |
| { |
| return combinationOf(1, list.size(), list); |
| } |
| |
| public static <T> Iterable<List<T>> combinationOf(int numElementsToChoose, |
| List<T> list) |
| { |
| return combinationOf(numElementsToChoose, numElementsToChoose, list); |
| } |
| |
| public static <T> Iterable<List<T>> combinationOf(final int minNumElementsInCombination, |
| final int maxNumElementsInCombination, |
| final List<T> list) |
| { |
| return new Iterable<List<T>>() |
| { |
| public Iterator<List<T>> iterator() |
| { |
| return new CombinationIterator<T>(minNumElementsInCombination, |
| maxNumElementsInCombination, |
| list); |
| } |
| }; |
| } |
| |
| private static class CombinationIterator<T> implements Iterator<List<T>> |
| { |
| protected List<T> list; |
| protected CombinationGenerator gen; |
| protected int[] nextCombination; |
| |
| public CombinationIterator(int minNumElementsInCombination, |
| int maxNumElementsInCombination, |
| List<T> list) |
| { |
| if (minNumElementsInCombination < 1 |
| || minNumElementsInCombination > list.size() |
| || maxNumElementsInCombination < 0 |
| || maxNumElementsInCombination > list.size()) |
| throw new IllegalArgumentException(); |
| |
| this.list = list; |
| this.gen = new CombinationGenerator(list.size(), maxNumElementsInCombination); |
| this.nextCombination = gen.firstCombination(minNumElementsInCombination); |
| } |
| |
| public boolean hasNext() |
| { |
| return nextCombination != null; |
| } |
| |
| public List<T> next() |
| { |
| if (nextCombination == null) return null; |
| |
| List<T> combination = new ArrayList<T>(nextCombination.length); |
| for (int i = 0; i < nextCombination.length; i++) |
| combination.add(list.get(nextCombination[i])); |
| |
| nextCombination = gen.nextCombination(nextCombination); |
| return combination; |
| } |
| |
| public void remove() |
| { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| |
| /** |
| * @return all pairs of two objects from the given set |
| */ |
| public static <T> Iterable<Pair<T,T>> pairOf(final List<T> objects) |
| { |
| return new Iterable<Pair<T,T>>() |
| { |
| public Iterator<Pair<T,T>> iterator() |
| { |
| return new PairIterator<T>(objects); |
| } |
| }; |
| } |
| |
| private static class PairIterator<T> implements Iterator<Pair<T,T>> |
| { |
| /** Set of objects from which pairs will be generated */ |
| protected final List<T> objects; |
| |
| /** Index of the first component of the pair in {@link #objects} */ |
| protected int fstIndex; |
| |
| /** Index of the second component of the pair in {@link #objects} */ |
| protected int sndIndex; |
| |
| public PairIterator(List<T> objects) |
| { |
| if (objects == null) throw new IllegalArgumentException(); |
| if (objects == null || objects.isEmpty()) |
| throw new IllegalArgumentException(); |
| |
| this.objects = objects; |
| this.fstIndex = 0; |
| this.sndIndex = 0; |
| } |
| |
| public boolean hasNext() |
| { |
| return fstIndex < objects.size(); |
| } |
| |
| public Pair<T,T> next() |
| { |
| if (fstIndex == objects.size()) return null; |
| |
| Pair<T,T> result = new Pair<T,T>(objects.get(fstIndex), objects.get(sndIndex)); |
| |
| if (++sndIndex == objects.size()) |
| { |
| ++fstIndex; |
| sndIndex = 0; |
| } |
| |
| return result; |
| } |
| |
| public void remove() |
| { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| |
| /** |
| * @return all tuples of objects with one component from each of the given sets |
| */ |
| public static <T> Iterable<List<T>> tupleOf(final List<? extends T>... objects) |
| { |
| return new Iterable<List<T>>() |
| { |
| public Iterator<List<T>> iterator() |
| { |
| return new TupleIterator<T>(objects); |
| } |
| }; |
| } |
| |
| private static class TupleIterator<T> implements Iterator<List<T>> |
| { |
| /** Sets of objects from which pairs will be generated */ |
| protected final List<? extends T>[] objects; |
| |
| /** Indices of the components of the tuple: <code>index[i]</code> is an |
| * index into {@link #objects}[i] */ |
| protected int[] indices; |
| |
| public TupleIterator(List<? extends T>... objects) |
| { |
| if (objects == null) throw new IllegalArgumentException(); |
| for (List<? extends T> list : objects) |
| if (list == null || list.isEmpty()) |
| throw new IllegalArgumentException(); |
| |
| this.objects = objects; |
| this.indices = new int[objects.length]; |
| } |
| |
| public boolean hasNext() |
| { |
| return indices[0] < objects[0].size(); |
| } |
| |
| public List<T> next() |
| { |
| if (indices[0] == objects[0].size()) return null; |
| |
| List<T> result = new ArrayList<T>(indices.length); |
| for (int i = 0; i < indices.length; i++) |
| result.add(objects[i].get(indices[i])); |
| incrementIndices(); |
| return result; |
| } |
| |
| private void incrementIndices() |
| { |
| for (int i = indices.length-1; i >= 0; i--) |
| { |
| indices[i]++; |
| if (indices[i] < objects[i].size()) |
| break; |
| else if (i > 0) |
| indices[i] = 0; |
| } |
| } |
| |
| public void remove() |
| { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| } |