1

我正在处理一个问题,其中我有一个输入整数列表,例如 {0,3,6,9,12,18,21,24,27,33,39}。我需要通过分析原始列表来创建一个新列表,这样如果我找到一个 3 的倍数的序列,那么该序列的第一个元素和最后一个元素都将添加到该列表中。不会添加该序列的第一个和最后一个元素之间的任何元素。任何其他元素(没有 3 的连续倍数)都将被添加。所以对于 {0,3,6,9,12,18,24,27,30,39,45} 的输入列表,我的输出应该是 [0,12,18,24,30,39,45]。请注意,我的第一个 3 的倍数序列是 0、3、6、9、12;所以根据我的要求,新列表有 0、12。由于 18 没有任何两侧相差 3 的邻居,所以它是这样添加的。同样,将 24,27,30 添加为 24,30。此外,与 18、39 和 45 类似,同样添加。

int difference = 3;  
public static List<Integer> parseList(List<Integer> input, int difference) {
    List<Integer> output = new ArrayList<Integer> ();
    for (int i = 0; i < input.size()-1; i++) {
        // Check if subsequent element values differ by specific difference
        if ( (input.get(i+1) - input.get(i)) == difference) {
            output.add(input.get(i));
            output.add(input.get(i+1));

        }
        else {
            output.add(input.get(i));
        }

    }
    return output;
}

我得到的输出是:0 3 3 6 6 9 9 12 12 18 24 27 27 30 30 39 同样,我的预期输出是:[0,12,18,24,30,39,45] 请注意,不仅我得到中间重复值,我也缺少最后一个值(ie45)。

4

4 回答 4

1

for (int i = 0; i < input.size()-1; i++)

这会导致您错过列表中的最后一个元素。

因此,您应该在循环之后添加最后一个元素(因为最后一个元素应该始终出现在输出中)。

以下:

if ( (input.get(i+1) - input.get(i)) == difference) {
            output.add(input.get(i));
            output.add(input.get(i+1));

导致重复条目,因为每当您遇到几个相差 3 的元素时,您都输入它们。

相反,当您发现差值为 3 时,您应该将某个标志设置为 true,否则将其设置为 false。只要标志为真,您就不会将元素放入输出列表中。

我相信这样的事情会奏效:

public static List<Integer> parseList(List<Integer> input, int difference) {
    List<Integer> output = new ArrayList<Integer> ();
    boolean isSeq = false;
    for (int i = 0; i < input.size()-1; i++) {
        if ((input.get(i+1) - input.get(i)) == difference) {
            // add start of a sequence 
            if (!isSeq) {
                output.add(input.get(i));
                isSeq = true;
            }
        }
        else {
            isSeq = false;
            output.add(input.get(i));
        }

    }
    output.add(input.get(input.size()-1));
    return output;
}
于 2013-10-24T02:18:20.910 回答
1

正如另一篇文章中提到的,您没有得到列表的最后一个元素,因为您的for循环在输入列表的倒数第二个元素处终止。但是,如果您只是调整for循环的结束条件,您最终会得到一个,IndexOutOfBoundsException因为您的算法会检查i+1每个循环。

我认为从索引 1 开始并简单地向后看数组会更简单。根据您对问题的描述,我了解到您将始终使用列表的第一个元素,因此我们可以从头开始插入它(但这意味着您需要确保输入列表至少包含一个元素):

public static List<Integer> parseList(List<Integer> input, int difference) {
    List<Integer> output = new ArrayList<Integer> ();
    if (input.size() > 0) {
        // always use first element
        int indexToAdd = -1;
        output.add(input.get(0));
        for (int i = 1; i < input.size(); i++) {
            if ( (input.get(i) - input.get(i-1)) == difference) {
                if (i == input.size()-1) {
                    output.add(input.get(i));               
                }
                else { 
                    indexToAdd = i;
                }
            }
            else {
                if(indexToAdd != -1) {
                    output.add(input.get(indexToAdd));
                    indexToAdd = -1;
                }
                output.add(input.get(i));
            }
        }
    }
    return output;
}
于 2013-10-24T02:40:53.317 回答
1

您的代码中的方法parseList不正确。这种方法有两个问题。 1.只要相邻的数字相差3,它就会添加数字。在这种情况下,当出现连续的差异时,您将添加重复的数字。 例如,0,3,6,9,12 Step#1。当 i = 0 时,条件 '相邻数字相差 3' 满足,您将 0 和 3 添加到输出列表中。step#2 当 i =1 时,条件 '相邻数字相差 3' 满足,将 3 和 6 添加到输出列表中,看看什么?添加重复值。对于索引 i=1您在 step#1 和 step#2 中将数字添加到输出列表这就是为什么您的输出列表中有重复数字,例如 0,3,3,6....

2. parseList 方法中的另一个问题是最后一个数字没有被处理,当最后两个数字相差 3 时,它被忽略。这就是为什么你也无法在输出列表中看到它。

您可以添加变量以检查是否出现连续数字不同,并添加逻辑来处理最后一个数字。

以下代码示例可以帮助您解决此问题。

在此处输入图像描述

于 2013-10-24T02:57:30.000 回答
1

我花了一段时间才弄明白……然而,另一种编码方式:

ArrayList<Integer> output = new ArrayList<Integer>();

int i = 0;
while (i < input.size()) {
    int start = input.get(i);
    output.add(start);
    int end = -1;
    int x = i+1;        

    while (x < input.size()) {
        if (input.get(x++) - input.get(i++) != 3) {
            end = input.get(i-1);
            break;
        }
    }           
    if (end > 0 && end != start) {
        output.add(end);
    }
    if (start == input.get(i)) break;
}
return output;
于 2013-10-24T04:36:04.120 回答