package alg.inflectedJOS; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import data.Enums.InflectedJosTypes; import data.StatisticsNew; import gui.ValidationUtil; import util.Combinations; // adapted from http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/ public class WordFormation { private static HashMap josTypeResult; private static Object[][] tmpResults; private static HashMap>> indices; static { indices = new HashMap<>(); for (int i = 4; i <= 8; i++) { indices.put(i, Combinations.generateIndices(i)); } } public static void calculateStatistics(StatisticsNew stat) { Map result = stat.getResult(); // 1. filter - keep only inflected types result.keySet().removeIf(x -> !InflectedJosTypes.inflectedJosTypes.contains(x.charAt(0))); // 2. for each inflected type get all possible subcombinations for (Character josChar : InflectedJosTypes.inflectedJosTypes) { josTypeResult = new HashMap<>(); // filter out results for a single word type Map singleTypeResults = result.entrySet().stream() .filter(x -> x.getKey().charAt(0) == josChar) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); if (ValidationUtil.isEmpty(singleTypeResults)) { continue; } // get all possible indices combos for a msd of this length // HashSet> indicesCombos = indices.get() //Combinations.generateIndices(singleTypeResults.keySet().stream().findFirst().get().length()); for (Map.Entry e : singleTypeResults.entrySet()) { int l = e.getKey().length(); for (HashSet indicesCombo : indices.get(e.getKey().length())) { updateResults(mask(e.getKey(), indicesCombo), e.getValue().longValue()); } } resultsMapToArray(singleTypeResults.values().stream().mapToLong(Number::longValue).sum()); } stat.setResultCustom(tmpResults); } private static String mask(String word, HashSet indicesCombo) { StringBuilder sb = new StringBuilder(); sb.append(word.charAt(0)); for (int i = 1; i < word.length(); i++) { sb.append(indicesCombo.contains(i) ? word.charAt(i) : "."); } return sb.toString(); } private static void updateResults(String s, Long nOfOccurences) { // if not in map add Long r = josTypeResult.putIfAbsent(s, nOfOccurences); // else update if (r != null) { josTypeResult.put(s, josTypeResult.get(s) + nOfOccurences); } } private static void resultsMapToArray(Long totalValue) { Double total = totalValue * 1.0; Object[][] josTypeResultArray = new Object[josTypeResult.size()][3]; int i = 0; for (Map.Entry e : josTypeResult.entrySet()) { josTypeResultArray[i][0] = e.getKey(); josTypeResultArray[i][1] = e.getValue(); josTypeResultArray[i][2] = e.getValue() / total; if (e.getValue() > total) { String debug = ""; } i++; } if (tmpResults == null) { tmpResults = josTypeResultArray; } else { int firstLength = tmpResults.length; int secondLength = josTypeResultArray.length; Object[][] tmp = new Object[firstLength + secondLength][3]; System.arraycopy(tmpResults, 0, tmp, 0, firstLength); System.arraycopy(josTypeResultArray, 0, tmp, firstLength, secondLength); tmpResults = tmp; // tmpResults = ArrayUtils.addAll(tmpResults, josTypeResultArray); } } private static void printArray() { for (int i = 0; i < tmpResults.length; i++) { for (int j = 0; j < tmpResults[i].length; j++) { System.out.print(tmpResults[i][j] + "\t"); } System.out.println(); } } }