我正在研究一个问题,我有一个输入整数列表,如{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] 请注意,我不仅获得中间重复值,我也缺少最后一个值(即45)。
答案 0 :(得分: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。只要标志为true,就不要将元素放在输出列表中。
我相信这样的事情可以解决问题:
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;
}
答案 1 :(得分:1)
正如另一篇文章所述,你没有得到列表的最后一个元素,因为你的for
循环终止于输入列表的倒数第二个元素。但是,如果您只调整for
循环的结束条件,最终会得到IndexOutOfBoundsException
,因为您的算法会在每个循环中检查i+1
。
我认为从索引1开始并简单地向后看数组就更简单了。根据您对问题的描述,我了解您将始终使用列表的第一个元素,因此我们可以从一开始就插入它(但这意味着您需要确保输入列表至少包含一个元素):< / p>
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;
}
答案 2 :(得分: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方法中的另一个问题是最后一个数字没有被处理,当最后两个数字没有相差3时会被忽略。这就是你无法在输出列表中看到它的原因。
您可以添加变量以检查是否发生连续数字,并添加逻辑以处理最后一个数字。
以下代码示例可以帮助您解决此问题。
答案 3 :(得分: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;