I have a list of integer numbers and I want to remove from this list the couples of consecutive numbers.
For example, from this list:
{ 1, 2, 3, 4, 5, 100, 11, 12, 100, 14, 15, 100, 7, 8, 9, 100, 26, 27 }
I want to have this result:
{ 1, 2, 3, 4, 5, 100, 100, 100, 7, 8, 9, 100 }
This is the executing code:
var list = new List<int> { 1, 2, 3, 4, 5, 100, 11, 12, 100, 14, 15, 100, 7, 8, 9, 100, 26, 27 };
list.Add(-1);
int counter = 0;
bool nonecons = false;
for (int i = 0; i < list.Count; i )
{
if ((i 1 < list.Count))
{
if ((list[i 1] - list[i]) == 1)
{
counter ;
}
else
{
nonecons = true;
if (counter < 2 && nonecons == true)
{
if (list[i] != 100)
{
list.Remove(list[i]);
list.Remove(list[i - 1]);
}
counter = 0;
nonecons = false;
}
else if (counter >= 2 && nonecons == true)
{
counter = 0;
nonecons = false;
}
}
}
}
list.RemoveAt(list.Count - 1);
But when i run this code I have this unexpected result:
{ 1, 2, 3, 4, 5, 100, 100, 100, 7, 100 }
What I need to change?
CodePudding user response:
The problem is the how you use an index value to iterate over the list and in which direction you iterate the indexer: "upwards" the list towards the end, combined with how/where you remove elements from the list.
Imagine a list with the elements 100,14,15,100,100,7,8,9,100
(to take a snippet from your example list). Your code is processing this and is at index position being 3, pointing at the element 100
after element 15
, when we start looking at what the code is doing:
100, 14, 15,100,100, 7, 8, 9,100
--- --- --- --- --- --- --- --- ---
^
i=3
Your code correctly detected that 14,15
is a consecutive sequence of a length smaller than 3, and proceeds to remove them.
Now the list looks like 100,100,100,7,8,9,100
. So far so good.
But, and herein lies the problem, the current index position value hasn't changed. It's still 3. And then comes the next iteration step, with the index position now being 4. So, the next element considered by your code after deleting 14,15
is the element 8
:
100,100,100, 7, 8, 9,100
--- --- --- --- --- --- ---
^
i=4
Because the element positions/indices have shifted to the left due to the removal of prior elements, but the index position hold in the i
variable has not been adjusted to account for this shift, the code misses the 100
element in front of the 7
element and the 7
element itself.
This leads your code to detect only the consecutive sequence 8,9
instead of 7,8,9
(due to it skipping over the 7
), hence it proceeds deleting 8,9
.
The solution to your problem should now be clear: Whenever deleting elements in front of or at the index position held by i
, you'll need to adjust the value of i
to follow the left-shift of the elements after the removed elements.
This is done by decreasing the value of i
by the amount of elements deleted in front or at the i
position:
list.Remove(list[i]);
list.Remove(list[i - 1]);
i -= 2;
(As an alternative solution, the direction of iterating over the list could be switched to go "downwards" from the end towards the beginning of the list. Then any elements subject to removal would be behind the index position hold by i
. And since i
is only decreasing in this approach, the value in i
wouldn't need to be adjusted because any elements still to be iterated over wouldn't have their position shifted. However, this would require significantly more changes to your code and isn't done with adding a single code line like i -= 2;
)
(There are other concerns to be found with your code, like the not very useful nonecons variable that has not discernible effect, but it's unrelated to the problem with the incorrect result, so it's not really an issue...)