我是一位经验不足的程序员。我写了一个字谜程序,唯一的问题是它不够快。我已经被告知我的嵌套for loop
是问题所在,但我无法确定如何修复它(set1
是一个HashSet
,其中包含所有单词I&# 39;正在处理,地图是LinkedHashMap<String, String>
和anagram a TreeMap<String, TreeSet<String>>
):
for (String element : set1) {
char[] woord = element.toCharArray(); //alfabetical order of each word
Arrays.sort(woord);
String chartostring = new String(woord);
map.put(element, chartostring); // add each word with its sorted letters
TreeSet<String> order_words = new TreeSet<String>(); //creating list of anagrams
for (String o : map.keySet()) { //for each word
if (map.get(o).equals(chartostring)) { //check if there is a value in map which is equal to the sorted letters
order_words.add(o); //add word to list of anagrams
if (order_words.size() > 1) { //we want anagrams so only print if there are atleast 2 words
anagram.put(chartostring, order_words);
}
}
}
}
有人可以帮帮我吗?非常感谢。
答案 0 :(得分:4)
嵌套循环确实很慢,因为您迭代地图就像它是一个列表一样。如果您可以在哈希映射中快速查找嵌套循环,那会不会很好?不幸的是,当您处理Map<String,String>
时,这不是一个选项,因为多个单词将具有相同的排序表示。这就是为什么你建立了一个从一个单词到它的排序表示的地图,而不是相反。
然而,这意味着您可以构建从排序表示到列表单词的地图:
Map<String,List<String>> sortedRepToWords
在进行任何匹配之前,您可以在单个循环中构建此映射。使用此映射列表,您可以消除嵌套循环,将其替换为sortedRepToWords
中整个列表的查找。
答案 1 :(得分:0)
我不知道你的情况是否更好,但当我需要key
的{{1}}和value
时,我会使用map
。因此,entrySet
方法的调用被避免,并且节省了一部分时间......
https://stackoverflow.com/a/3870210/1811730
get
如果还不够,我认为你应该用另一个逻辑重写代码并尝试实现dasblinkenlight的答案
答案 2 :(得分:0)
如果使用HashSet,则可以按1(单循环)的顺序执行此操作。
Set<char[]> dict_set = new HashSet<char[]>();
Set<char[]> anag_set = new HashSet<char[]>();
for (String element : set1) {
// Sort the characters in string.
char[] woord= element.toCharArray();
Arrays.sort(woord);
//if already encountered add as a known anagram
//else add the sorted charset to the dictionary.
if (dict_set.contains(woord)) anag_set.add(woord)
else dict_set.add(word);
return anag_set;
}
你需要所有字符串作为字谜及其sortform;你可以使用排序表格的地图和所有相关字谜的列表。
PS:它只是一个伪代码。
答案 3 :(得分:0)
介绍Java 8 ...
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
Map<String, List<String>> tmp = set1.parallelStream() // Possibly using multiple cores...
.collect(groupingBy(s-> sortMe(s))); // One liner!
List<List<String>> result = tmp.values().stream()
.filter(l -> l.size() > 1) // At least 2 anagrams
.collect(toList());
System.out.println(tmp);
System.out.println(result);
//...//
// If you really want to use Java 8 for sorting a String...
private String sortMe(String input) {
return Stream.of(input.split("")).sorted().collect(joining());
}
答案 4 :(得分:0)
// Importing the Arrays class that will help us manipulate arrays.
import java.util.Arrays;
public class AnagramTest {
private static boolean isAnagram(String str1 , String str2){
// Converting both strings to char arrays as strings do not have direct
// sorting method in java.
char [] leftArray = ( str1.trim().toLowerCase()).toCharArray();
char [] rightArray = ( str2.trim().toLowerCase()).toCharArray();
Arrays.parallelSort(leftArray);
Arrays.parallelSort(rightArray);
if(leftArray.length != rightArray.length){
return false;
}
// Both char arrays have the same number of characters
for(int i = 0; i < leftArray.length; i++){
if(leftArray[i] != rightArray[i]){
return false;
}
}
// We only get to this stage if all the elements pass the if test
return true;
}
public static void main(String [] args){
String a = "integral"; // initializing first string
String b = "Triangle"; // initializing second string
System.out.println(isAnagram(a,b));
}
}