Usunięcie co 2 elementu tablicy

0

Mam tablicę która ma 1440000 elementów. Potrzebuję wywalić co drugi czyli 1,3,5..7777,7779... etc. Jest może jakaś gotowa funkcja? Mogę to zrobić w pętli ale może znajdzie się gotowiec ;>

0

Pętla... Skaczesz co drugi element.

1

Robisz w pętli i dzielisz wartość indeksu tabeli modulo przez 2. Jeśli wynik == 0 to usuwasz ten element. Chyba że chcesz z tego zrobić drugą tablicę to przepisujesz tylko tą co drugą wartość.

0

Zrobiłem tak:
for (int x = 0; x < (8006003); x++){
if (x%2==0) {
bitslow[x/2] = bits[x];
}
}
Ale coś nie działa (bitslow to nowa, mniejsza tablica) :(

1
const unsigned int size = 1440000;
int* twojaGlupiaTablica = new int[size];
int* nowaGlupiaTablica = new int[size/2+1]; //+1 jeden takie zabezpieczenie, nie wiem szczerze czy jest potrzebne, nie chce mi się myśleć.
for(unsigned int i = 1; i<size;i+=2) nowaGlupiaTablica[i>>1] = twojaGlupiaTablica[i];
0

No to móiwe robie jak ty:

    const unsigned int size = 1440000;
    unsigned char* bitslow = new unsigned char[400*300*3];
    for(unsigned int i = 1; i<size; i+=2) bitslow[i>>2] = bits[i];

I crash programu (C::B)</del>

Mój błąd to crash był przez dalszy kod

0

Zastanawiałem się czy można to prosto zrobić za pomocą algorytmów z biblioteki standardowej. Okazuje się, że chyba nie ma niczego odpowiedniego. Inspirując się postem na stackoverflow napisałem takie coś do kopiowania co któregoś elementu:

template<typename InputIt, typename OutputIt>
OutputIt copy_every_nth(InputIt first, InputIt last, OutputIt d_first, size_t nth) {
  if (nth == 0) {
    throw std::invalid_argument("copy_nth: nth can't be 0");
  }    
    
  size_t counter = 0;
  
  auto pred = [&counter, nth]
  (const typename std::iterator_traits<InputIt>::value_type &) -> bool {
      
    return !(counter++ % nth);
  };
  
  return std::copy_if(first, last, d_first, pred);
}

http://ideone.com/I7wKSl

W podobny sposób można napisać remove_every_nth (zamieniając copy_if na coś innego z _if) itd. Oczywiście to bardzo ogólny zapis i prawdopodobnie prościej jest zrobić normalną pętlę z odpowiednimi licznikami, wrzucam, bo może komuś się przyda. ;-) (Najbardziej podoba mi się ogromny typ argumentu lambdy, który i tak nie jest potrzebny :->) Inną możliwością jest napisanie ładnego funktora, to teraz to po prostu algorithm-style.

O, funktor będzie np. taki:

class EveryNth {
public:
  
  EveryNth(size_t nth) :
    mNth(nth),
    mCounter(0) {
        
    if (mNth == 0) {
      throw std::invalid_argument("EveryNth: nth can't be 0");
    }
  }
    
  template<typename T>
  bool operator()(const T &) {
    return !(mCounter++ % mNth);
  }
  
  // Mało potrzebne, ale niech będzie.
  void reset() {
    mCounter = 0;      
  }
    
private:
  size_t mNth;
  size_t mCounter;
};

http://ideone.com/I7wKSl

Na dobrą sprawę to funkcjonalnie dokładnie to samo co ta lambda tylko zajmuje więcej miejsca. ;-) Można też wprowadzić dodatkowe funktory dla mniej ogólnych przypadków, żeby pozbyć się modulo. (Tak jak niżej)

Boost ma za to ładne adaptery iteratorów.

0

@Endrju, przecież jest już gotowy remove_if

struct Odd
  {
   bool f;
   Odd():f(true) {}
   bool operator()(int) { f=!f; return f; }
  };

int main()
  {
   int tb[]={1,2,3,4,5,6,7,8,9},n=sizeof(tb)/sizeof(*tb);
   for(int i=0;i<n;++i) cout<<" "<<tb[i]; cout<<endl;
   n=remove_if(tb,tb+n,Odd())-tb;
   for(int i=0;i<n;++i) cout<<" "<<tb[i]; cout<<endl;
   cin.sync(); cin.get();
   return 0;
  }

Ewentualnie: remove_if_copy
Ewentualnie:

bool Odd(int)
  {
   static bool f=true;
   f=!f;
   return f;
  }

Chociaż to nie jest bezpieczne rozwiązanie mimo że prostsze, ponieważ przed remove_if trzeba zrobić coś dziwnego:
if(!Odd(0)) Odd(0);

0

Nie potrzebnie próbujecie wcisnąć tam coś z <algorithm>. Czyż takie coś

template <class InputIterator, class OutputIterator>
OutputIterator copy_even(InputIterator first, InputIterator last, OutputIterator result)
{
    while(first != last && ++first != last) *result++ = *first++;
    return result;
}

nie będzie eleganckie?

1 użytkowników online, w tym zalogowanych: 0, gości: 1