Tee
Tee

Reputation: 93

How to delete multiple elements from a array at the same time

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?

Upvotes: 2

Views: 6685

Answers (4)

Muhammet Madraimov
Muhammet Madraimov

Reputation: 117

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.

Upvotes: 2

4386427
4386427

Reputation: 44274

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;
}

Upvotes: 3

jnapor
jnapor

Reputation: 63

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);
}

Upvotes: -1

ultrajohn
ultrajohn

Reputation: 2597

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

Upvotes: 0

Related Questions