2

I want to delete multiple elements from array using index array,this is my code:

// b is an index array, n is size of b,
// player is the array need to be delete elements,
// size is the size of player
void play_cards(int b[],int n,int player[],int *size){
    int i;
    for(i = 0; i < n; i++)
        delete_cards(b[i],player,size);
}

void delete_cards(int n,int player[],int *size){
    int i;
    for(i = n; i < *size; i++)
        player[i] = player[i+1];   
    *size -= 1;
}

int main(void){

  int player[10] = {1,2,3,3,4,4,5,5,6,7};
  int index[6] = {2,3,4,5,6,7};
  int size = 10;

  play_cards(index,6,player,&size);

  for(int i = 0; i < size; i++)
       printf("%d|",player[i]);
  puts("");

  return 0;
}

I expect print the player should be 1,2,6,7 instead of 1,2,3,4. How should I fix it?

3
  • 1
    To remove from the end of the (big) index. for(i = 0; i < n; i++) --> for(i = n-1; i >=0; --i) Commented May 1, 2016 at 15:34
  • 1
    which print? I don't see it Commented May 1, 2016 at 15:36
  • 2
    The problem is that once you've removed card at index 2, the meaning of index 3 has changed; what was originally at 3 is now at 2. You're going to need to think rather carefully about how to resolve this. And if the contents of the index array is not guaranteed to be sorted, it won't help if you work from the tail of the list of indexes (but if the indexes are guaranteed to be in ascending order, it will work). Are the elements of index guaranteed to be unique? (It is problematic in most card games if you play the same card twice, so the answer to that's probably "Yes — they're unique".) Commented May 1, 2016 at 15:38

4 Answers 4

3

First I would not call the function delete_cards as it suggests that it deletes multiple cards which it does not - just delete_card would make things more clear.

Anyway - when you change the player array before you have played all cards in the index array, you change the meaning of the indexes. This is why your current code doesn't work.

So you can do two things:

a) Play all cards first and then delete the cards played. This could be done by first marking played card with -1 and then have a loop where you removed all element being -1

or

b) Play a card, delete it and adjust the remaining elements in index by decrementing them by one. Note: This solution requires that index is sorted (lowest first).

Solution a) could look something like this:

void delete_played_cards(int player[],int *size)
{
    int i;
    int next_pos = 0;
    int deleted = 0;
    for(i = 0; i < *size; i++)
    {
        if (player[i] != -1)
        {
            player[next_pos] = player[i];
            if (i != next_pos)
            {
                player[i] = -1;
            }
            ++next_pos;
        }
        else
        {
            ++deleted;
        }
    }

    *size -= deleted;
}

void play_cards(int b[],int n,int player[],int *size)
{
    int i;

    for(i = 0; i < n; i++)
    {
        player[b[i]] = -1;  // Mark card as played
    }

    delete_played_cards(player,size);
}

int main(void)
{
  int player[10] = {1,2,3,3,4,4,5,5,6,7};
  int index[6] = {2,3,4,5,6,7};
  int size = 10;

  play_cards(index,6,player,&size);

  for(int i = 0; i < size; i++)
       printf("%d|",player[i]);
  puts("");

  return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

2

Modify play_cards:

void play_cards(int b[], int n, int player[], int *size)
{
    int i;
    for(i = n-1; i >= 0; i--)
        delete_cards(b[i],player,size);
}

This will start deleting from the end of array. As BLUEPIXY mentioned.

Comments

0

here is a pseudocode that you can work with:

given a sorted list, 1..n

for i = 2 up to length of list:
  if list[i] is equal to list[i-1]:
    shift the sublist [2..] 1 position to the left
  else
     increment i by 1

Comments

-1

If you want to delete easily and efficiently without using loop you can use memcpy

#include <stdio.h>
#include <string.h>
#define INDEX_MAX 6

int main ()
{
   int size = 10;
   int src[] = {1,2,3,3,4,4,5,5,6,7};
   int index[] = {2,3,4,5,6,7};
   int x;

   size = size - INDEX_MAX; 
   memcpy(src+2, src+8, sizeof(int)*(size-2));// - 2 since index 1 and 2 remains in the array

   for(x = 0; x < size; x++){
       printf("%d",src[x]);
   }

   return(0);
}

2 Comments

This is not what OP wants to do. OP wants to fill an index array with th e cards to be played, call the play_cardsfunction and have the player array reorganized.
You dont' want sizeof(int)*(size-2). You access out of bounds.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.