2013-10-24 64 views
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)。

+0

你期待该代码输出你想要的输出?现在它所做的是检查两个相邻的数字是否相差3,并将两者都加到输出中,从而得到结果输出。您必须存储起始值,直到下一个值_doesn't_相差3,然后添加开始值和结束值。就像你所描述的那样。而且你没有得到最后的值,因为你永远不会把它添加到列表中。你的循环只能达到input.size() - 2. – Radiodef

回答

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; 
} 
+0

是的,这当然有诀窍。我正在获得预期的产出。 – missKK

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不同的元素,你进入他们两个。相反,当你发现差异是三时,你应该设置一些标志为真,否则将其设置为假。只要该标志为真,就不会在输出列表中放入元素。

我相信这样的事情会做的伎俩:

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; 
} 
+0

谢谢你的回答。非常感激。 – missKK

1

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

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

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

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

enter image description here

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; 
相关问题