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 aTreeMap
):
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));
}
}