如何更快地制作anagram程序代码? (JAVA)

时间:2016-10-11 14:06:47

标签: java

我是一位经验不足的程序员。我写了一个字谜程序,唯一的问题是它不够快。我已经被告知我的嵌套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);
            }
        }
    }
}

有人可以帮帮我吗?非常感谢。

5 个答案:

答案 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));     
  }         
}