Compress the array, removing from it all elements whose value is in the interval [a, b]. Fill in the elements at the end of the array with zeros.

Help with this task please. I replaced the elements with zeros, but as soon as I try to swap them, the program gives an error ...

http://pastebin.com/42HEW32q

help me please

for (i = 0; i < n; i++){ if ( arr[i] >= a && arr[i] <= b ){ arr[i] = arr[i+1]; arr[i] = 0; } } for (i = 0; i < n; i++){ cout << arr[i] << " "; } 
  • Give the text of the program in your answer instead of a link. - Vlad from Moscow
  • What error occurs? - Vlad from Moscow
  • arri [i + 1] probably goes beyond the limit of the array if n is its length. And i + 1 is not true, if along the array we have deleted 2 elements, then we already need +2. those. we need to increase the counter by how much to move and shift all elements at each deleted element, and not only when it doesn’t fit - Mike
  • I would suggest copying the current item x back - Mike
  • I would have trailed from the end of the array and, if I had found a number from this gap, I rotated it to this number to the right and added 0 - user31238

5 answers 5

 int i = 0, j = i; for (; i < n; i++) { if (arr[i] < a || arr[i] > b) arr[i - j] = arr[i]; else j++; } for (i = n - j; i < n; i++) arr[i] = 0; 

more understandable =)

    And it will not do? :)

     int arr[10] = { 1, 2, 5, 8, 12, 15, 45, 3, 4, 7 }; int main(int argc, const char * argv[]) { int a = 6, b = 20; fill(remove_if(arr,arr+10,[a,b](int x){ return (x >= a && x <= b); }),arr+10,0); for(auto x: arr) cout << x << " "; cout << endl; } 

    Especially for @pavel: :-)

     void removeArr(int * arr, int size, int a, int b) { struct pred { pred(int a, int b):a(a),b(b){} bool operator()(int x) { return (x >= a && x <= b); } int a, b; }; fill(remove_if(arr,arr+size,pred(a,b)),arr+size,0); } 
    • wrong conclusion) not through lambda - pavel
    • @pavel Well, here you are without lambda :) - Harry
    • I mean the opposite) cout << x << " " does not look here. Just lambda top beautiful. - pavel

    In this cycle

     for (i = 0; i < n; i++){ if ( arr[i] >= a && arr[i] <= b ){ arr[i] = arr[i+1]; arr[i] = 0; } 

    out-of-bounds occurs when i equals n-1 in a sentence

      arr[i] = arr[i+1]; 

    and besides, the body of the loop does not make sense, since first the assignment for the element with index i value arr[i+1] , and then this value is overwritten with zero.

      arr[i] = arr[i+1]; arr[i] = 0; 

    Below is a demo program showing how you can "remove" elements from an array that lie in the [a, b] segment, use loops

     #include <iostream> int main() { int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; const size_t N = sizeof( arr ) / sizeof( *arr ); for ( size_t i = 0; i < N; i++ ) std::cout << arr[i] << ' '; std::cout << std::endl; int a = 3, b = 6; size_t k = 0; for ( size_t i = 0; i < N; i++ ) { if ( not ( a <= arr[i] && arr[i] <= b ) ) { if ( i != k ) arr[k] = arr[i]; ++k; } } for ( size_t i = k; i < N; i++ ) arr[i] = 0; for ( size_t i = 0; i < N; i++ ) std::cout << arr[i] << ' '; std::cout << std::endl; return 0; } 

    Output of the program to the console

     0 1 2 3 4 5 6 7 8 9 0 1 2 7 8 9 0 0 0 0 

    The same can be done using standard algorithms. For example,

     #include <iostream> #include <algorithm> int main() { int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; const size_t N = sizeof( arr ) / sizeof( *arr ); for ( size_t i = 0; i < N; i++ ) std::cout << arr[i] << ' '; std::cout << std::endl; int a = 3, b = 6; size_t k = 0; std::fill( std::remove_if( arr, arr + N, [&]( int x ) { return a <= x && x <= b; } ), arr + N, 0 ); for ( size_t i = 0; i < N; i++ ) std::cout << arr[i] << ' '; std::cout << std::endl; return 0; } 

    The output of this program is similar to the one shown above.

     0 1 2 3 4 5 6 7 8 9 0 1 2 7 8 9 0 0 0 0 

      In addition to the answers already given. You can do just one cycle with two indices. As soon as the first index reaches the end of the array, all elements between the second index and the end can be replaced with 0.

       for(int i=0, j=0;i<N;){ if(j<N){ if(!(arr[j] >= a && arr[j] <=b)){ i++; } arr[i]=++j<N? arr[j]:0; } else{ arr[i++]=0; } } 

      Example on ideone

        What do you think will happen here?

        arr[i] = arr[i+1];

        with i = n - 1 ?

        Here is the code for you. Optimization at your discretion

         int i = 0; int lastIdx = n - 1; while (i <= lastIdx) { if (arr[i] >= a && arr[i] <= b) { for (int j = i; j < lastIdx; j++) arr[j] = arr[j + 1]; arr[lastIdx--] = 0; } else i++; } 
        • Thank you very much) I figured it out - Roman