DejaVu |
» 2012-01-09 20:04:36 @ison: To nie są równoważne algorytmy.
#include <vector> #include <set> #include <iostream> #include <algorithm> #include <Tools/Time.hpp>
void test1( const std::vector < int >& dane, const std::vector < int >& szukane ) { std::vector < int > v; v.reserve( dane.size() ); for( int i = 0; i < dane.size(); ++i ) { if( v.empty() || !std::binary_search( & v[ 0 ], & v[ 0 ] + v.size(), dane[ i ] ) ) { v.push_back( dane[ i ] ); std::inplace_merge( v.begin(), v.begin() + v.size() - 1, v.end() ); } bool bFound = std::binary_search( & v[ 0 ], & v[ 0 ] + v.size(), szukane[ i ] ); } }
void test2( const std::vector < int >& dane, const std::vector < int >& szukane ) { std::set < int > v; for( int i = 0; i < dane.size(); ++i ) { v.insert( dane[ i ] ); bool bFound = v.find( szukane[ i ] ) != v.end(); } } int main() { std::vector < int > dane; std::vector < int > szukane; for( int i = 0; i < 1000000; ++i ) { dane.push_back( rand() % 1000 ); szukane.push_back( rand() % 1000 ); } std::cout << "Dane gotowe." << std::endl; std::cout << "std::vector + inplace_merge: "; tools::CTime stoper; stoper.Set( 0 ); test1( dane, szukane ); std::cout.setf( std::ios::showpoint ); std::cout.setf( std::ios::fixed ); std::cout.precision( 4 ); stoper.Update(); std::cout << " Czas = " << stoper.Get() << "s" << std::endl; std::cout << "std::set: "; stoper.Set( 0 ); test2( dane, szukane ); std::cout.setf( std::ios::showpoint ); std::cout.setf( std::ios::fixed ); std::cout.precision( 4 ); stoper.Update(); std::cout << " Czas = " << stoper.Get() << "s" << std::endl; return 0; }
Results:
Dane gotowe.
std::vector + inplace_merge: Czas = 0.1326s
std::set: Czas = 0.1692s
|
|
DejaVu |
» 2012-01-09 20:10:12 Dodam jeszcze, że jakby porządnie przygotować się do tej operacji i zrobić odpowiednią klasę to w każdym przypadku std::vector będzie lepszy.
PS. Dla testu który przygotowałeś równie dobrze można zrobić algorytm O(1) dodawania i wyszukiwania :p |
|
ison |
» 2012-01-09 20:38:54 Ciekawy sposób :) Traktowanie vectora jako set, całkiem fajne. Stlowy set jest dosyć wolny więc jak widać nawet fakt, że dodawanie elementu do środka vectora jest w czasie liniowym nie wpływa jakoś rażąco. Ten kod w sumie obrazuje różnicę między dużą stałą w stlowym secie w zamian za wolne dodawanie elementu do środka vectora, ale rozwiązanie mi się podoba :) nie zawsze vector jednak będzie lepszy for( int i = 0; i < 1000000; ++i ) { dane.push_back( rand() % 2000000000 ); szukane.push_back( rand() % 2000000000 ); }
std::vector + inplace_merge: 722 ms std::set: 340 ms
//edit aa, zapomniałem, że rand() zwraca short int :D for( int i = 0; i < 100000; ++i ) { dane.push_back( rand() * rand() ); szukane.push_back( rand() * rand() ); }
wynik: std::vector + inplace_merge: 4878 ms std::set: 63 ms
:) //edit (ok, zwraca do RAND_MAX ;)) w każdym razie dla dużej ilości różnych liczb set zdecydowanie wygra pojedynek z vectorem |
|
DejaVu |
» 2012-01-09 21:50:05 Mimo wszystko std::vector jest lepszym rozwiązaniem dla zbiorów nieprzekraczających 200-250 elementów :) Siła std::set to zrównoważone drzewo binarne, którego efekty widać dopiero przy dużej ilości danych w kontenerze. Jeżeli pracujemy na dużej liczbie małych zbiorów to std::set będzie tylko zarzynał proca :) |
|
ison |
» 2012-01-09 22:05:55 zgadza się, dlatego właśnie przed wyborem algorytmu/czy czegokolwiek tam innego trzeba wziąć pod uwagę wszystkie tego typu czynniki i nie można mówić, że coś jest bezwzględnie lepsze od czegoś innego, takie podsumowanie :D |
|
pekfos |
» 2012-01-09 22:14:52 Jak wie że nic nie było dodane, to może raz posortować i przeszukać binarnie :P |
dodaj do list element sprawdź czy element+1 występuje na liście sprawdź czy element-1 występuje na liście sprawdź czy element+x występuje na liście sprawdź czy element-x występuje na liście | ... ;) |
No to raz posortuje i 4 razy sprawdzi a nie za każdym razem :P |
|
ison |
» 2012-01-09 22:21:27 @up no tak :P ale on tego (te 5 operacji) nie robi raz tylko n razy, i wtedy bardziej opłaca się trzymać cały czas posortowany ciąg tak jak to zaprezentował DejaVu albo wrzucać elementy do seta, który zrobi to za Ciebie |
|
DejaVu |
» 2012-01-09 22:26:30 Dobra, styka tych wywodów :P myślę, że wyczerpaliśmy temat więc pozwolę sobie go zamknąć.
Wnioski końcowe tego tematu: mamy braki w dokumentacji w standardowych algorytmach C++ ;p |
|
1 2 « 3 » |