Erasing odd array's element

Hey all, so I have a problem with this code that it's not working properly. I have n (how many there are numbers) and P the numbers. (in a text file).

8
50 80 40 80 90 40 50 60

The answer should be:
50 40 90 50

This function should erase all odd index numbers. So I tried running debugger (not the best codeblock can have) but what was happening it took the first i = 0 as a true and did nothing however the other 7 numbers passed the else statement. By the end, I got that my n is = 1 (when it came to printing). So why all other numbers passed?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  void erase_odd(int n, int P[])
{
    for(int i = 0; i != n; i++)
    {
        if(i % 2 == 0) continue;
        else
        {
            n--;
            for(int k = i; k != n; k++)
            {
                P[k] = P[k + 1];
            }
            i--;
        }
    }
    ofstream out(rez);
    for(int i = 0; i != n; i++)
    {
        out << P[i] << " ";
    }
    out.close();
}


EDIT : I just noticed that I'm doing i-- and I realized that if I'm looking for an odd or even this thing messes it all up. Is there any other way I can do this ?
Last edited on
The simplest way would be to skip the unwanted data, i.e. not to store them.
May I ask you what are you trying to achieve?
Is this an exercise or homework? Do you have constraints? Do you need to store the data or you just need to output them?

At first glance, I’d say: read the data in a loop and:
- if you don’t need to store them, display only the right ones;
- if you need to store them, load (read into an array, push_back() into a std::vector...) only the right ones.

Or are you requested to read all data and later delete the unwanted ones?
Could you just not output them?

Could you please add details?
What I'm trying to achieve is to delete the i odd elements from the array. That's an exercise from one of my school books. I wouldn't say that I have constraints but at the moment I have 0 clue with vectors. I'm outputting the array that doesn't include the odd index elements. As I said I think the biggest issue right here is my part of the code that is not optimal.

1
2
3
4
5
6
            n--;
            for(int k = i; k != n; k++)
            {
                P[k] = P[k + 1];
            }
            i--;


If you're interested in full code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <fstream>
//
using namespace std;
//
const char duom[] = "d.txt";
const char rez[] = "r.txt";
//
void read(int &n, int P[])
{
    ifstream in(duom);
    in >> n;
    for(int i = 0; i != n; i++)
    {
        in >> P[i];
    }
    in.close();
}
//
void erase_odd(int n, int P[])
{
    for(int i = 0; i != n; i++)
    {
        if(i % 2 == 0) continue;
        else
        {
            n--;
            for(int k = i; k != n; k++)
            {
                P[k] = P[k + 1];
            }
            i--;
        }
    }
    ofstream out(rez);
    for(int i = 0; i != n; i++)
    {
        out << P[i] << " ";
    }
    out.close();
}
//
int main()
{
    int n, P[100];
    read(n, P);
    erase_odd(n, P);
    return 0;
}
Last edited on
I have 0 clue with vectors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>

int main()
{
   // simulate reading data from a file.
   std::vector<int> file = { 50, 80, 40, 80, 90, 40, 50, 60 };

   std::cout << "Unaltered vector:\n";
   for (auto itr = file.cbegin(); itr != file.cend(); itr++)
   {
      std::cout << *itr << ' ';
   }
   std::cout << "\nThe number of elements in the vector: " << file.size() << "\n\n";

   std::cout << "Deleting odd-numbered elements...\n\n";

   unsigned count = 0;

   for (auto itr = file.begin(); itr != file.end();)
   {
      if (count % 2 != 0)
      {
         itr = file.erase(itr);
      }
      else
      {
         itr++;
      }
      count++;
   }

   std::cout << "Altered vector:\n";
   for (auto itr = file.cbegin(); itr != file.cend(); itr++)
   {
      std::cout << *itr << ' ';
   }
   std::cout << "\nThe number of elements in the vector: " << file.size() << '\n';
}
Unaltered vector:
50 80 40 80 90 40 50 60
The number of elements in the vector: 8

Deleting odd-numbered elements...

Altered vector:
50 40 90 50
The number of elements in the vector: 4
Last edited on
you may go backwards, that way you will not change the position of the yet-to-visit elements
or you may use another array to store the result so it's a simply traversal O(n)
or you may realise that `remove()' will skip one element, so
1
2
for (int i=1 /*first odd element*/; i<n; ++i)
   remove(P, n, i);
closed account (z05DSL3A)
A bit of playing with pointers...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>

void PrintArray (const int* arr, const size_t count)
{
    for (int i = 0; i < count; i++)
    {
        std::cout << arr[i] << ":";
    }
    std::cout << "\n";
}

void EraseOdd (int* arr, size_t & count)
{
    int* src{ arr }, * dst{ arr }, i{ 0 };
    while (src < arr + count)
    {
        *dst = *src;
        src += 2;
        dst++;
        i++;
    }
    count = i;
}

int main ()
{
    constexpr size_t ARRAYMAX{ 10 };

    size_t count{ ARRAYMAX };
    int testData[ARRAYMAX]{ 1,2,3,4,5,6,7,8,9,0 };
    
    PrintArray (testData, count);
    EraseOdd (testData, count);
    PrintArray (testData, count);

    return 0;
}
A bit of playing with valarray:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <valarray>
using namespace std;

int main()
{
   valarray<int> V = { 50, 80, 40, 80, 90, 40, 50, 60 };
   valarray<int> Evens = V[ slice( 0, ( V.size() + 1 )/ 2, 2 ) ];

   cout << "Original array: ";
   for ( int i : V ) cout << i << ' ';

   cout << "\nAfter removal:  ";
   for ( int i : Evens ) cout << i << ' ';
}


Original array: 50 80 40 80 90 40 50 60 
After removal:  50 40 90 50
Last edited on
And............ I still have no clue what's up with my code. Once I tried to
outputting instead of erasing them everything was okay... So guys can you actually tell me where's the mistake

1
2
3
4
5
6
            n--;
            for(int k = i; k != n; k++)
            {
                P[k] = P[k + 1];
            }
            i++;
Last edited on
Well, once you've moved everything forward by 1, then what was at an odd index is now at an even index and vice versa. So i % 2 == 0 ceases to be a useful test.

Do you not get the idea that since we've given you four rather different solutions it might be time to stop flogging a dead horse? The one that needs least modification for your insistence on fixed-size arrays is @GreyWolf's.

Last edited on
Well, my skill level is not that high yet to be capable to use vectors or pointers. So how do I prevent it the moving index ? Do I have to save i somehow so the computer knows what next index is actually going to be ? Okay I can output like that but I need to erase the element.

1
2
3
4
5
6
7
8
9
10
    {
        if(i % 2 == 0)
        {
            out << P[i] << " ";
        }
        else
        {
            continue;
        }
    }


Okay, let's say I'm not capable of that how do I save the index to new array let's say it's named EvenArray ?
Last edited on
closed account (z05DSL3A)
DdavidDLT wrote:
And............ I still have no clue what's up with my code.

Sorry, I was responding to the "Is there any other way I can do this ?" bit in your original post.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

const char duom[] = "d.txt";
const char rez[] = "r.txt";

void read( int &n, int P[] )
{
    stringstream in( "8 \n"
                     "50 80 40 80 90 40 50 60" );    // To fake file input in cpp shell
    in >> n;
    for ( int i = 0; i != n; i++ ) in >> P[i];
}

void erase_odd( int &n, int P[] )      // *** n should be a reference
{
    int i = 0, j = 0;
    for ( ; j < n; i++, j += 2 ) P[i] = P[j];
    n = i;
}

int main()
{
    int n, P[100];

    read(n, P);

    erase_odd(n, P);

    //ofstream out(rez);
    ostream &out = cout;          // To fake file output in cpp shell
    for ( int i = 0; i < n; i++ ) out << P[i] << " ";
}


What was at P[0] will go to P[0]
What was at P[2] will go to P[1]
What was at P[4] will go to P[2]
What was at P[6] will go to P[3]
....
What was at P[j] will go to P[i], with i increasing by 1 each time, j increasing by 2 each time.
Last edited on
EDIT : Yeah I just finished writing that on paper. But what is the empty space in loop ?
 
for ( ; j < n; i++, j += 2 ) P[i] = P[j];
Last edited on
closed account (z05DSL3A)
1
2
3
int i = 0, j = 0;
for ( ; j < n; i++, j += 2 ) P[i] = P[j];
n = i;

is practically the same as
1
2
3
4
5
for (int i = 0, j = 0 ; j < n; i++, j += 2 ) 
{
    P[i] = P[j];
}
n = i; //problem with scope here though, so i and j are defined outside of the for loop. 
Last edited on
With one subtle difference over the scope of i.
closed account (z05DSL3A)
My browser was having a bit of a fit (had to post, reload, and edit). :0)
My browser was having a bit of a fit (had to post, reload, and edit). :0)

I'd opine that's more the fault of the site vs. your browser. Sometimes the scripts get overwhelmed and go on holiday for a bit.

It makes for some interesting cross-talk commentary. ;)

Not that I know nor care why it happens, that it does is all I get concerned about.
Last edited on
closed account (z05DSL3A)
All I know is the page started jumping all over when I was typing or moving the mouse...eventually got it to where I could hit submit.

Reminded me of a prank with Windows 95. Had and elephant that walked around the desktop but it ran away from the mouse.
1
2
v[i] = v[2*i];
n = n/2 + n%2;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <sstream>
using namespace std;

void read( int &n, int P[] )
{
    stringstream in( "8 \n"
                     "50 80 40 80 90 40 50 60" );
    in >> n;
    for ( int i = 0; i != n; i++ ) in >> P[i];
}

void erase_odd( int &n, int P[] )
{
    n = ( n + 1 ) / 2;
    for ( int i = 0; i < n; i++ ) P[i] = P[2 * i];
}

int main()
{
    int n, P[100];
    read(n, P);
    erase_odd(n, P);
    for ( int i = 0; i < n; i++ ) cout << P[i] << " ";
}
Topic archived. No new replies allowed.