Java 检查和打印字谜时的IndexOutOfBoundsException
我有一组如下类型的输入字符串Java 检查和打印字谜时的IndexOutOfBoundsException,java,Java,我有一组如下类型的输入字符串 String[] arr = {"pear", "amleth", "dormitory", "tinsel", "dirty room", "hamlet", "listen", "silent"}; 我需要编写一个程序来检查这些字符串中的哪些是字谜,并将它们打印在一个逗号分隔的列表中,按字典顺序排序。因此,预期产出是有限的 amleth, hamlet dirty room, dormitory 这是我的密码 public class Main {
String[] arr = {"pear", "amleth", "dormitory", "tinsel", "dirty room", "hamlet", "listen", "silent"};
我需要编写一个程序来检查这些字符串中的哪些是字谜,并将它们打印在一个逗号分隔的列表中,按字典顺序排序。因此,预期产出是有限的
amleth, hamlet
dirty room, dormitory
这是我的密码
public class Main {
static void checkPrintAnagrams(String[] str){
List<List<String>> out = new ArrayList<>();
int[] check = new int[str.length];
for(int i = 0; i < str.length; i++){
List<String> list = new ArrayList<>();
for(int j= 1; j < str.length; j++){
if(check[j] != 1 && check[i] != 1){
if(isAnagram(str[i], str[j])){
list.add(str[i]);
list.add(str[j]);
check[j] = 1;
check[i] = 1;
}
}
}
out.add(list);
}
Collections.sort(out, new Comparator<List<String>> () {
@Override
public int compare(List<String> a, List<String> b) {
return a.get(1).compareTo(b.get(1));
}
});
for(Iterator itr = out.iterator(); itr.hasNext();){
List<String> l = (List<String>) itr.next();
for(Iterator it = l.iterator(); it.hasNext();){
System.out.print(it.next() + ",");
}
System.out.println();
}
}
static boolean isAnagram(String firstWord, String secondWord) {
char[] word1 = firstWord.replaceAll("[\\s]", "").toCharArray();
char[] word2 = secondWord.replaceAll("[\\s]", "").toCharArray();
Arrays.sort(word1);
Arrays.sort(word2);
return Arrays.equals(word1, word2);
}
public static void main(String[] args) {
// write your code here
String[] arr = {"pear", "amleth", "dormitory", "tinsel", "dirty room", "hamlet", "listen", "silent"};
checkPrintAnagrams(arr);
}
}
如果您能帮助理解
集合排序
部分,以及如何在此上下文中正确实现它,将不胜感激。您可以使用流
并创建映射
您所需要做的就是将数据按一些标准化值分组:
- 删除所有空格
- 按字母顺序排列字符
- 创建一个
字符串
简单:
Map<String, List<String>> anagrams = Stream.of(arr).collect(groupingBy(s -> {
char[] chars = s.replaceAll("\\s", "").toCharArray();
Arrays.sort(chars);
return new String(chars);
}));
输出:
eilnst的字谜-[金属丝,倾听,沉默]
dimoorrty的字谜-[宿舍,脏房间]
aehlmt的字谜-[amleth,hamlet]
aepr-[梨]的字谜
如果您不理解代码,请在代码中添加注释和打印语句;这将帮助你理解它。因此,您理解该代码的问题是:
如果要从一个数组中生成所有可能的对,可以使用两个循环
String[] arr = {"pear", "amleth", "dormitory", "tinsel", "dirty room", "hamlet", "listen", "silent"};
// Comment: first loop, the outer loop, iterates from 0 to length
for ( int i=0, il = arr.length; i<il; ++i ) {
// Comment: second loop, the inner loop, iterates from
// the starting position of the first loop to length
for( int j=i, jl=arr.length; j<jl; ++j ) {
System.out.println("S1="+arr[i]+":S2="+arr[j]);
}
}
String[]arr={“pear”、“amleth”、“宿舍”、“金属片”、“脏房间”、“哈姆雷特”、“听着”、“沉默”};
//注释:第一个循环,即外部循环,从0到长度进行迭代
对于(inti=0,il=arr.length;i这里有一些指导,而不是一个完整的解决方案,因为您需要一些理解
首先,错误跟踪准确地显示了错误的内容和位置,只是有点模糊
at io.soumasish.Main.checkPrintAnagrams(Main.java:28)
是您编写的调用跟踪中的最后一行。从上到下到该行的所有内容都在您调用的库代码中。因此,问题出在Main.java文件的第28行。我猜是这一行:
return a.get(1).compareTo(b.get(1));
那么这段代码中发生了什么呢?首先,变量a
和b
的类型是List
,每个compare()
方法的签名都是get()列表
上的
方法接受一个整数参数,在本例中返回一个字符串
。整数参数是列表
的索引。关键是:索引是0-relative,这意味着您在请求列表
中的第二个元素。引发的异常指示至少在在a
和b
中的一个元素中,没有第二个元素。它包含零个或一个元素
那么我该怎么处理比较器呢?
是的,这就是问题所在。所以想一想:你会如何对两个列表进行排序?我猜你会想这样做:
- 如果两个列表都为空,则返回0(相等)
- 如果只有a为空,则返回-1(小于)
- 如果只有b为空,则返回1(大于)
- 如果它们都有元素,请检查第一个元素
- 如果第一个元素不相同,则返回这些元素的比较结果
- 如果一个列表只有一个元素,则返回(-1或1,具体取决于)
- 检查第二个元素
诸如此类。我相信,你可以把它转换成一个合适的算法
底线
您需要使用比较器
,以便它正确地比较两个类型为列表
的对象,这两个对象可能具有任意数量的元素
我已经实现了下面的compare()
方法。我试着编写它,以使基本思想清晰明了
public int compare(List<String> a, List<String> b) {
int aSize = a.size();
int bSize = b.size();
int index = 0;
while (index < aSize && index < bSize) {
String aStr = a.get(index);
String bStr = b.get(index);
int comp = aStr.compareTo(bStr);
if (comp != 0)
return comp;
index++;
}
return aSize < bSize ? -1 : (aSize > bSize ? 1 : 0);
}
public int比较(列表a、列表b){
int aSize=a.size();
int bSize=b.size();
int指数=0;
while(索引bSize-1:0);
}
您可能会注意到,您的逻辑中仍然存在问题,但至少例外情况消失了。:-您的程序不是完全正确的,因为它不会检测到像“blob”、“bobl”、“lobb”这样的三个字谜的存在,尽管我欣赏这种方法,如果你能帮我修改我的方法并理解我在排序部分做错了什么,那真的会很有帮助。我试着按照你的算法修改我的比较器,但仍然不起作用。您希望我更新这个问题,但这会改变上下文,或者如果您可以编写几行代码,这会有所帮助。
return a.get(1).compareTo(b.get(1));
public int compare(List<String> a, List<String> b) {
int aSize = a.size();
int bSize = b.size();
int index = 0;
while (index < aSize && index < bSize) {
String aStr = a.get(index);
String bStr = b.get(index);
int comp = aStr.compareTo(bStr);
if (comp != 0)
return comp;
index++;
}
return aSize < bSize ? -1 : (aSize > bSize ? 1 : 0);
}