All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.invation.code.toval.misc.ListUtils Maven / Gradle / Ivy

package de.invation.code.toval.misc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

import de.invation.code.toval.file.FileWriter;
import de.invation.code.toval.math.CombinationsCalculator;
import de.invation.code.toval.math.Permutations;
import de.invation.code.toval.types.HashList;


public class ListUtils {
	
	private static java.util.Random rand = new Random();
	
	/**
	 * Returns a random element of the given list.
	 * @param  Type of list elements
	 * @param list List
	 * @return Random element of list
	 */
	public static  T getRandomItem(List list){
		return list.get(rand.nextInt(list.size()));
	}
	
	/**
	 * Inserts a header
	 * @param 
	 * @param list
	 * @param headerValue
	 * @param headerSize
	 */
	public static  void insertHeader(List list, T headerValue, int headerSize){
		for(int i=0; inull-value entries for every missing intermediate integer value.
	 * @param list List containing integer values
	 * @return An expanded list containing null values for missing intermediate integer values
	 */
	public static List fillUpWithNulls(List list){
		return fillUpWithNulls(list, null);
	}
	
	/**
	 * Expands an integer list to a size equal to its value range
	 * and adds null-value entries for every missing intermediate integer value.
	 * If replace is not null, all original values are replaced by replace.
	 * @param list List containing integer values
	 * @param replace Replacement for existing values within list
	 * @return An expanded list containing null values for missing intermediate integer values
	 * and optionally replaced original values
	 */
	public static List fillUpWithNulls(List list, Integer replace){
		Collections.sort(list);
		int minValue = list.get(0);
		int maxValue = list.get(list.size()-1);
		int range = (int) (maxValue-Math.signum(minValue)*Math.abs(minValue));
		
		ArrayList result = new ArrayList(range+1);
		for(int i=0; i void swapElements(List list, T element1, T element2){
		int index1 = list.indexOf(element1);
		int index2 = list.indexOf(element2);
		if(index1 == -1 || index1 == -1){
			return;
		}
		Collections.swap(list, index1, index2);
	}
	
	/**
	 * Returns a new list containing all elements of the original list but exclude
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @param exclude Element to exclude
	 * @return A new List containing all elements of the original list but exclude
	 */
	public static  List getListWithout(List list, T exclude){
		List result = new ArrayList(list.size());
		for(T t: list)
			if(!t.equals(exclude))
				result.add(t);
		return result;
	}
	
	/**
	 * Returns a new list containing all elements of the original list but the elements in exclude
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @param exclude Elements to exclude
	 * @return A new List containing all elements of the original list but the elements in exclude
	 */
	public static  List getListWithout(List list, List exclude){
		List result = new ArrayList(list.size());
		for(T t: list)
			if(!exclude.contains(t))
				result.add(t);
		return result;
	}
	
	public static  boolean containsOnlyNulls(List list){
		for(T t: list)
			if(t!=null)
				return false;
		return true;
	}

	/**
	 * Converts a list to an array of the same type.
	 * @param  Type of list elements
	 * @param list Basic list for operation
	 * @return An array of the same type containing all elements of list
	 */
	@SuppressWarnings("unchecked")
	public static  T[] asArray(List list) {
		return (T[]) list.toArray();
	}
	
	/**
	 * Creates a mutable list containing n copies of value.
	 * @param  Type of list elements
	 * @param value Basic value for list generation
	 * @param n Number of copies
	 * @return A mutable list containing n copies of value
	 */
	public static  List createList(T value, int n){
		ArrayList result = new ArrayList(n);
		for(int i=0; isize incrementing integer values beginning with begin.
	 * @param size Number of integer values within the result list
	 * @param begin First integer to start with
	 * @return A list containing incrementing integer values beginning with the specified value
	 */
	public static List createAndInitializeList(int size, int begin){
		ArrayList result = new ArrayList(size);
		for(int i=begin; icuts.
* Cuts are interpreted in an inclusive way, which means that a single cut at position i * divides the given list in 0...i-1 + i...n
* This method deals with both cut positions including and excluding start and end-indexes
* @param Type of list elements * @param list The list to divide * @param cuts Cut positions for divide operations * @return A list of sublists of list according to the given cut positions */ public static List> divideList(List list, Integer... cuts) { Arrays.sort(cuts); int c = cuts.length; if(cuts[0]<0 || cuts[c-1]>list.size()-1) throw new IllegalArgumentException(); int startIndex = cuts[0]==0 ? 1 : 0; if(cuts[c-1]!=list.size()-1) { cuts = Arrays.copyOf(cuts, cuts.length+1); cuts[cuts.length-1] = list.size()-1; c++; } List> result = new ArrayList>(c-startIndex); int lastEnd = 0; for(int i=startIndex; i<=c-1; i++) { int c2 = icuts.
* Cuts are interpreted in an inclusive way, which means that a single cut at position i * divides the given list in 0...i-1 + i...n
* This method deals with both cut positions including and excluding start and end-indexes
* @param list List to divide * @param cuts Cut positions for divide operations * @return A list of sublists of list according to the given cut positions * @see #divideList(List, Integer...) */ public static List> divideObjectList(List list, Integer... cuts) { return divideList(list, cuts); } public static List> randomPartition(List coll, int number){ List> checkResult = checkPartitionConditions(coll, number); if(checkResult!=null) return checkResult; HashList cuts = new HashList(); while(cuts.size()0 && nextInt List> exponentialPartition(List coll, int number){ List> checkResult = checkPartitionConditions(coll, number); if(checkResult!=null) return checkResult; HashList cuts = new HashList(); Double factor = Math.max(3.0, 3.0 + (3.0-number))/Math.max(3, 3.0 + (number-3.0)); for(int i=-1; i>(-1)*number; i--){ int cut = (int) Math.ceil(Math.exp(factor*i)*coll.size()); if(cut == coll.size() || (!cuts.isEmpty() && cut==cuts.get(cuts.size()-1))) cut -= 1; cuts.add(cut); } return divideList(coll, cuts.toArray(new Integer[1])); } private static List> checkPartitionConditions(List coll, int number){ if(coll==null || coll.isEmpty() || number<1 || number>coll.size()) throw new IllegalArgumentException(); if(number==1){ List> result = new ArrayList>(); result.add(coll); return result; } if(number == coll.size()) return divideAsList(coll); return null; } /** * Returns a list of lists containing exactly one element of the given list each. * @param coll The list to split * @return A list of lists containing exactly one element of the given list each. */ public static List> divideAsList(List coll){ List> result = new ArrayList>(); for(T t: coll){ ArrayList list = new ArrayList(); list.add(t); result.add(list); } return result; } /** * Returns a new list containing all elements of the original list with an index in [from;to] * @param Type of list elements * @param list Basic list for operation * @param from Start-index (inclusive) for copy operation * @param to End-index (inclusive) for copy operation * @return The sublist of list starting at index from and ending at index to */ public static List copyOfRange(List list, int from, int to) { if(from<0 || from >=list.size() || to<0 || to>=list.size() || from>to) throw new IllegalArgumentException("Illegal extraction bounds"); ArrayList result = new ArrayList(to-from+1); for(int i=from; i<=to; i++) result.add(list.get(i)); return result; } /** * Returns a copy of the given list. * @param Type of list elements * @param list List to copy * @return Copy of list containing the same elements */ public static List copyOf(List list) { ArrayList result = new ArrayList(list.size()); result.addAll(list); return result; } /** * Returns a string list representation of the given list. * @param coll List to convert * @return A list containing string representations for all elements of the input list. */ public static List asStringList(List coll){ List result = new ArrayList(); for(Object t: coll){ result.add(t.toString()); } return result; } public static String toString(List coll, char delimiter){ StringBuilder builder = new StringBuilder(); for(int i=0; i Type of list elements * @param list Basic list for permutations * @return Iterator holding all possible permutations */ public static ListPermutations getPermutations(List list){ return new ListPermutations(list); } public static List> getPartitions(List list, Integer... elementCounts){ int totalCount = 0; for(Integer elements: elementCounts) totalCount += elements; if(totalCount!=list.size()) return null; Integer[] cuts = new Integer[elementCounts.length-1]; for(int i=0; i> result = new ArrayList>(); Iterator> permutations = getPermutations(list); while(permutations.hasNext()){ Partition part = new Partition(list); List> dividedList = divideList(permutations.next(), cuts); for(List l: dividedList) part.addSubset(l); result.add(part); } return result; } /** * Generates a random sublist of list, that contains at most maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param maxCount Maximum number of items * @return A sublist with at most maxCount elements */ public static List getRandomSublistMax(List list, int maxCount){ int count = rand.nextInt(maxCount)+1; return getRandomSublist(list, count); } /** * Generates a random sublist of list, that contains at least maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param minCount Minimum number of items * @return A sublist with at least minCount elements */ public static List getRandomSublistMin(List list, int minCount){ int count = RandomUtils.randomIntBetween(minCount, list.size()); return getRandomSublist(list, count); } /** * Generates a random sublist of list, that contains exactly maxCount elements. * @param Type of list elements * @param list Basic list for operation * @param count Number of items * @return A sublist with exactly count elements */ public static List getRandomSublist(List list, int count){ List result = new ArrayList(); ArrayList opSet = new ArrayList(list); while(result.size() Type of list elements. */ public static class ListPermutations extends Permutations> { private List list; public ListPermutations(List list) { super(list.size()); this.list = list; } /** * Returns a new list with permuted elements. * @return A new list with permuted elements */ @Override public List next() { Integer[] next = super.nextPermutation(); List newList = new ArrayList(); for (int i = 0; i < next.length; i++) { newList.add(i, list.get(next[i])); } return newList; } } public static class Partition { private List basicSet = null; private List> subsets = new ArrayList>(); private int elements = 0; public Partition(List basicSet){ this.basicSet = basicSet; } public List getSubset(int index){ return subsets.get(index); } public void addSubset(List subset){ if(basicSet.containsAll(subset) && (elements+subset.size())<=basicSet.size()){ subsets.add(subset); elements += subset.size(); } } @Override public String toString(){ StringBuilder builder = new StringBuilder(); for(List subset: subsets){ builder.append(subset); builder.append(' '); } return builder.toString(); } } public static List> getKElementaryLists(List list, int k) { // OLD METHOD: // Is way slower than the new one and needs bit count calculation // The usage of integer or long restricts the applicability to input list sizes < 63! // if(list.size()<0) // throw new IllegalArgumentException("set size 0"); // List> result = new ArrayList>(); // for (int i = 0; i < Math.pow(2, list.size()); i++) { // int setSize = Integer.bitCount(i); // if(setSize == k){ // List newList = new ArrayList(setSize); // result.add(newList); // for (int j = 0; j < list.size(); j++) { // if ((i & (1 << j)) != 0) { // newList.add(list.get(j)); // } // } // } // } // return result; List> result = new ArrayList>(); CombinationsCalculator calc = new CombinationsCalculator(list, k); while(calc.hasNext()){ result.add(Arrays.asList(calc.next())); } return result; } public static List> getBiPartitions(List input, int sizeOfFirstPartition){ List> result = new ArrayList>(); boolean reverse = input.size()-sizeOfFirstPartition> r = rek(input, 0, input.size()-1-sizeOfFirstPartition, Math.min(sizeOfFirstPartition, input.size()-sizeOfFirstPartition)-1,""); for(List l: r){ Partition part = new Partition(input); if(reverse){ part.addSubset(ListUtils.getListWithout(input, l)); part.addSubset(l); } else { part.addSubset(l); part.addSubset(ListUtils.getListWithout(input, l)); } result.add(part); } return result; } public static List> rek(List input, int startIndex, int endIndex, int number, String header){ // System.out.println(header+"call("+startIndex+", "+endIndex+", "+number+")"); // System.out.println(header+"start: "+startIndex+", end: "+endIndex+", number: "+number); // System.out.println(input + " " + itemIndex); List> result = new ArrayList>(); if(number==0){ // System.out.println(header+"return trivial result"); for(int i=startIndex; i newList = new ArrayList(); newList.add(input.get(i)); result.add(newList); // System.out.println(header+"add: "+newList); } } else { // // System.out.println(header+"go deeper"); for(int i=startIndex; i<=endIndex; i++){ // System.out.println(header+"i = "+i); T head = input.get(i); // System.out.println(header+"head: "+head); List> rekResult = rek(input, i+1, endIndex+1, number-1, header+" "); for(List list: rekResult){ List newList = new ArrayList(Collections.singletonList(head)); newList.addAll(list); result.add(newList); // System.out.println(header+"add: "+newList); } } } // System.out.println(header+"return "+result); return result; } private static void precompileBitCountNumbers() throws IOException{ int power = 63; int maxBitCount = 5; Map writers = new HashMap(); Map counters = new HashMap(); for(int i=2; i<=maxBitCount; i++){ FileWriter newWriter = new FileWriter(System.getProperty("user.dir") + "/bitCount" + i + "Numbers"); // newWriter.writeLine("long[] bitCount"+i+"Numbers = {"); writers.put(i, newWriter); counters.put(i, 0L); } for(long i=1L; i < Math.pow(2, power) - 1; i++){ long bitCount = Long.bitCount(i); for(int j=2; j<=maxBitCount; j++){ if(j >= power) break; if(bitCount == j){ counters.put(j, counters.get(j) + 1); writers.get(j).writeLine(i); // if(counters.get(j) > 1 && counters.get(j) % 10 == 0){ // writers.get(j).writeLine('+'); // } continue; } } if(i % 10000000L == 0) System.out.println(i / (Long.MAX_VALUE + 0.0)); } for(FileWriter writer: writers.values()){ // writer.writeLine("};"); writer.closeFile(); } } }