projet-donnees-reparties/linda/search/basic/Searcher.java
2021-11-27 17:50:33 +01:00

67 lines
2.1 KiB
Java

package linda.search.basic;
import linda.*;
import java.util.Arrays;
import java.util.UUID;
public class Searcher implements Runnable {
private Linda linda;
public Searcher(Linda linda) {
this.linda = linda;
}
public void run() {
System.out.println("Ready to do a search");
Tuple treq = linda.read(new Tuple(Code.Request, UUID.class, String.class));
UUID reqUUID = (UUID)treq.get(1);
String req = (String) treq.get(2);
Tuple tv;
System.out.println("Looking for: " + req);
while ((tv = linda.tryTake(new Tuple(Code.Value, String.class))) != null) {
String val = (String) tv.get(1);
int dist = getLevenshteinDistance(req, val);
if (dist < 10) { // arbitrary
linda.write(new Tuple(Code.Result, reqUUID, val, dist));
}
}
linda.write(new Tuple(Code.Searcher, "done", reqUUID));
}
/*****************************************************************/
/* Levenshtein distance is rather slow */
/* Copied from https://www.baeldung.com/java-levenshtein-distance */
static int getLevenshteinDistance(String x, String y) {
int[][] dp = new int[x.length() + 1][y.length() + 1];
for (int i = 0; i <= x.length(); i++) {
for (int j = 0; j <= y.length(); j++) {
if (i == 0) {
dp[i][j] = j;
}
else if (j == 0) {
dp[i][j] = i;
}
else {
dp[i][j] = min(dp[i - 1][j - 1]
+ costOfSubstitution(x.charAt(i - 1), y.charAt(j - 1)),
dp[i - 1][j] + 1,
dp[i][j - 1] + 1);
}
}
}
return dp[x.length()][y.length()];
}
private static int costOfSubstitution(char a, char b) {
return a == b ? 0 : 1;
}
private static int min(int... numbers) {
return Arrays.stream(numbers).min().orElse(Integer.MAX_VALUE);
}
}