检查子列表是否以相同的顺序在列表中

Check if sublist is in list in the same order

我正在尝试找到一种方法来检查一个列表的元素是否以 Java 中的相同顺序出现在另一个列表中。例如:

char[] list = {'A','B','B','C','B','D'};
char[] sublist = {'B','C','B'};
char[] sublist2 = {'A','B','D'};

子列表应该 return 正确,但子列表 2 应该 return 错误(因为它们没有以相同的顺序出现)。我主要是尝试将 for 循环与一些 while 和一些 ifs 一起使用(尝试不使用一些内置函数,除了 length 之外)。

我试过了,但我认为它不正确(得到错误的答案):

public static boolean subList(char[] list, char[] sublist) {
    for (int i = 0; i < sublist.length; i++) {
        for (int j = 0; j < list.length; j++) {
            if (sublist[i] == list[j]) {
                break;
            }
        }
        return true; 
    }
    return false;
}

有可能实现吗?

这不是最正确的代码,但它有效!

public static boolean subList(char[] list, char[] sublist) {
    int subposition = 0;
    boolean subarray = false;
    for (int i = 0; i < list.length; i++) {
        if (subposition < sublist.length) {
            if (list[i] == sublist[subposition]) {
                subposition++;
            } else if (subposition > 0) {
                subposition = 0;
                i--;
            }

            if(subposition == sublist.length) {
                subarray = true;
            }
        }
    }

    return subarray;
}

以下代码应该有效:

  • 列表外循环,子列表嵌套循环
  • 创建一个布尔标志 found
  • 在嵌套循环中比较 list starting 从列表中的 current 位置的元素,一旦不一致检测到,found 重置为 false
  • 如果在完成嵌套循环后,foundtrue 则检测到子列表。
public static boolean subList(char[] list, char[] sublist) {
    for(int i = 0; i < list.length; i++) {
        boolean found = true;
        for(int j = 0, k = i; j < sublist.length && found && k < list.length; j++, k++) {
            if (sublist[j] != list[k]) {
                found = false;
            }
        }
        if (found) return true;
    }
    return false;
}

测试:

char[] list = {'A','B','B','C','B','D'};
char[] sublist = {'B','C','B'};
char[] sublist2 = {'A','B','D'};        
System.out.println(subList(list, sublist));  // true
System.out.println(subList(list, sublist2)); // false

试试这个。

public static boolean subList(char[] list, char[] sublist) {
    L: for (int i = 0, max = list.length - sublist.length; i <= max; i++) {
        for (int j = 0, k = i; j < sublist.length; j++, k++)
            if (sublist[j] != list[k])
                continue L;
        return true;
    }
    return false;
}

public static void main(String[] args) throws InterruptedException {
    char[] list = {'A', 'B', 'B', 'C', 'B', 'D'};
    char[] sublist = {'B', 'C', 'B'};
    char[] sublist2 = {'A', 'B', 'D'};
    System.out.println(subList(list, sublist));
    System.out.println(subList(list, sublist2));
}

输出:

true
false

快捷方式是将每个 char 数组转换为 String,因为 String 有一个 contains 方法可以给出我们想要的答案。 contains() 接受任何 CharSequence 作为参数,因此 String 可以工作,并且可能稍微便宜一些的变体是将 sublistsublist2 包装在 CharBuffer 中s 而不是将它们也转换为 String.

char[] list = { 'A', 'B', 'B', 'C', 'B', 'D' };
char[] sublist = { 'B', 'C', 'B' };
char[] sublist2 = { 'A', 'B', 'D' };

String listString = new String(list);
System.out.println("Contains sublist? " + listString.contains(CharBuffer.wrap(sublist)));
System.out.println("Contains sublist2? " + listString.contains(CharBuffer.wrap(sublist2)));

输出:

Contains sublist? true
Contains sublist2? false

你的代码出了什么问题?

在你的内部 for 循环中发生什么并不重要,因为在循环完成后你无条件地 return true。因此,如果 sublist 的长度至少为 1(不为空),您将达到 return statement 和 return true。如果 sublist 为空,则跳过外部 for 循环,因此您可以到达方法的底部并 return false (尽管空列表通常是被视为包含在任何列表中)。

您需要从 list(不是 sublist)中的每个位置搜索两个列表中的字符 不同 的位置。如果你发现这样的差异,子列表不包含在list的当前位置,你应该尝试下一个位置。