From b5e9480edc56924d652a1a207c7cbf7fa5b5cb92 Mon Sep 17 00:00:00 2001 From: Yannic Link Date: Wed, 19 Jan 2022 23:02:36 +0100 Subject: [PATCH] =?UTF-8?q?String-=C3=84hnlichkeit=20durch=20Jaccard-Dista?= =?UTF-8?q?nz=20ersetzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../command/commands/PlayCommand.java | 58 +++++-------------- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5b8b1b9..615b995 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,6 +30,7 @@ dependencies { implementation 'com.sedmelluq:lavaplayer:1.3.73' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' + implementation 'org.apache.commons:commons-text:1.9' implementation "net.dean.jraw:JRAW:1.1.0" diff --git a/app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java b/app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java index e5318a3..3bba353 100644 --- a/app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java +++ b/app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java @@ -5,14 +5,14 @@ import de.yannicpunktdee.yoshibot.command.YoshiCommandContext; import de.yannicpunktdee.yoshibot.main.YoshiBot; import de.yannicpunktdee.yoshibot.utils.Resources; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.entities.VoiceChannel; +import org.apache.commons.text.similarity.JaccardDistance; + import java.awt.Color; import java.io.File; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -44,6 +44,11 @@ public class PlayCommand extends YoshiCommand { sendCustomMessage(eb.build()); } else if (context.containsArgument("name")) { String requestedFile = getBestMatch(context.getArgument("name"), getAllFiles()); + if(requestedFile == null){ + sendErrorMessage(String.format("Konnte keine Audiodatei namens '%s.opus' finden!", + context.getArgument("name"))); + return false; + } File file = new File(Resources.getPathToAudioFile(requestedFile)); if (!file.isFile()) { sendErrorMessage(String.format("Konnte keine Audiodatei namens '%s.opus' finden!", @@ -68,48 +73,17 @@ public class PlayCommand extends YoshiCommand { } private String getBestMatch(String word, List choices) { - Map hammingDists = - choices.parallelStream() - .collect(Collectors.toMap(file -> file, - file -> (double) maximalMatchingChars(file, word) / - Math.max(file.length(), - word.length()))); - return hammingDists.keySet().stream() - .max((file1, file2) -> (int) Math.signum(hammingDists.get(file1) - hammingDists.get(file2))) - .orElse(choices.get(0)); - } - - private int maximalMatchingChars(String word1, String word2) { - int maxMatches = 0; - int combinedSize = word1.length() + word2.length() - 1; - char[] word1Chars = new char[combinedSize], word2Chars = new char[combinedSize]; - for (int i = 0; i < combinedSize; i++) { - if (i < word2.length()) { - word2Chars[i] = word2.charAt(i); - } else { - word2Chars[i] = '&'; + double bestScore = 1.0; + String bestMatching = null; + for(String file : choices){ + double score = (new JaccardDistance()).apply(word, file); + if(score < bestScore){ + bestScore = score; + bestMatching = file; } } - for (int i = 0; i < combinedSize; i++) { - for (int j = 0; j < combinedSize; j++) { - if (i <= j && j < i + word1.length()) { - word1Chars[j] = word1.charAt(j - i); - } else { - word1Chars[j] = '$'; - } - } - maxMatches = Math.max(getMatchingChars(word1Chars, word2Chars), maxMatches); - } - return maxMatches; - } - - private int getMatchingChars(char[] word1, char[] word2) { - int dist = 0; - assert word1.length == word2.length; - for (int i = 0; i < word1.length; i++) { - dist += word1[i] == word2[i] ? 1 : 0; - } - return dist; + + return bestMatching; } private List getAllFiles() {