You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.7 KiB
132 lines
3.7 KiB
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<String, Long> josTypeResult;
|
|
private static Object[][] tmpResults;
|
|
|
|
private static HashMap<Integer, HashSet<HashSet<Integer>>> 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<String, AtomicLong> 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<String, AtomicLong> 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<HashSet<Integer>> indicesCombos = indices.get()
|
|
//Combinations.generateIndices(singleTypeResults.keySet().stream().findFirst().get().length());
|
|
|
|
for (Map.Entry<String, AtomicLong> e : singleTypeResults.entrySet()) {
|
|
int l = e.getKey().length();
|
|
|
|
for (HashSet<Integer> 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<Integer> 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<String, Long> 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();
|
|
}
|
|
}
|
|
}
|