查找最长的重复序列

时间:2018-09-12 18:00:36

标签: java pattern-matching byte

有这样一个问题。我有一个方法可以从文件中将字节读取到数组中,并且可以搜索该数组中最长的字节序列。

private int element;
private int lastElement;
private int length;

private byte[] readByteFromFile(File name) throws IOException {
            return Files.readAllBytes(name.toPath());
        }

private void searchByte(byte[] byteMass) {
    for (int i = 0; i < byteMass.length; i++) {
        int count = 0;
        for (int j = i + 1; j < byteMass.length; j++) {
            if (byteMass[i + count] == byteMass[j]) {
                if (count >= length) {
                    length = count + 1;
                    element = i;
                    lastElement = j - count;
                }
                count++;
            } else {
                count = 0;
            }
        }
    }
}

假设我的文件包含这样的数字序列:

  

444478126354444

在处理的情况下,我的方法将推断出第一次出现在0,第二次出现在11且序列长度= 4

但是如果我有这样的顺序

  

133333444478126354444

然后我的方法将推断出第一次出现在1,第二次出现在2,序列4的长度

如何解决该问题,使其继续正常工作?

2 个答案:

答案 0 :(得分:1)

未经测试。不要在我面前有IDE。 是对原始代码的更改。第二个循环减少一个元素的迭代。如果下一个元素与上一个元素不相等,则循环退出。

private void searchByte(byte[] byteMass) {
        int maxLength = 0
        int element;
        for (int i = 0; i < byteMass.length; i++) {
            int count = 0;
            for (int j = i + 1; j < byteMass.length-1; j++) {
                if (byteMass[i] == byteMass[j]) {
                    if (count > length) {
                        maxLength = count;
                        element = i;
                    }
                    count++;
                } else {

                    break;
                 }
            }
        }

答案 1 :(得分:0)

如果您还没有,我认为追踪代码的逻辑很重要 !您尝试先寻求帮助,然后再寻求帮助。如果您依靠别人来制定自己的逻辑,那么作为一名程序员,您将不会取得太大进步。

话虽如此,让我们深入研究并在有问题输入的情况下运行代码(这不是实际的代码,我们只是在程序运行时查看值)

byteMass = 133333444478126354444
(byteMass.length = 21)
length = 0
    0 (i) < 21 (byteMass.length): true
        count = 0
        1 (j) < 21: true
            1 (byteMass[0 (i + count)]) == 3 (byteMass[1 (j)]): false
                count = 0
        2 (j) < 21: true
            1 (byteMass[0 (i + count)]) == 3 (byteMass[2 (j)]): false
                count = 0
        3 (j) < 21: true
            1 == 3: false

它继续这样,但是当j = 12时会发生一些有趣的事情

        12 (j) < 21: true
            1 (byteMass[0 (i + count)]) == 1 (byteMass[12 (j)]): true
                0 (count) >= 0 (length): true
                    length = 1 (count + 1)
                    element = 0 (i)
                    lastElement = 12 (j - count)
                count = 1

至少对我来说,这看起来像是意外的行为!我们想计算重复的数字,但是这个1与前一个1相差11个数字!我们可以通过编辑内部for循环来解决此问题

for (int j = i + 1; j < byteMass.length && byteMass[i] == byteMass[j]; j++) {

这样,byteMass[i] == byteMass[j]的值为false时,内部循环就会中断。现在,让我们使用新的内部for循环重新启动过程

byteMass = 133333444478126354444
(byteMass.length = 21)
length = 0
    0 (i) < 21 (byteMass.length): true
        count = 0
        1 (j) < 21 && 1 (byteMass[0 (i)]) == 3 (byteMass[1 (j)]): false
    1 (i) < 21: true
        count = 0
        2 (j) < 21 && 3 (byteMass[1 (i)]) == 3 (byteMass[2 (j)]): true
            0 (count) >= 0 (length): true
                length = 1 (0 (count) + 1)
                element = 1 (i)
                lastElement = 2 (2 (j) - 0 (count))
            count = 1 (0 (count) + 1)
        3 (j) < 21 && 3 (byteMass[2 (1 (i) + 1 (count))]) == 3 (byteMass[3 (j)]): true
            1 (count) >= 1 (length): true
                length = 2 (1 (count) + 1)
                element = 1 (i)
                lastElement = 2 (3 (j) - 1 (count))

对我来说,这似乎是意外的行为,但由于我不知道如何解决,所以我不会修复它:我不知道element和lastElement代表什么。代码继续这样直到j = 6:

        6 (j) < 21 && 3 (byteMass[5 (1 (i) + 4 (count))]) == 4 (bteMass[3 (j)]): false
    2 (i) < 21: true
        count = 0
        3 (j) < 21: true
            3 (byteMass[2 (2 (i) + 0 (count))]) == 3 (byteMass[3 (j)]): true
                length = 1 (0 (count) + 1)
                element = 2 (i)
                lastElement = 3 (3 (j) - 1 (count))
            count = 1 (0 (count) + 1)

这再次以相同的方式继续进行,直到j =6。这时希望您可以看到为什么程序无法按预期运行的原因。但是我仍然没有回答如何解决它的问题。我不太了解您如何解决此问题的思考过程,但我会与您分享我的个人观点

首先,我们需要将问题分解成小块

您可以按照自己的意愿做任何事情,但这是我的方法:我们的目标是找到最长的重复图案。为了做到这一点,我们需要弄清楚

  1. 一个数字重复一次以及重复多少次
  2. 如果该特定数字在序列中其他位置重复了该特定次数。如果确实如此,我们将需要保存其重复的次数
  3. 然后我们将重复该过程,但仅在重复次数大于保存的数据时才保存数据

这实际上是一种复杂的问题,说实话,使用助手功能可能会更容易解决。我希望这会有所帮助!