Public Group

# Array question

This topic is 1789 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello everybody

I have a programming question.

My array looks like this:

array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

And I want to erase from the array the elements like in a queue.

first modification:  |1|2|3|4|5|6|7|8|9|
second modification: |2|3|4|5|6|7|8|9|0|
tird modification:   |3|4|5|6|7|8|9|0|0|
fourth modification: |4|5|6|7|8|9|0|0|0|
...

Since now its easy:

array[i] = array[i+1];

But I have another boolean array that can lock in some numbers, for example:

bool lock[3] = {false, false, false};

I want that when lock[1] = true, the array[1] remains unchanged.

lock[1] = true;
first modification:       |1|2|3|4|5|6|7|8|9|
second modification:      |3|2|4|5|6|7|8|9|0|
tird modification:        |4|2|5|6|7|8|9|0|0|
and so on..

How can be implemented in a easy manner?

##### Share on other sites

EDIT: This won't work correctly after all. See further posts.

---

Since the arrays aren't the same size, you can't use:

if (!locked[i])
array[i] = array[i + 1];


Either setting the array sizes to be the same and use above, or using something like this might work:

if (i < 3) //size of bool array
{
if (!locked[i])
array[i] = array[i + 1];
}
else
{
array[i] = array[i + 1];
}


Note that I don't think this is actually safe for the last element, since you're trying to read outside the bounds of the array and using that value for something.

I would probably (at least before breakfast and waking up properly) do something like this:

for (int i = 0; i < 10; i++)
{
int newValue = 0;
if (i < 3) //Size of the bool array... AND a heart emoticon
{
if (!locked[i])
newValue = array[i + 1];
else
newValue = array[i]; //Forgot this, as richardurich pointed out
}
else
{
if ((i + 1) < 10)
newValue = array[i + 1];
}
array[i] = newValue;
}
Edited by Lactose!

##### Share on other sites

Lactose, your solution needs to actually lock in the old value when locked is true instead of changing to zero.


for (int i = 0; i < 10; i++)
{
int newValue = 0;
if (i < 3) //Size of the bool array... AND a heart emoticon
{
if (!locked[i])
newValue = array[i + 1];
else //lock in old value
newValue = array[i];
}
else
{
if ((i + 1) < 10)
newValue = array[i + 1];
}
array[i] = newValue;
}

##### Share on other sites

Different sizes is awkward. You should use a struct

struct Element
{
int value;
bool isLocked;
};

bool IsNotLocked(const Element& elt) { return !elt.isLocked; }

Element myArray[10] = { {0}, {1}, {2, true}, {3}, {4}, {5}, {6}, {7}, {8}, {9} };

Element* newEnd = std::remove_if(myArray, myArray + 10, IsNotLocked);

for(; newEnd != myArray + 10; ++newEnd)
{
newEnd->value = 0;
newEnd->isLocked = false;
}


It's still not very nice though ;) And I didn't test it. If you use a std::vector instead of an array you can use vector::erase(newEnd) instead of the loop at the end.

EDIT: Whoops, that erases everything that is not locked. I did say I didn't test it ;)

##### Share on other sites

Lactose, your solution needs to actually lock in the old value when locked is true instead of changing to zero.

Edited your fix into my post. Thanks for the correction :)

##### Share on other sites

Actually, looking at it now, this wouldn't give the behavior wanted in the final parts of the post.

If lock[1] is true, array[0] should copy the value of array[2] instead of array[1] -- assuming lock[2] is false.

My suggestion solution will not work. Sorry

---

Starting to think nested loops.

Loop through to update values. In that loop, loop through the remaining until a non-locked entry is found (breaking the inner loop when found), and using that. If nothing found, use default value of 0.

Edited by Lactose!

##### Share on other sites

Well my method doesn't work either ;)

It's going to be problematic anyway - what is supposed to happen if you want to keep say the 5th element locked and you delete everything else from the array?

##### Share on other sites

EDIT: But this also shares the question from Paradigm Shifter...


for (int i = 0; i < 10; i++)
{
int newValue = 0;
if (locked[i])
newValue = array[i];
else
{
for (int j = (i + 1); j < 10; j++)
{
if (j < 3) //Size of the bool array
{
if (locked[j])
continue;
}
newValue = array[j];
break;
}
}
array[i] = newValue;
}


Edited by Lactose!

##### Share on other sites
This is tricky to get right. Here's my attempt (with same-length arrays, to keep sanity):
#include <algorithm> // Just for std::swap

unsigned find_first_unlocked(bool const *locked, unsigned n, unsigned i) {
for (; i < n; ++i) {
if (!locked[i])
break;
}

return i;
}

void shift(int *v, bool const *locked, unsigned n) {
unsigned i, j;
for (i = find_first_unlocked(locked, n, 0), j = find_first_unlocked(locked, n, i + 1);
j < n;
std::swap(i, j), j = find_first_unlocked(locked, n, i + 1)) {
v[i] = v[j];
}

if (i < n)
v[i] = 0;
}


Edited by Álvaro

##### Share on other sites

No love for recursion, huh? I'll provide a recursive solution:

int GetNextValue(int currIndex, int* array, int arraySize, bool* locked, int lockedSize){
if (currIndex >= arraySize) return 0;
if ((currIndex < lockedSize) && (locked[currIndex])) //locked, so skip this value
return GetNextValue(currIndex+1, array, arraySize, locked, lockedSize);
return array[currIndex];
}

void ShiftValues(int* array, int arraySize, bool* locked, int lockedSize){
for (int i = 0; i < arraySize; i++){
if ((i < lockedSize) && (locked[i])) //value is locked, so keep it the same
continue;
else //value is not locked, so set to the next value
array[i] = GetNextValue(i+1, array, arraySize, locked, lockedSize);
}
}


Edit: first post only had half the code for some reason?!?! And second post messed up the code block.

Edited by richardurich

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 15
• 14
• 46
• 22
• ### Forum Statistics

• Total Topics
634054
• Total Posts
3015267
×