Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查和打印字谜时的IndexOutOfBoundsException_Java - Fatal编程技术网

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