Java 打印列表中最长的回文
我想知道是否有人能给我指出正确的方向 我有一个超过400000字的外部文本文件,目标是打印出每一个回文字,我做到了,但现在我正试图找出如何从打印到控制台的所有回文中收集10个最长的回文,并通过将它们打印到控制台来分离前10个 如果有人能让我开始,我就一片空白 以下是我的代码:Java 打印列表中最长的回文,java,Java,我想知道是否有人能给我指出正确的方向 我有一个超过400000字的外部文本文件,目标是打印出每一个回文字,我做到了,但现在我正试图找出如何从打印到控制台的所有回文中收集10个最长的回文,并通过将它们打印到控制台来分离前10个 如果有人能让我开始,我就一片空白 以下是我的代码: import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Palindrome {
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Palindrome {
public static void main(String[] args) {
// store external text file into a new File object
File file = new File("dict.txt");
try {
// new Scanner object to read external file
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
// read each word so long as there is a word on subsequent line
String word = sc.nextLine();
// if the word is a palindrome
if (isPalindrome(word)) {
// print out the palindrome word to console
System.out.println(word + " is a palindrome");
}
}
} catch(FileNotFoundException fnfe) {
// if file is not found, print error to console
System.out.println(fnfe.toString());
}
} // end main
public static boolean isPalindrome(String word) {
// if there is no word
if (word == null || word.length() == 0) {
// return false
return false;
}
// StringBuilder to hold a variable of the reverse of each word
String reverse = new StringBuilder(word).reverse().toString();
// if the reversed word equals the original word
if (reverse.equals(word)) {
// it is a palindrome
return true;
}
// return false if no palindrome found
return false;
} // end isPalindrome
} // end class Palindrome
提前感谢您的建议 例如,您可以在一个集合中收集所有回文并按大小分组:
Map<Integer, Set<String>> palindromes = new HashMap<>();
Map palindromes=newhashmap();
找到回文后,将其添加到此处:
palindromes.computeIfAbsent(word.length(), f -> new HashSet<>()).add(word);
palindromes.computeIfAbsent(word.length(),f->newhashset()).add(word);
在循环结束时,您可以找到地图中最大的键,在该集中您可以找到单词。可能有几种方法可以实现这一点,但首先想到的是将所有回文收集到一个集合中,然后按长度排序,以找到最长的10个
因此,在
if
对isAlindrome
的块调用中,您可以将单词添加到集合中。然后在while
循环之后,对列表进行排序。我不记得为默认Javasort
方法提供自定义排序规则有多容易/难。集合和映射很好,但是如果单词列表很长,它们的内存就很昂贵。如果低n(例如,n=10)只需要top-n,则以下几点更好:
// to compare strings by reverse length, and then alphabetically
private static final Comparator<String> lengthComparator = new Comparator<String>(){
public int compare(String a, String b) {
int c = b.length() - a.length();
return c==0 ? a.compareTo(b) : c;
}
};
// to update the top-n list. Pass in an empty list at the start
public static void updateTop10(String word, ArrayList<String> top, int n) {
int index = Collections.binarySearch(top, word, lengthComparator);
System.out.println("found at " + index + ": " + word);
if (index >= 0) {
// word already in list; no need to add it
return;
} else if (top.size()<n) {
// list not full - add it in
top.add(-1-index, word);
} else if (word.length() > top.get(n-1).length()) {
// larger than smallest word in list - insert into position
top.remove(n-1);
top.add(-1-index, word);
}
}
//按反向长度比较字符串,然后按字母顺序比较
专用静态最终比较器长度比较器=新比较器(){
公共整数比较(字符串a、字符串b){
int c=b.length()-a.length();
返回c==0?a。与(b)相比:c;
}
};
//更新前n名列表。在开始时传入一个空列表
公共静态void updateTop10(字符串字、ArrayList top、int n){
int index=Collections.binarySearch(top、word、lengthComparator);
System.out.println(“在“+index+”:“+word处找到);
如果(索引>=0){
//单词已在列表中;无需添加它
返回;
}else if(top.size()top.get(n-1.length()){
//大于列表中最小的单词-插入位置
顶部。移除(n-1);
添加(-1-索引,单词);
}
}
查找速度比在集合中快(O(log(n)
)-但您的n是10),而不是字典的大小。最糟糕的情况是在前面插入,但是移动9个元素非常便宜,而且可能比TreeMap
traversal+insert要好得多。对于这个问题,我建议使用TreeSet而不是列表。给定一个自定义比较器,并对其进行排序you@cricket_007谢谢,我不是有意要特别调用任何一个数据结构。我成功地创建了这个构建(有错误),但它崩溃了。此外,比较器使用大小,因此假设两个大小相同的不同单词是同一个单词,这是不正确的。我还没有真正测试代码,而且有多个输入错误,加上比较器错误。谢谢你的帮助。以前从未使用过比较器,这看起来相当复杂。我想肯定会有一个更简单的方法来完成它,我只是有一个大脑屁不能得到它,但我想这比我预期的要难一点。不确定在何处或如何实现这样的功能。不过谢谢你…@tucuxi:是的,对空间和时间都没有要求。有许多可能的优化,可以存储前10个回文的当前最小大小,甚至不去验证一个单词是否正确。一般认为编写更高效的代码更好,包括空间和时间。因此,虽然你的答案在技术上可行,但我觉得可以改进。因此评论。