Wpis z mikrobloga

#cpp #programowanie

Dobra załóżmy, że mam wektor intów i chce go posortować, jak to zrobić ładnie? Ale żeby zera były na końcu?

Niby mogę zrobić sort i później jakoś wyłuskać te zera i przerzucić na koniec, ale nie wydaje mi się to optymalne ;/ A operatora porwania nie da rady napisać, żeby sorta oszukać...
  • 29
@kasper93: napisz wlasne sortowanie quick sort nie zawsze jest najlepszy.

EDIT: tak mi szybko przyszło do głowy.

Ja bym na szybko policzyl zera i usunal je z wektora, potem posortowal wektor i dodal zera na koniec :>
@KrzaQ2: Co jest wymyslaniem kola na nowo bo nie bardzo rozumiem ? Funkce sortujaca można napisać w kilka minut i będzie działać tak jak od niej oczekujesz.
operatora porwania nie da rady napisać, żeby sorta oszukać...


@sw69: No jak to nie? Nie mniej jednak, lepiej tego nie robić. Odpowiednia byłaby własna funkcja sortująca. A quicksort zawsze jest najlepszy, chyba że masz jakieś bardzo niestandardowe dane (na przykład prawie posortowane).

bool compare(int a, int b) {

return (a != 0)? (a < b) : false;

}

sort(vector.begin(), vector.end(), compare);

Ta funkcja compare zwraca, czy a jest mniejsze od b
@sw69: Funkcje sortujące są juƶ dostępne w bibliotece standardowej. Napisanie własnej to marnowanie czasu, szczególnie, ƶe efektem takiego działania będzie prawie zawsze mniej wydajny kod, który moƶe zawierać błędy.
bool compare(int a, int b) {


return (a != 0)? (a < b) : false;


}

@Onoki: To była moja pierwsza myśl, żeby zrobić coś takiego. Ale to oczywiście nie działa, bo funkcja jest niepoprawna dla nieliniowego porównania. Owszem, jeżeli b byłby zawsze następnym elementem to tak, ale inaczej... Zresztą wywala assert, że funkcja porównująca jest niepoprawna.

@deekox: Dzięki, właśnie po chwili zastanowienia miałem spróbować sprawdzać a i b :)
@kasper93: Oj rzeczywiście, pomyliłem się. :)

A spróbuj

return (a != 0 && b != 0)? (a < b) : (a > b);

Zwraca mniejszy element jeżeli oba są niezerowe, większy (w szczególności niezerowy) w przeciwnym razie. :) W tamtym poprzednim zapomniałem, że b może też być zerem.
@Onoki: @KrzaQ2: W sumie nie powinno się zdarzyć ujemne, ale zawsze lepiej uwzględniać ten przypadek.

Tak więc bazując na Twojej propozycje zrobiłem tak i za chwilę przetestuje, ale powinno być ok.

return (a.GetOrgNumber() == 0 && b.GetOrgNumber() == 0) ? less()(a.GetNumber(), b.GetNumber()) : (a.GetOrgNumber() == 0 || b.GetOrgNumber() == 0) ? b.GetOrgNumber() == 0 : less()(a.GetOrgNumber(), b.GetOrgNumber());
Ps. W tym przypadku już nie muszę mieć XORa, bo i tak wcześniej
@kasper93: Nie wiem po co powtarzasz warunki



int
```**```
 l = a.GetOrgNumber();
```**```
int
```**```
 r = b.GetOrgNumber();
```**```
return
```**```
 (l == 0) ^ (r == 0) ? r == 0 : l < r;
@kasper93 jak koncznie n chcesz xora, to dla dwóch zer zwróć

false
, to wynik tego porównania zawsze taki sam jest.



int
```**```
 l = a.GetOrgNumber();
```**```
int
```**```
 r = b.GetOrgNumber();
```**```
return
```**```
 (l == 0 && r == 0) ? 
```**```
false
```**```
 : (l == 0 || r == 0) ? r == 0 : l < r;
@KrzaQ2: Zwróć uwagę, że sprawdzam inną liczbę jak przy obu mam zero. Ogólnie jedna może być zerowe, druga nie i chodzi o to, żeby te zerowe elementy też były posortowane wg. innego kryterium.

a.GetNumber();

a.GetOrgNumber();