Solve exercise 10

This commit is contained in:
Manuel Thalmann 2022-11-22 22:27:05 +01:00
parent 025bfa7a7f
commit c120592296

View file

@ -1,10 +1,12 @@
package ch.nuth.zhaw.exbox;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class FuzzySearchServer implements CommandExecutor {
public static List<String> names = new ArrayList<>(); // List of all names
@ -15,11 +17,24 @@ public class FuzzySearchServer implements CommandExecutor {
// each name only once (i.e. no doublettes allowed
public static void loadNames(String nameString) {
// TODO implement
BufferedReader reader = new BufferedReader(new StringReader(nameString));
String line;
try {
while ((line = reader.readLine()) != null) {
String name = line.split(";")[0];
names.add(name);
}
} catch (Exception e) {
System.err.println("An error occurred:");
System.err.println(e);
}
}
// add a single trigram to 'trigrams' index
public static void addToTrigrams(int nameIdx, String trig) {
// TODO implement
trigrams.computeIfAbsent(trig, (_name) -> new ArrayList<>()).add(nameIdx);
}
// works better for flipped and short names if " " added and lowercase
@ -29,52 +44,80 @@ public class FuzzySearchServer implements CommandExecutor {
// construct a list of trigrams for a name
public static List<String> trigramForName(String name) {
List<String> result = new ArrayList<>();
name = nomalize(name);
// TODO implement
for (int i = 0; i < name.length() - 3; i++) {
result.add(name.substring(i, i + 3));
}
return result;
}
public static void constructTrigramIndex(List<String> names) {
for (int nameIdx = 0; nameIdx < names.size(); nameIdx++) {
List<String> trigs = trigramForName(names.get(nameIdx));
for (String trig : trigs) {
addToTrigrams(nameIdx, trig);
}
}
}
private static void incCount(int cntIdx) {
Integer c = counts.get(cntIdx);
c = (c == null) ? 1 : c + 1;
counts.put(cntIdx, c);
private static void incCount(int cntIdx, Map<Integer, Integer> counts) {
int count = counts.computeIfAbsent(cntIdx, (_index) -> 0);
counts.put(cntIdx, count + 1);
}
// find name index with most corresponding trigrams
// if no trigram/name matches at all then return -1
public static int findIdx(String name) {
counts.clear();
public static int findIdx(String name, Map<Integer, Integer> counts) {
int maxIdx = -1;
// TODO implement
int maxCount = -1;
for (String trigram : trigramForName(name)) {
if (trigrams.containsKey(trigram)) {
for (int index : trigrams.get(trigram)) {
incCount(index, counts);
}
}
}
for (Entry<Integer, Integer> entry : counts.entrySet()) {
if (entry.getValue() > maxCount) {
maxCount = entry.getValue();
maxIdx = entry.getKey();
}
}
return maxIdx;
}
// finde Namen gebe "" zurück wenn gefundener Name nicht grösser als verlangter score ist.
// finde Namen gebe "" zurück wenn gefundener Name nicht grösser als verlangter
// score ist.
public static String find(String searchName, int scoreRequired) {
int found = findIdx(searchName);
Map<Integer, Integer> counts = new HashMap<>();
int found = findIdx(searchName, counts);
String foundName = "";
if (found >= 0 && score(found) >= scoreRequired) {
if (found >= 0 && score(found, counts) >= scoreRequired) {
foundName = names.get(found);
}
return foundName;
}
private static int score(int found) {
private static int score(int found, Map<Integer, Integer> counts) {
String foundName = names.get(found);
return (int) (100.0 * Math.min(counts.get(found), foundName.length()) / foundName.length());
}
public String execute(String searchName) {
int found = findIdx(searchName);
Map<Integer, Integer> counts = new HashMap<>();
int found = findIdx(searchName, counts);
if (found >= 0) {
int score = score(found);
int score = score(found, counts);
String foundName = names.get(found);
return searchName + " -> " + foundName + " " + score + "%\n";
} else {
@ -82,14 +125,6 @@ public class FuzzySearchServer implements CommandExecutor {
}
}
public static void main(String[] args) {
FuzzySearchServer fs = new FuzzySearchServer();
System.out.println(fs.execute("Kiptum Daniel"));
System.out.println(fs.execute("Daniel Kiptum"));
System.out.println(fs.execute("Kip Dan"));
System.out.println(fs.execute("Dan Kip"));
}
static {
String rangliste = "Mueller Stefan;02:31:14\n" +
"Marti Adrian;02:30:09\n" +