有没有办法在搜索字谜时保持单词的大小写书写?
Is there a way to keep the upper and lower case writing of words when searching for anagrams?
我需要编写一个程序,将整个文本文件读入一个字符串并在其中搜索字谜。输出必须是同一类型的所有变位词,并在单独的一行中显示其原始大小写。
我试过以下方法,但没有给我想要的结果(显然都是小写):
String input = inputStringBuilder.toString();
input = input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", "").toLowerCase();
String[] sentence = input.split(" ");
Map<String, Set<String>> anagrams = new HashMap<>();
for(int i = 0; i < sentence.length; i++){
char[] charwords = sentence[i].toCharArray();
Arrays.sort(charwords);
String key = new String(charwords);
Set<String> anagramSet = anagrams.get(key);
if (anagramSet == null) {
anagramSet = new HashSet<>();
anagrams.put(key, anagramSet);
}
anagramSet.add(sentence[i]);
}
首先你需要移动 toLowerCase()
调用。
input = input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", ""); // <== Removed from here
String[] sentence = input.split(" ");
Map<String, Set<String>> anagrams = new HashMap<>();
for(int i = 0; i < sentence.length; i++){
char[] charwords = sentence[i].toLowerCase().toCharArray(); // <== Added here
Arrays.sort(charwords);
String key = new String(charwords);
Set<String> anagramSet = anagrams.get(key);
if (anagramSet == null) {
anagramSet = new HashSet<>();
anagrams.put(key, anagramSet);
}
anagramSet.add(sentence[i]);
}
接下来,您需要从 anagrams
映射中删除不包含任何实际字谜的条目。
问题代码中完全缺少此步骤,其中 Set
大小为 1 的映射条目不是实际的字谜。
现在 Set
包含原始大小写的单词,可能会出现 "The"
和 "the"
等非字谜,并且也必须消除,假设没有 真实字谜。如果有真正的变位词,则应保留各种大小写变体。
要检查这一点,请将所有单词添加到一个小写的集合,如果这个新集合的大小为 1,则将其删除,否则保留保留大小写的集合。
// code from above here
for (Iterator<Set<String>> iter = anagrams.values().iterator(); iter.hasNext(); ) {
Set<String> words = iter.next();
if (words.size() == 1) {
iter.remove(); // Not anagram: Single spelling only
} else {
Set<String> lower = new HashSet<>();
for (String word : words)
lower.add(word.toLowerCase());
if (lower.size() == 1) {
iter.remove(); // Not anagram: Multiple case variants, but all same spelling
}
}
}
测试
Input: This is a test of 'the' and 'The'
Result: {}
Input: This is a test of 'the', 'The', and 'eth'
Result: {eht=[the, The, eth]}
如果您不想保留同一个单词的所有大小写变体,则只需使用 new TreeSet<>(String.CASE_INSENSITIVE_ORDER)
.[=] 使集合不区分大小写。 22=]
(代码精简,部分使用了Java8个特征)
Map<String, Set<String>> anagrams = new HashMap<>();
for (String word : input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", "").split(" ")) {
char[] letters = word.toLowerCase().toCharArray();
Arrays.sort(letters);
String key = new String(letters);
anagrams.computeIfAbsent(key, k -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER))
.add(word);
}
anagrams.values().removeIf(words -> words.size() == 1);
测试
Input: This is a test of 'the' and 'The'
Result: {}
Input: This is a test of 'the', 'The', and 'eth'
Result: {eht=[eth, the]}
Input: This is a test of 'The', 'the', and 'eth'
Result: {eht=[eth, The]}
我需要编写一个程序,将整个文本文件读入一个字符串并在其中搜索字谜。输出必须是同一类型的所有变位词,并在单独的一行中显示其原始大小写。
我试过以下方法,但没有给我想要的结果(显然都是小写):
String input = inputStringBuilder.toString();
input = input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", "").toLowerCase();
String[] sentence = input.split(" ");
Map<String, Set<String>> anagrams = new HashMap<>();
for(int i = 0; i < sentence.length; i++){
char[] charwords = sentence[i].toCharArray();
Arrays.sort(charwords);
String key = new String(charwords);
Set<String> anagramSet = anagrams.get(key);
if (anagramSet == null) {
anagramSet = new HashSet<>();
anagrams.put(key, anagramSet);
}
anagramSet.add(sentence[i]);
}
首先你需要移动 toLowerCase()
调用。
input = input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", ""); // <== Removed from here
String[] sentence = input.split(" ");
Map<String, Set<String>> anagrams = new HashMap<>();
for(int i = 0; i < sentence.length; i++){
char[] charwords = sentence[i].toLowerCase().toCharArray(); // <== Added here
Arrays.sort(charwords);
String key = new String(charwords);
Set<String> anagramSet = anagrams.get(key);
if (anagramSet == null) {
anagramSet = new HashSet<>();
anagrams.put(key, anagramSet);
}
anagramSet.add(sentence[i]);
}
接下来,您需要从 anagrams
映射中删除不包含任何实际字谜的条目。
问题代码中完全缺少此步骤,其中 Set
大小为 1 的映射条目不是实际的字谜。
现在 Set
包含原始大小写的单词,可能会出现 "The"
和 "the"
等非字谜,并且也必须消除,假设没有 真实字谜。如果有真正的变位词,则应保留各种大小写变体。
要检查这一点,请将所有单词添加到一个小写的集合,如果这个新集合的大小为 1,则将其删除,否则保留保留大小写的集合。
// code from above here
for (Iterator<Set<String>> iter = anagrams.values().iterator(); iter.hasNext(); ) {
Set<String> words = iter.next();
if (words.size() == 1) {
iter.remove(); // Not anagram: Single spelling only
} else {
Set<String> lower = new HashSet<>();
for (String word : words)
lower.add(word.toLowerCase());
if (lower.size() == 1) {
iter.remove(); // Not anagram: Multiple case variants, but all same spelling
}
}
}
测试
Input: This is a test of 'the' and 'The'
Result: {}
Input: This is a test of 'the', 'The', and 'eth'
Result: {eht=[the, The, eth]}
如果您不想保留同一个单词的所有大小写变体,则只需使用 new TreeSet<>(String.CASE_INSENSITIVE_ORDER)
.[=] 使集合不区分大小写。 22=]
(代码精简,部分使用了Java8个特征)
Map<String, Set<String>> anagrams = new HashMap<>();
for (String word : input.replaceAll("[^äÄöÖüÜßa-zA-Z ]", "").split(" ")) {
char[] letters = word.toLowerCase().toCharArray();
Arrays.sort(letters);
String key = new String(letters);
anagrams.computeIfAbsent(key, k -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER))
.add(word);
}
anagrams.values().removeIf(words -> words.size() == 1);
测试
Input: This is a test of 'the' and 'The'
Result: {}
Input: This is a test of 'the', 'The', and 'eth'
Result: {eht=[eth, the]}
Input: This is a test of 'The', 'the', and 'eth'
Result: {eht=[eth, The]}