[英]How to compare character input by user to dictionary file in Java?
我需要阅读用户输入并将其与dictionary.txt.
进行比较dictionary.txt.
用户可以输入任意数量的字符,并且程序必须返回可以由这些字符组成的所有英语单词。 这些字母可以以任何顺序使用,并且只能使用一次。 例如:
用户输入 :“ odg”
输出: “狗”,“神” ...以及其他任何东西
经过大量的研究,我提出了以下部分解决方案:
-1
的单词 如何将用户输入的一组字符与文本文件(字典)中的字符进行比较? 字符不必以任何顺序进行匹配。 (如上面的示例所示)
在这里忍受,我知道这一定是执行此任务的最无效的方法之一! 我们将不胜感激关于如何实现我的原始想法的任何其他想法,同时我也愿意接受任何新的更有效的方法来执行此操作。
以下是我到目前为止提出的内容:
public static void main(String[] args) throws FileNotFoundException {
BufferedReader reader1 = new BufferedReader(new FileReader(FILENAME));
Scanner sc = new Scanner(System.in);
String line;
ArrayList<String> match = new ArrayList<>();
System.out.println("Enter characters to see which english words match: ");
String userInput = sc.next();
char arr[] = userInput.toCharArray();
int i;
try {
while ((line = reader1.readLine()) != null) {
for (i=0; i < arr.length; i++)
{
if ((line.indexOf(userInput.charAt(i)) != -1) && (line.length() == arr.length)) {
match.add(line);
}
else {
// System.out.println("no matches");
}
}
}
System.out.println(match);
}
catch (IOException e) {
e.printStackTrace();
}
**当前结果:**
文字档中的字词:
cab
dog
god
back
dogs
quick
用户输入:“ odg”
程序输出:
[god, god, god, dog, dog, dog]
该程序应返回字典中的所有单词,这些单词可以由用户输入的字符串组成,在这种情况下,我将设法返回两个实例,但是每个实例都显示3次(arr.length)。
首先,有趣的问题。 我实施了我的解决方案和Ole VV的解决方案。 这是基于您的帖子的代码。 我测试了您提供的唯一测试用例,不确定是否是您想要的。 让我知道它是否无法按预期工作。
解决方案一:计算O(nk)
public static void main(String[] args) throws IOException {
BufferedReader reader1 = new BufferedReader(new FileReader(FILENAME));
Scanner sc = new Scanner(System.in);
System.out.println("Enter characters to see which english words match: ");
String userInput = sc.next();
Map<Character, Integer> counter = count(userInput);
String line;
while ((line = reader1.readLine()) != null) {
Map<Character, Integer> lineCounter = count(line);
if(lineCounter.equals(counter)) {
System.out.println(line);
}
}
}
public static Map<Character, Integer> count(String input) {
Map<Character, Integer> result = new HashMap<Character, Integer>();
for (char c: input.toCharArray()) {
result.putIfAbsent(c, 0);
result.put(c, result.get(c) + 1);
}
return result;
}
解决方案二:排序O(nk)
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(FILENAME));
Scanner sc = new Scanner(System.in);
System.out.println("Enter characters to see which english words match: ");
String userInput = sc.next();
userInput = sort(userInput);
String line;
while ((line = reader.readLine()) != null) {
String sortedLine = sort(line);
if(sortedLine.equals(userInput)) {
System.out.println(new String(line));
}
}
}
// counting sort
public static String sort(String input) {
char c[] = input.toCharArray();
int length = c.length;
char output[] = new char[length];
int count[] = new int[256];
for (int i = 0; i < length; i++) {
count[c[i]] = count[c[i]] + 1;
}
for (int i = 1; i <= 255; i++) {
count[i] += count[i - 1];
}
for (int i = 0; i < length; i++) {
output[count[c[i]] - 1] = c[i];
count[c[i]] = count[c[i]] - 1;
}
return new String(output);
}
此类问题的标准解决方案是:对用户输入的字符进行排序。 因此, odg
将成为dgo
和back
会变得abck
。 对于字典中的每个单词,进行相同的排序。 因此cab
将变为abc
而dog
将为dgo
嘿,这与第一个用户输入相同,因此现在我们知道应该输出该单词了。
此解决方案的优点是您确保每个字母都使用一次。 它甚至会考虑重复的字母:如果相同的字母在用户输入中出现两次,它将仅查找也包含该字母两次的单词。
如果愿意,您可以通过构建地图来预先准备单词列表,其中的键是按字母顺序排序的单词,值是包含这些相同字母的单词的列表。 因此密钥dgo
将映射到[dog, god]
的列表。 然后,您只需要对输入进行排序并进行查找。
我将向您展示一个易于理解和实施的解决方案,但不是最快的解决方案:
可能的解决方案 :数组排序
将输入字符串和字典单词视为char数组,对其进行排序,然后进行比较:
public static boolean stringsMatchSort(String a, String b) {
// Different length? Definitely no match!
if (a.length() != b.length()) {
return false;
}
// Turn both Strings to char arrays
char[] charsA = a.toCharArray();
char[] charsB = b.toCharArray();
// Sort both arrays
Arrays.sort(charsA);
Arrays.sort(charsB);
// Compare them, if equal: match!
return Arrays.equals(charsA, charsB);
}
请注意我是如何将您的程序/问题的实质变成一种方法的。 然后,您可以在循环访问字典中所有单词的循环中轻松使用该方法。 该方法并不关心单词的来源:文件,集合,其他用户输入,网络等。
通过将程序划分为各个较小的部分,每个部分的责任较小,也有助于简化程序。 这通常称为分而治之,对于处理复杂的问题,无论对于新老程序员,这都是最有价值的策略之一。
其他解决方案 :质数,HashMaps,...
还有其他(包括更快,更优雅)的解决方案。 看一下这些相关的问题,您的问题几乎是以下问题的重复:
根据您的应用程序,最好先将字典读入合适的集合中,这是一个好主意。 如果您对同一个字典执行多个“查询”,这将特别有用。 或者,如果字典真的很大,那么您可以在创建集合的过程中删除重复项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.