954,504 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Remove specific elements from an array of integers

Hello, so I recently started reading on arrays and I have an assignment to make a program that removes the necessary elements from an array of integers so that the array consists only of increasing integers, for example, transform {2,3,5,1,6,2,3} to {2,3,5,6}. Now, I do not know of any possible ways to remove elements from an array, so I tried overwriting the bad values and shitfing the array to the left, but I still need to remove the elements from the right-end of the array. My code is not really working properly but thats just a blueprint, anyone has got any idea how to do this right or has a different approach to this? Thanks in advance!

#include <iostream>
using namespace std;
int main ()
{
    int ok;
    do
    {
        int size;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        for (int i=1; i<size; i++)
        {
            if (arr[i-1]>arr[i])
            {
                for (int j=i; j<(size-1); j++)
                {
                    arr[j] = arr[j+1];
                }
            }
        }
        for (int i=0; i<size; i++)
        {
            cout << arr[i];
        }
    cout << endl;
    cout << "Continue (1) or end (0)" << endl;
    cin >> ok;
    } while (ok==1);
    return 0;
}
DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

What do you mean by removing the necessary elements from an array?

Do you want to output increasing elements in an array and remove the smaller ones that comes after them?

vidit_X
Junior Poster
168 posts since Aug 2008
Reputation Points: 40
Solved Threads: 26
 

Hello, so I recently started reading on arrays and I have an assignment to make a program that removes the necessary elements from an array of integers so that the array consists only of increasing integers, for example, transform {2,3,5,1,6,2,3} to {2,3,5,6}. Now, I do not know of any possible ways to remove elements from an array, so I tried overwriting the bad values and shitfing the array to the left. My code is not working but thats just a blueprint, anyone has got any idea how to do this right or has a different approach to this? Thanks in advance!

#include <iostream>
using namespace std;
int main ()
{
    int ok;
    do
    {
        int size;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        for (int i=1; i<size; i++)
        {
            if (arr[i-1]>arr[i])
            {
                for (int j=i; j<(size-1); j++)
                {
                    arr[j] = arr[j+1];
                }
            }
        }
        for (int i=0; i<size; i++)
        {
            cout << arr[i];
        }
    cout << endl;
    cout << "Continue (1) or end (0)" << endl;
    cin >> ok;
    } while (ok==1);
    return 0;
}

As you go through the array, keep track of these values:

int last_valid_value //numerical value of the right-most valid integer in your array
int next_position //index to the spot directly after last_valid_value
int i //index to spot you will be checking, the same as in your for loop
int count
//use checks like these
if (i > last_valid_value) {
  arr[next_position] = i;
  next_position += 1;
  last_valid_value = arr[i];
  count += 1;
 }


At the end you can resize your array or simply only output the number of valid integers found.

Greywolf333
Junior Poster
145 posts since Sep 2010
Reputation Points: 40
Solved Threads: 39
 

What do you mean by removing the necessary elements from an array?

Do you want to output increasing elements in an array and remove the smaller ones that comes after them?


about right, yes

DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

simplest way

size_t A[] = {1, 1, 2, 3, 4, 4, 5};
size_t *APtr = std::unique(A, A + sizeof_array(A) );
std::copy(A, APtr + 1, std::ostream_iterator<size_t>(std::cout, "\n") );


or

//from cplus_plus.com
size_t *unique_test( size_t *first, size_t *last )
{
  size_t *result = first;
  while (++first != last)
  {
    if (!(*result == *first))
      *(++result)=*first;
  }
  return ++result;
}

size_t A[] = {1, 1, 2, 3, 4, 4, 5};
size_t *APtr = unique_test(A, A + sizeof_array(A) );
std::copy(A, APtr + 1, std::ostream_iterator<size_t>(std::cout, "\n") );
stereomatching
Posting Whiz in Training
260 posts since Sep 2010
Reputation Points: 28
Solved Threads: 10
 

A bit more like it, but still not it, how to work around the situation when arr[i-1] is equal to arr[i+1] ? also can I actually resize the array or do I have to copy it to a new array to get rid of the duplicate values in the end of the array? In the code below im just outputting the valid values.

#include <iostream>
using namespace std;
int main ()
{
    int ok;
    do
    {
        int size, count = 1;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        int last_valid_value = arr[0];
        for (int i=1; i<size; i++)
        {
            if (arr[i]>last_valid_value)
            {
                last_valid_value = arr[i];
                count++;
            }
            else
            {
                for (int j=i; j<size;j++)
                {
                    arr[j] = arr[j+1];
                }
            }

        }
        for (int i=0; i<count; i++)
        {
            cout << arr[i];
        }
    cout << endl;
    cout << "Continue (1) or end (0)" << endl;
    cin >> ok;
    } while (ok==1);
    return 0;
}
DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

I'm not sure I got your question. How do you know right element to remove (bad ones)?

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

For example, 12123 will get transformed to 1223 instead of 123, 12342169 will get transformed to 1234169.. it wil replace 2 with 1 and jump to 6 to check if its greater than 1, but it wont check if 1 is greater than 4. if you know what I mean.

DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 
For example, 12123 will get transformed to 1223 instead of 123, 12342169 will get transformed to 1234169.. it wil replace 2 with 1 and jump to 6 to check if its greater than 1, but it wont check if 1 is greater than 4. if you know what I mean.


you mean sorting?

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

I mean removing every element that is not greater than the previous one.

DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

Sort the values
Copy only the first of any duplicates to a new array.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

you could tune the codes to make it become safer, faster and generic
as your need, if there are bugs, please tell me, I will try my best to
fix it

size_t *remove_adjacent(size_t *first, size_t *last, std::vector<size_t> &result)
{
  if(first == last) return 0;

  size_t *next = first + 1;
  if(next == last) result.push_back(*first);
  while(next != last)
  {
    if(*first <= *next)
    {
      std::cout<<*first<<", "<<*next<<std::endl;

      result.push_back(*first);
      ++first; ++next;
      if(next == last)
      result.push_back(*first);
    }
    else if(*first > *next)
    {
      std::cout<<*first<<", "<<*next<<std::endl;
      result.push_back(*first);
      if(last - next > 1)
      {
        first += 2;
        next  += 2;
      }
      else
      {
        return last;
      }
    }
  }
}

void case_03()
{
  size_t A[] = { 1, 2, 3, 4, 2, 1, 6, 9 };
  std::vector<size_t> result;
  remove_adjacent(A, A + sizeof(A) / sizeof(*A), result);
  std::copy(result.begin(), result.end(), std::ostream_iterator<size_t>(std::cout, "\n") );
}
stereomatching
Posting Whiz in Training
260 posts since Sep 2010
Reputation Points: 28
Solved Threads: 10
 

I highly appreciate your effort guys and I`m sure I will make use of your help, but I sorta need to stay away from functions, classes etc on this one. Basically the only problem I`m having is as it follows. For 1 2 4 2 1 5, my code would stop at 2, see that it is not greater than 4 and replace that 2 with the next value witch is 1, converting the array to 1 2 4 1 5 5, then it would check the next index in line which has a value of 5, which is greater than 1 and assume that everythings okay. But that is wrong, it should check for the next left-most value that is greater than 4 and replace 1 with that one, in this case it is 5. I get this right and then I can copy the good values to a new array and its set.

#include <iostream>
using namespace std;
int main ()
{
    int ok;
    do
    {
        int size, count = 1;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        int last_valid_value = arr[0];
        for (int i=1; i<size; i++)
        {
            if (arr[i]>last_valid_value)
            {
                last_valid_value = arr[i];
                count++;
            }
            else
            {
                for (int j=i; j<(size-1);j++)
                {
                    if(arr[j+1]>arr[j-1])
                    {
                        arr[j] = arr[j+1];
                    }
                    else
                    {

                    }
                }
            }

        }
        for (int i=0; i<count; i++)
        {
            cout << arr[i] << " ";
        }
    cout << endl;
    cout << "Continue (1) or end (0)" << endl;
    cin >> ok;
    } while (ok==1);
    return 0;
}
DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

you could tune the codes to make it become safer, faster and generic as your need, if there are bugs, please tell me, I will try my best to fix it

size_t *remove_adjacent(size_t *first, size_t *last, std::vector<size_t> &result)
{
  if(first == last) return 0;

  size_t *next = first + 1;
  if(next == last) result.push_back(*first);
  while(next != last)
  {
    if(*first <= *next)
    {
      std::cout<<*first<<", "<<*next<<std::endl;

      result.push_back(*first);
      ++first; ++next;
      if(next == last)
      result.push_back(*first);
    }
    else if(*first > *next)
    {
      std::cout<<*first<<", "<<*next<<std::endl;
      result.push_back(*first);
      if(last - next > 1)
      {
        first += 2;
        next  += 2;
      }
      else
      {
        return last;
      }
    }
  }
}

void case_03()
{
  size_t A[] = { 1, 2, 3, 4, 2, 1, 6, 9 };
  std::vector<size_t> result;
  remove_adjacent(A, A + sizeof(A) / sizeof(*A), result);
  std::copy(result.begin(), result.end(), std::ostream_iterator<size_t>(std::cout, "\n") );
}


This is bad!!!!

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

Heres an updated version, nearly good, but in some cases I get some unexpected results like 121111 is transformed into 1 2 5, and 1211111 to 1 2 4199614, anyone can guess the cause of this? The count and last_valid_value values go wrong at some point in these cases.

#include <iostream>
using namespace std;
int main ()
{
    int ok;
    do
    {
        int size, count = 1;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        int last_valid_value = arr[0];
        int next_position = 1;
        for (int i=1; i<size; i++)
        {
            if (arr[i]>last_valid_value)
            {
                last_valid_value = arr[i];
                next_position++;
                count++;
            }
            else
            {
                for (int j=i; j<(size-1);j++)
                {
                    if(arr[j+1]>arr[j-1])
                    {
                        arr[j] = arr[j+1];
                    }
                    else
                    {
                        while (arr[next_position]<=arr[j-1] && next_position<size)
                        {
                            next_position++;
                        }
                        if (arr[next_position]>arr[j-1])
                        {
                            arr[j] = arr[next_position];
                        }
                    }
                }
            }

        }
        for (int i=0; i<count; i++)
        {
            cout << arr[i] << " ";
        }
        cout << endl;
        cout << "Continue (1) or end (0)" << endl;
        cin >> ok;
        } while (ok==1);
    return 0;
}
DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 

This one is much more better

std::list<size_t> A = { 1, 2, 3, 4, 2, 1, 6, 9 };
  auto it = A.begin();
  while( it != A.end() )
  {
    it = std::adjacent_find(it, A.end(), [](size_t const Fir, size_t const Sec)
    {
      return Sec <= Fir;
    } );
    if( it != A.end() )
    it = A.erase(it);
  }
  std::copy(A.begin(), A.end(), std::ostream_iterator<size_t>(std::cout, ", ") );

you could change your requirement of < or <=, dependent on your need.
STL is just like lego, your question is a good lesson for me too
Thanks a lot

refinement of my previous code

//turn all of the return last; to return;
void remove_adjacent(size_t *first, size_t *last, std::vector<size_t> &result);


ps : most of the compilers don't support the initialization way of { 1, 2, 3, 4, 2, 1, 6, 9 } yet
maybe this is because they lack variadic template(I guess)?

stereomatching
Posting Whiz in Training
260 posts since Sep 2010
Reputation Points: 28
Solved Threads: 10
 

I modified your code a bit. I think this works fine.

#include<iostream>
using namespace std;
int main()
{
    int ok;
    do
    {
        int size;
        cout << "Input array size" << endl;
        cin >> size;
        int arr[size];
        cout << "Input " << size << " array elements" << endl;
        for (int i=0; i<size; i++)
        {
            cin >> arr[i];
        }
        for (int i=1; i<size; i++)
        {
            if (arr[i-1]>=arr[i])
            {
                for (int j=i; j<(size-1); j++)
                {
                    arr[j] = arr[j+1];
                }
                size--;
                i--;
            }
        }
        for (int i=0; i<size; i++)
        {
            cout << arr[i];
        }
    cout << endl;
    cout << "Continue (1) or end (0)" << endl;
    cin >> ok;
    }
    while (ok==1);
    return 0;
}
sreejithbabu
Newbie Poster
9 posts since Nov 2009
Reputation Points: 10
Solved Threads: 1
 

Oh, wow, sweet idea `sreejithbabu`, thank you very much!

DoubleZ
Newbie Poster
24 posts since Sep 2011
Reputation Points: 10
Solved Threads: 0
 
Oh, wow, sweet idea `sreejithbabu`, thank you very much!


You're welcome.
:)

sreejithbabu
Newbie Poster
9 posts since Nov 2009
Reputation Points: 10
Solved Threads: 1
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: