Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[c++] porównywanie tysięcy liczb

Ostatnio zmodyfikowano 2017-12-07 20:00
Autor Wiadomość
carlosmay
» 2017-12-05 21:47:04
Jeśli ma być tylko policzone ile jest powtarzających się liczb, można tak:
C/C++
#include <iostream>
#include <algorithm>
#include <iterator>

int main()
{
    int arr[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int arr2[] { 2, 4, 6, 8, 10, 12, 14, 16 };
    std::cout << std::count_if( std::begin( arr ), std::end( arr ),
    [ & ]( int el ) { return std::find( std::begin( arr2 ), std::end( arr2 ), el ) != std::end( arr2 ); } );
}
Pisane z palca, ale powinno działać.
P-167616
grzeso
Temat założony przez niniejszego użytkownika
» 2017-12-05 21:47:20
Mam w jednym obiekcie jeden zbiór a w drugim obiekcie drugi zbiór i może da się to jakoś wykorzystać. W sensie porównać te obiekty czy coś (to tak w uproszczeniu pisze o porównaniu obiektów)

Chodzi mi o to że ktoś mi pokazywał jakąś konstrukcje bez użycia ifa i szukam inspiracji jak to odtworzyć
P-167617
pekfos
» 2017-12-05 22:17:18
carlosmay: to to samo co w pierwszym poście, tylko nie widać tych pętli. Chodzi o uniknięcie złożoności kwadratowej.

ktoś mi pokazywał jakąś konstrukcje bez użycia ifa i szukam inspiracji jak to odtworzyć
Może chodziło o ?:, różnica praktycznie tylko w zapisie.
P-167618
grzeso
Temat założony przez niniejszego użytkownika
» 2017-12-05 22:59:26
do carlosmay

kod nie za bardzo działa

moge poprosić o wyjaśnienie co to jest ten fragment:

C/C++
std::cout << std::count_if( std::begin( arr ), std::end( arr ),
[ & ]( int el ) { return std::find( std::begin( arr2 ), std::end( arr2 ), el ) != std::end( arr2 ); }

a konkretnie :
C/C++
[ & ]( int el ) { return std::find( std::begin( arr2 ), std::end( arr2 ), el ) != std::end( arr2 ); }

bo od poczatku do kończa arr szuka tego co jest wyżej?

czemu jest find to wiem, tylko find zwraca 1 element i jak to ma zadziałać na zasadzie przeszukania 2 zbiorów?
P-167619
carlosmay
» 2017-12-05 23:28:06
» Kurs C++ » Poziom XWyrażenia lambda (C++11) lekcja
Funkcja count_if liczy wystąpienia tych elementów tablicy arr, dla których
predykat zwraca true, czyli w tablicy arr2 znajdzie taką samą wartość.
Wyrażenie lambda jest tutaj użyte w roli predykatu.

kod nie za bardzo działa
Co nie działa? Daje wyniki niezgodne z oczekiwaniami, czy jest jakiś błąd kompilacji (włącz C++11).


pekfos ma rację, co do złożoności.

edit: wstawiam jeśli chce ci się analizować:
dane pochodzą z dwóch plików, zawierających dokładnie 10000 liczb z przedziału 1 - 1000000.
C/C++
#include <iostream>
#include <cstdlib>
#include <string>
#include <set>
#include <unordered_set>
#include <vector>
#include <chrono>
#include <algorithm>
#include <iterator>
#include <utility>
#include <fstream>
using namespace std;

template < typename C >
size_t count_duplicate( const C & coll_1, const C & coll_2 )
{
    return count_if( begin( coll_1 ), end( coll_1 ),
    [ & ]( auto el ) { return coll_2.find( el ) != end( coll_2 ); } );
}

template < typename C >
auto work_time_and_count_duplicate( const C & coll_1, const C & coll_2 )
{
    using tp = chrono::high_resolution_clock::time_point;
    tp start = chrono::high_resolution_clock::now();
    size_t count = count_duplicate( coll_1, coll_2 );
    tp stop = chrono::high_resolution_clock::now();
    double diff = chrono::duration_cast < chrono::duration < double >>( stop - start ).count();
    return make_pair( diff, count );
}

template < typename C >
C create_coll( const string & path )
{
    C ret = C { };
    ifstream fin( path );
    if( fin ) {
        typename C::value_type val { };
        while( fin >> val )
        {
            ret.insert( val );
        }
    }
    return ret;
}

template < typename C >
void print_arrays_state( const C & coll_1, const C & coll_2 )
{
    pair < double, size_t > count_set = work_time_and_count_duplicate( coll_1, coll_2 );
    cout << "found " << count_set.second << " dupilactes in " << count_set.first << " sec\n";
}

template < typename C >
void print_vector_state( const C & v1, const C & v2 )
{
    using hrc_tp = chrono::high_resolution_clock::time_point;
    hrc_tp start = chrono::high_resolution_clock::now();
    size_t count = count_if( begin( v1 ), end( v1 ),
    [ & ]( auto el ) { return find( begin( v2 ), end( v2 ), el ) != end( v2 ); } );
    hrc_tp stop = chrono::high_resolution_clock::now();
    double diff = chrono::duration_cast < chrono::duration < double >>( stop - start ).count();
    cout << "found " << count << " dupilactes in " << diff << " sec\n";
}

int main()
{
    string path_1 { "test_1.txt" };
    string path_2 { "test_2.txt" };
   
    set < unsigned > s1 = create_coll < decltype( s1 ) >( path_1 );
    set < unsigned > s2 = create_coll < decltype( s2 ) >( path_2 );
    print_arrays_state( s1, s2 );
   
    unordered_set < unsigned > us1 { begin( s1 ), end( s1 ) };
    unordered_set < unsigned > us2 { begin( s2 ), end( s2 ) };
    print_arrays_state( us1, us2 );
   
    vector < unsigned > v1 { begin( s1 ), end( s1 ) };
    vector < unsigned > v2 { begin( s2 ), end( s2 ) };
    print_vector_state( v1, v2 );
   
    cin.get(); // zatrzymanie konsoli, kompilacja releas
   
    return EXIT_SUCCESS;
}
Czasy analizy dla dokładnie tych samych danych:
pierwszy dla std::set
drugi dla std::unordered_set
trzeci dla tablicy std::vector
found 108 dupilactes in 0.000521103 sec
found 108 dupilactes in 0.000133919 sec
found 108 dupilactes in 0.0478203 sec
P-167620
RazzorFlame
» 2017-12-06 13:48:39
C/C++
template < typename C >
auto work_time_and_count_duplicate( const C & coll_1, const C & coll_2 )
{
    using tp = chrono::high_resolution_clock::time_point;
    tp start = chrono::high_resolution_clock::now();
    size_t count = count_duplicate( coll_1, coll_2 );
    tp stop = chrono::high_resolution_clock::now();
    double diff = chrono::duration_cast < chrono::duration < double >>( stop - start ).count();
    return make_pair( diff, count );
}
Chyba tak będzie to wyglądać czytelniej:

C/C++
template < typename C >
auto work_time_and_count_duplicate( const C & coll_1, const C & coll_2 )
{
    using hr_clock = chrono::high_resolution_clock;
    using seconds_d = chrono::duration < double >;
   
    auto start = hr_clock::now();
    auto count = count_duplicate( coll_1, coll_2 );
    auto stop = hr_clock::now();
   
    auto diff = chrono::duration_cast < seconds_d >( stop - start ).count();
    return make_pair( diff, count );
}
P-167630
grzeso
Temat założony przez niniejszego użytkownika
» 2017-12-07 20:00:47
Dzięki wielkie za pomoc, zaraz sobie to wszystko przeanalizuje
P-167715
1 « 2 »
Poprzednia strona Strona 2 z 2