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

Edited 5 Years Ago by DoubleZ: n/a

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?

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.

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

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

Edited 5 Years Ago by stereomatching: n/a

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

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.

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?

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

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") );
}
Comments
Why would you do his work? Why???
That would be good. Then he doesn't have to do the project himself and he can pass his class on YOUR work.

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

Edited 5 Years Ago by DoubleZ: n/a

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!!!!

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

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)?

Edited 5 Years Ago by stereomatching: n/a

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;
}
This question has already been answered. Start a new discussion instead.