Java 如何使字谜程序代码更快?(爪哇)

Java 如何使字谜程序代码更快?(爪哇),java,Java,我是一个不太有经验的程序员。我写了一个字谜程序,唯一的问题是速度不够快。有人告诉我,我的嵌套for循环是个问题,但我不知道如何解决它(set1是一个HashSet,包含了我正在处理的所有单词,map是一个LinkedHashMap和anagram aTreeMap): for(字符串元素:set1){ char[]woord=element.toCharArray();//每个单词的字母顺序 数组。排序(woord); 字符串图表显示=新字符串(woord); map.put(元素,图表);//

我是一个不太有经验的程序员。我写了一个字谜程序,唯一的问题是速度不够快。有人告诉我,我的嵌套
for循环
是个问题,但我不知道如何解决它(
set1
是一个
HashSet
,包含了我正在处理的所有单词,map是一个
LinkedHashMap
和anagram a
TreeMap
):

for(字符串元素:set1){
char[]woord=element.toCharArray();//每个单词的字母顺序
数组。排序(woord);
字符串图表显示=新字符串(woord);
map.put(元素,图表);//添加每个单词及其排序的字母
TreeSet order_words=new TreeSet();//创建字谜列表
for(字符串o:map.keySet()){//for每个单词
if(map.get(o).equals(chartostring)){//检查map中是否有一个值等于已排序的字母
对单词进行排序。添加(o);//将单词添加到字谜列表中
如果(order_words.size()>1){//我们需要字谜,所以只有在至少有2个单词时才打印
字谜.put(图表、单词顺序);
}
}
}
}

有人能帮我吗?非常感谢。

嵌套循环确实很慢,因为您像迭代列表一样迭代映射。如果可以用哈希映射中的快速查找来替换嵌套循环,那不是很好吗?不幸的是,在处理
Map
时,这不是一个选项,因为多个单词将具有相同的排序表示。这就是为什么要从一个单词到它的排序表示构建一个映射,而不是相反

但是,这意味着您可以构建从排序表示到单词列表的映射:

Map<String,List<String>> sortedRepToWords
Map-sortedRepToWords

在进行任何匹配之前,可以在单个循环中构建此映射。有了这个列表映射,您可以消除嵌套循环,用从
sortedRepToWords
中查找整个列表来替换它我不知道这对您来说是否更好,但是当我需要
映射的
键和
值时,我使用
入口集
。因此,避免了调用
get
方法,节省了一部分时间

for(字符串元素:set1){
char[]woord=element.toCharArray();//每个单词的字母顺序
数组。排序(woord);
字符串图表显示=新字符串(woord);
map.put(元素,图表);//添加每个单词及其排序的字母
TreeSet order_words=new TreeSet();//创建字谜列表
for(条目o:map.entrySet()){//for每个单词
如果(o.getValue().equals(chartostring)){//检查map中是否有一个值等于已排序的字母
order_words.add(o.getKey());//将单词添加到字谜列表中
如果(order_words.size()>1){//我们需要字谜,所以只有在至少有2个单词时才打印
字谜.put(图表、单词顺序);
}
}
}
}

如果这还不够,我认为您应该用另一个逻辑重写代码,并尝试实现dasblinkenlight的答案。如果使用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;
}
Set dict_Set=new HashSet();
Set anag_Set=new HashSet();
for(字符串元素:set1){
//对字符串中的字符进行排序。
char[]woord=element.toCharArray();
数组。排序(woord);
//如果已经遇到添加为已知的字谜
//否则,将已排序的字符集添加到字典中。
if(dict_set.contains(woord))anag_set.add(woord)
else dict_set.add(单词);
返回anag_集;
}
万一你需要所有的字谜和它的分类形式的字符串;您可以使用排序形式的映射和所有关联的字谜列表

PS:这只是一个伪代码。

介绍Java8

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());
}
import java.util.stream.stream;
导入静态java.util.stream.Collectors.*;
Map tmp=set1.parallelStream()//可能使用多个核。。。
.collect(分组方式->排序方式);//一艘客轮!
列表结果=tmp.values().stream()
.filter(l->l.size()>1)//至少2个字谜
.collect(toList());
系统输出打印LN(tmp);
系统输出打印项次(结果);
//...//
//如果您真的想使用Java8对字符串进行排序。。。
私有字符串排序(字符串输入){
返回Stream.of(input.split(“”).sorted().collect(joining());
}
//导入将帮助我们操作数组的Arrays类。
导入java.util.array;
公共类AnagramTest{
私有静态布尔isAnagram(字符串str1、字符串str2){
//将两个字符串转换为字符数组,因为字符串没有直接
//java中的排序方法。
char[]leftArray=(str1.trim().toLowerCase()).toCharArray();
char[]rightArray=(str2.trim().toLowerCase()).toCharArray();
parallelSort(leftArray);
parallelSort(rightArray);
if(leftArray.length!=rightArray.length){
返回false;
}
//两个字符数组的字符数相同
for(int i=0;i
谢谢你的评论,我会试试,我是初学者,所以我不知道所有的选项。我应该用我的内部forloop替换它还是把它放在外部?我不理解你的问题,我已经将你的代码改编为示例。。。试着把它换掉或放在外面。天哪,对不起,我明白了。谢谢我将尝试看看这是否真的解决了问题,因为我仍然会有一个嵌套的for循环,因为它是一个hashset——查找非常快,你可以去掉foorloop。这不是真的
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;
}
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());
}
// 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));     
  }         
}