diff --git a/app/src/main/java/ch/nuth/zhaw/exbox/FuzzySearchServer.java b/app/src/main/java/ch/nuth/zhaw/exbox/FuzzySearchServer.java new file mode 100644 index 0000000..c4be5d0 --- /dev/null +++ b/app/src/main/java/ch/nuth/zhaw/exbox/FuzzySearchServer.java @@ -0,0 +1,107 @@ +package ch.nuth.zhaw.exbox; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class FuzzySearchServer implements CommandExecutor { + public static List names = new ArrayList<>(); // List of all names + public static Map> trigrams = new HashMap<>(); // List of all Trigrams + public static Map counts = new HashMap<>(); // Key: index of + + // load all names into names List + // each name only once (i.e. no doublettes allowed + public static void loadNames(String nameString) { + // TODO implement + } + + // add a single trigram to 'trigrams' index + public static void addToTrigrams(int nameIdx, String trig) { + // TODO implement + } + + // works better for flipped and short names if " " added and lowercase + private static String nomalize(String name) { + return " " + name.toLowerCase().trim() + " "; + } + + // construct a list of trigrams for a name + public static List trigramForName(String name) { + name = nomalize(name); + // TODO implement + } + + public static void constructTrigramIndex(List names) { + for (int nameIdx = 0; nameIdx < names.size(); nameIdx++) { + List 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); + } + + // 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(); + int maxIdx = -1; + // TODO implement + return maxIdx; + } + // 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); + String foundName = ""; + if (found >= 0 && score(found) >= scoreRequired) { + foundName = names.get(found); + } + return foundName; + } + + private static int score(int found) { + 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); + if (found >= 0) { + int score = score(found); + String foundName = names.get(found); + return searchName + " -> " + foundName + " " + score + "%\n"; + } else { + return "nothing found\n"; + } + } + + 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" + + "Kiptum Daniel;02:11:31\n" + + "Ancay Tarcis;02:20:02\n" + + "Kreibuhl Christian;02:21:47\n" + + "Ott Michael;02:33:48\n" + + "Menzi Christoph;02:27:26\n" + + "Oliver Ruben;02:32:12\n" + + "Elmer Beat;02:33:53\n" + + "Kuehni Martin;02:33:36\n"; + loadNames(rangliste); + constructTrigramIndex(names); + } +} diff --git a/app/src/test/java/ch/nuth/zhaw/exbox/ADS10_3_test.java b/app/src/test/java/ch/nuth/zhaw/exbox/ADS10_3_test.java new file mode 100644 index 0000000..027d44c --- /dev/null +++ b/app/src/test/java/ch/nuth/zhaw/exbox/ADS10_3_test.java @@ -0,0 +1,68 @@ +package ch.nuth.zhaw.exbox; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author K Rege + * @version 1.00 2018/3/17 + * @version 1.01 2021/8/1 + */ +public class ADS10_3_test { + @BeforeEach + void init() { + FuzzySearchServer.names.clear(); + FuzzySearchServer.trigrams.clear(); + String rangliste = "Mueller Stefan;02:31:14\n" + + "Marti Adrian;02:30:09\n" + + "Kiptum Daniel;02:11:31\n" + + "Ancay Tarcis;02:20:02\n" + + "Kreibuhl Christian;02:21:47\n" + + "Ott Michael;02:33:48\n" + + "Menzi Christoph;02:27:26\n" + + "Oliver Ruben;02:32:12\n" + + "Elmer Beat;02:33:53\n" + + "Kuehni Martin;02:33:36\n"; + FuzzySearchServer.loadNames(rangliste); + } + + @Test + public void testLoadNames() { + assertEquals(10, FuzzySearchServer.names.size(), "Länge von 'names' Liste"); + assertEquals("Mueller Stefan", FuzzySearchServer.names.get(0), "Erster Name"); + } + + @Test + public void testTrigramForName() { + List trigList = FuzzySearchServer.trigramForName("Heinz"); + assertEquals(5, trigList.size(), "Länge von Trigram Liste"); + String[] good = {" he", "hei", "ein", "inz", "nz "}; + for (int i = 0; i < good.length; i++) { + assertEquals(good[i], trigList.get(i), "trigram [" + i + "]"); + } + } + + @Test + public void testAddToTrigrams() { + FuzzySearchServer.addToTrigrams(0, "mue"); + FuzzySearchServer.addToTrigrams(0, "uel"); + FuzzySearchServer.addToTrigrams(1, "mar"); + assertEquals(3, FuzzySearchServer.trigrams.size(), "Länge von 'trigram'"); + assertEquals(0, FuzzySearchServer.trigrams.get("mue").get(0), "mue"); + assertEquals(0, FuzzySearchServer.trigrams.get("uel").get(0), "uel"); + assertEquals(1, FuzzySearchServer.trigrams.get("mar").get(0), "mar"); + } + + @Test + public void testFind() { + FuzzySearchServer.constructTrigramIndex(FuzzySearchServer.names); + assertEquals("Kiptum Daniel", FuzzySearchServer.find("Kiptum Daniel", 80)); + assertEquals("Kiptum Daniel", FuzzySearchServer.find("Daniel Kiptum", 80)); + assertEquals("Kiptum Daniel", FuzzySearchServer.find("Kip Dan", 30)); + assertEquals("Kiptum Daniel", FuzzySearchServer.find("Dan Kip", 30)); + } +}