Jump to content
  • Advertisement
Sign in to follow this  
bratiefanut

Array question

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 ;)

Edited by Paradigm Shifter

Share this post


Link to post
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 this post


Link to post
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 sad.png

---

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!