Erasing odd array's element

Apr 8, 2019 at 1:57pm
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 Apr 8, 2019 at 2:01pm
Apr 8, 2019 at 2:22pm
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?
Apr 8, 2019 at 2:28pm
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 Apr 8, 2019 at 2:30pm
Apr 8, 2019 at 2:52pm
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 Apr 8, 2019 at 2:58pm
Apr 8, 2019 at 2:56pm
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);
Apr 8, 2019 at 3:12pm
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;
}
Apr 8, 2019 at 3:26pm
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 Apr 9, 2019 at 8:16am
Apr 8, 2019 at 3:36pm
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 Apr 8, 2019 at 3:51pm
Apr 8, 2019 at 3:46pm
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 Apr 8, 2019 at 3:50pm
Apr 8, 2019 at 3:55pm
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 Apr 8, 2019 at 3:56pm
Apr 8, 2019 at 3:57pm
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.
Apr 8, 2019 at 4:02pm
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 Apr 8, 2019 at 4:15pm
Apr 8, 2019 at 4:21pm
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 Apr 8, 2019 at 4:30pm
Apr 8, 2019 at 4:45pm
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 Apr 8, 2019 at 4:50pm
Apr 8, 2019 at 4:48pm
With one subtle difference over the scope of i.
Apr 8, 2019 at 4:56pm
closed account (z05DSL3A)
My browser was having a bit of a fit (had to post, reload, and edit). :0)
Apr 8, 2019 at 5:05pm
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 Apr 8, 2019 at 5:10pm
Apr 8, 2019 at 5:14pm
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.
Apr 8, 2019 at 5:37pm
1
2
v[i] = v[2*i];
n = n/2 + n%2;
Apr 9, 2019 at 9:12am
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.