eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › Masowe wyszukiwanie anagramów
Ilość wypowiedzi w tym wątku: 14

  • 11. Data: 2016-04-05 00:17:21
    Temat: Re: Masowe wyszukiwanie anagramów
    Od: slawek <f...@f...com>

    Wystarczy wypisać wszystkie słowa w dwu kolumnach, dwa razy obok
    siebie. Litery z pierwszej kolumny posortować wiersz po wierszu.
    Potem posortować wiersze jako klucza używając ciągów znaków z
    pierwszej kolumny. Klasyka.

    Pierwsze sortowanie kosztuje O(N) zakładając że ilość liter na słowo
    jest mniejsza niż pewna stała. Drugie to O(N log N). Czyli tyle ma
    cały algorytm.

    Pamięciowo jest przyzwoicie: circa 2 razy tyle co słownik.

    Hale fun.


  • 12. Data: 2016-04-05 01:54:54
    Temat: Re: Masowe wyszukiwanie anagramów
    Od: bartekltg <b...@g...com>

    On 04.04.2016 17:35, Borneq wrote:
    > W dniu 04.04.2016 o 17:20, Borneq pisze:
    >> Jak najszybciej wyszukać anagramy? Mam słownik 100-200 tyś słów, i
    >> kolejne słowa próbuję.
    >> Może tak, że słownik przestawię w postaci pary - słowa
    >> posortowanego,słowa?
    >> np.
    >> abcino,bocian
    >> ?

    Całkowicie wysatrczy.

    > Tylko jak to sortować?,

    funckją sort? ;-)


    > sortowanie kubełkowe? czy to sortowanie nie
    > stwarza problemów, gdy jakaś litera się powtarza,

    Nie.

    > Kubełków mogło by byc
    > mało dla ASCII, ale trzeba by dużej liczby dla Unicodu

    Hmm, ciekawostka, patrząc na tabelkę utf-8 traktując
    wyrazy jak ciagi bajtów i sortując te bajty nie spowodujesz
    niezamierzonej kolizji;-) żadne "ęąń" nie okaże się tym samym ciągiem
    co "ółś"


    Albo czegoś nie mówisz, albo przekombinowujesz:


    #include <vector>
    #include <string>
    #include <iostream>
    #include <algorithm>



    using namespace std;


    int main()
    {

    vector <pair<string, string > > S;
    string str,strs;

    while ( cin>>str )
    {
    strs=str;
    sort(strs.begin(),strs.end());

    S.emplace_back( strs,str );
    }

    sort(S.begin(),S.end());

    for (auto it = S.begin(); it!=S.end();)
    {
    auto itend = next(it);
    while (itend!=S.end() && itend->first == it->first) ++itend;
    if (distance(it, itend)>1)
    {
    cout<<"-- "<<distance(it, itend)<<endl;
    while (it!=itend)
    cout<<(it++)->second<<endl;

    }
    else it++;
    }

    return 0;
    }

    Dłużej piszę posta niż pisałem ten kod,
    http://sjp.pl/slownik/growy/
    2.7 mln słow, 38MB,
    time ./untitled <slowa.txt >bla.txt
    real 0m5.638s

    Nie jest poprawny dla unikodu, ale dzięki uwadze powyżej - działa ;-)

    Rekordzista
    -- 13
    akrom
    arkom
    kamor
    karmo
    karom
    komar
    makro
    marko
    mokra
    morka
    okarm
    rakom
    ramko


    pzdr
    bartekltg



  • 13. Data: 2016-04-05 14:32:08
    Temat: Re: Masowe wyszukiwanie anagramów
    Od: "M.M." <m...@g...com>

    On Tuesday, April 5, 2016 at 1:54:56 AM UTC+2, bartekltg wrote:
    > On 04.04.2016 17:35, Borneq wrote:
    > > W dniu 04.04.2016 o 17:20, Borneq pisze:
    > >> Jak najszybciej wyszukać anagramy? Mam słownik 100-200 tyś słów, i
    > >> kolejne słowa próbuję.
    > >> Może tak, że słownik przestawię w postaci pary - słowa
    > >> posortowanego,słowa?
    > >> np.
    > >> abcino,bocian
    > >> ?
    >
    > Całkowicie wysatrczy.
    >
    > > Tylko jak to sortować?,
    >
    > funckją sort? ;-)
    >
    >
    > > sortowanie kubełkowe? czy to sortowanie nie
    > > stwarza problemów, gdy jakaś litera się powtarza,
    >
    > Nie.
    >
    > > Kubełków mogło by byc
    > > mało dla ASCII, ale trzeba by dużej liczby dla Unicodu
    >
    > Hmm, ciekawostka, patrząc na tabelkę utf-8 traktując
    > wyrazy jak ciagi bajtów i sortując te bajty nie spowodujesz
    > niezamierzonej kolizji;-) żadne "ęąń" nie okaże się tym samym ciągiem
    > co "ółś"
    >
    >
    > Albo czegoś nie mówisz, albo przekombinowujesz:
    >
    >
    > #include <vector>
    > #include <string>
    > #include <iostream>
    > #include <algorithm>
    >
    >
    >
    > using namespace std;
    >
    >
    > int main()
    > {
    >
    > vector <pair<string, string > > S;
    > string str,strs;
    >
    > while ( cin>>str )
    > {
    > strs=str;
    > sort(strs.begin(),strs.end());
    >
    > S.emplace_back( strs,str );
    > }
    >
    > sort(S.begin(),S.end());
    >
    > for (auto it = S.begin(); it!=S.end();)
    > {
    > auto itend = next(it);
    > while (itend!=S.end() && itend->first == it->first) ++itend;
    > if (distance(it, itend)>1)
    > {
    > cout<<"-- "<<distance(it, itend)<<endl;
    > while (it!=itend)
    > cout<<(it++)->second<<endl;
    >
    > }
    > else it++;
    > }
    >
    > return 0;
    > }
    >
    > Dłużej piszę posta niż pisałem ten kod,
    > http://sjp.pl/slownik/growy/
    > 2.7 mln słow, 38MB,
    > time ./untitled <slowa.txt >bla.txt
    > real 0m5.638s
    >
    > Nie jest poprawny dla unikodu, ale dzięki uwadze powyżej - działa ;-)
    >
    > Rekordzista
    > -- 13
    > akrom
    > arkom
    > kamor
    > karmo
    > karom
    > komar
    > makro
    > marko
    > mokra
    > morka
    > okarm
    > rakom
    > ramko
    >
    >
    > pzdr
    > bartekltg

    Na hash-table z QT działa z kompilacją 02 na procesorze i3 działa
    ciut wolniej:



    int main(int argc, char *argv[])
    {
    QTextStream in(stdin);
    in.setCodec("UTF-8");
    QString line;
    QMultiHash<QString,QString> hash;

    while( ! ( line = in.readLine() ).isEmpty() ) {
    QString sort = line;
    qSort( sort.begin() , sort.end() );
    hash.insert( sort , line );
    }

    QStringList max;
    QStringList keys = hash.uniqueKeys();
    for( int i=0 ; i<keys.size() ; i++ ) {
    if( max.size() < hash.values( keys[i] ).size() )
    max = hash.values( keys[i] );
    }

    for( int i=0 ; i<max.size() ; i++ )
    printf("%d %s\n",i+1,qPrintable(max[i]));
    fflush(stdout);

    return 0;
    }




    x@x:~/tmp/build-anagrams-Desktop-Release$ time cat ~/Pobrane/slowa.txt | ./anagrams
    1 ramko
    2 rakom
    3 okarm
    4 morka
    5 mokra
    6 marko
    7 makro
    8 komar
    9 karom
    10 karmo
    11 kamor
    12 arkom
    13 akrom

    real 0m6.810s
    user 0m6.535s
    sys 0m0.325s


  • 14. Data: 2016-04-05 15:28:35
    Temat: Re: Masowe wyszukiwanie anagramów
    Od: "M.M." <m...@g...com>

    On Tuesday, April 5, 2016 at 2:32:10 PM UTC+2, M.M. wrote:
    > On Tuesday, April 5, 2016 at 1:54:56 AM UTC+2, bartekltg wrote:
    > > On 04.04.2016 17:35, Borneq wrote:
    > > > W dniu 04.04.2016 o 17:20, Borneq pisze:
    > > >> Jak najszybciej wyszukać anagramy? Mam słownik 100-200 tyś słów, i
    > > >> kolejne słowa próbuję.
    > > >> Może tak, że słownik przestawię w postaci pary - słowa
    > > >> posortowanego,słowa?
    > > >> np.
    > > >> abcino,bocian
    > > >> ?
    > >
    > > Całkowicie wysatrczy.
    > >
    > > > Tylko jak to sortować?,
    > >
    > > funckją sort? ;-)
    > >
    > >
    > > > sortowanie kubełkowe? czy to sortowanie nie
    > > > stwarza problemów, gdy jakaś litera się powtarza,
    > >
    > > Nie.
    > >
    > > > Kubełków mogło by byc
    > > > mało dla ASCII, ale trzeba by dużej liczby dla Unicodu
    > >
    > > Hmm, ciekawostka, patrząc na tabelkę utf-8 traktując
    > > wyrazy jak ciagi bajtów i sortując te bajty nie spowodujesz
    > > niezamierzonej kolizji;-) żadne "ęąń" nie okaże się tym samym ciągiem
    > > co "ółś"
    > >
    > >
    > > Albo czegoś nie mówisz, albo przekombinowujesz:
    > >
    > >
    > > #include <vector>
    > > #include <string>
    > > #include <iostream>
    > > #include <algorithm>
    > >
    > >
    > >
    > > using namespace std;
    > >
    > >
    > > int main()
    > > {
    > >
    > > vector <pair<string, string > > S;
    > > string str,strs;
    > >
    > > while ( cin>>str )
    > > {
    > > strs=str;
    > > sort(strs.begin(),strs.end());
    > >
    > > S.emplace_back( strs,str );
    > > }
    > >
    > > sort(S.begin(),S.end());
    > >
    > > for (auto it = S.begin(); it!=S.end();)
    > > {
    > > auto itend = next(it);
    > > while (itend!=S.end() && itend->first == it->first) ++itend;
    > > if (distance(it, itend)>1)
    > > {
    > > cout<<"-- "<<distance(it, itend)<<endl;
    > > while (it!=itend)
    > > cout<<(it++)->second<<endl;
    > >
    > > }
    > > else it++;
    > > }
    > >
    > > return 0;
    > > }
    > >
    > > Dłużej piszę posta niż pisałem ten kod,
    > > http://sjp.pl/slownik/growy/
    > > 2.7 mln słow, 38MB,
    > > time ./untitled <slowa.txt >bla.txt
    > > real 0m5.638s
    > >
    > > Nie jest poprawny dla unikodu, ale dzięki uwadze powyżej - działa ;-)
    > >
    > > Rekordzista
    > > -- 13
    > > akrom
    > > arkom
    > > kamor
    > > karmo
    > > karom
    > > komar
    > > makro
    > > marko
    > > mokra
    > > morka
    > > okarm
    > > rakom
    > > ramko
    > >
    > >
    > > pzdr
    > > bartekltg
    >
    > Na hash-table z QT działa z kompilacją 02 na procesorze i3 działa
    > ciut wolniej:
    >
    >
    >
    > int main(int argc, char *argv[])
    > {
    > QTextStream in(stdin);
    > in.setCodec("UTF-8");
    > QString line;
    > QMultiHash<QString,QString> hash;
    >
    > while( ! ( line = in.readLine() ).isEmpty() ) {
    > QString sort = line;
    > qSort( sort.begin() , sort.end() );
    > hash.insert( sort , line );
    > }
    >
    > QStringList max;
    > QStringList keys = hash.uniqueKeys();
    > for( int i=0 ; i<keys.size() ; i++ ) {
    > if( max.size() < hash.values( keys[i] ).size() )
    > max = hash.values( keys[i] );
    > }
    >
    > for( int i=0 ; i<max.size() ; i++ )
    > printf("%d %s\n",i+1,qPrintable(max[i]));
    > fflush(stdout);
    >
    > return 0;
    > }
    >
    >
    >
    >
    > x@x:~/tmp/build-anagrams-Desktop-Release$ time cat ~/Pobrane/slowa.txt | ./anagrams

    > 1 ramko
    > 2 rakom
    > 3 okarm
    > 4 morka
    > 5 mokra
    > 6 marko
    > 7 makro
    > 8 komar
    > 9 karom
    > 10 karmo
    > 11 kamor
    > 12 arkom
    > 13 akrom
    >
    > real 0m6.810s
    > user 0m6.535s
    > sys 0m0.325s

    A samoróbka na hashach szybsza:


    x@x:~/tmp/build-anagrams-Desktop-Release$ time cat ~/Pobrane/slowa.txt | ./anagrams
    1 ramko
    2 rakom
    3 okarm
    4 morka
    5 mokra
    6 marko
    7 makro
    8 komar
    9 karom
    10 karmo
    11 kamor
    12 arkom
    13 akrom

    real 0m2.962s
    user 0m2.666s
    sys 0m0.348s



    #include <QString>
    #include <QTextStream>

    #define HASH_SIZE (1024*1024*12)
    #define STACK_SIZE (1024*1024*3)
    #define KEYS_SIZE (1024)

    struct Item {
    QString str;
    QString sort;
    Item *next;
    };

    static int count[HASH_SIZE];
    static Item *hash[HASH_SIZE];
    static Item stack[STACK_SIZE];
    static int stack_size = 0;
    static unsigned int keys[KEYS_SIZE];


    static void initKeys() {
    for( int i=0 ; i<KEYS_SIZE*1 ; i++ )
    keys[i % KEYS_SIZE] = (keys[ i % KEYS_SIZE ] * 16) ^ qrand();
    }


    static unsigned int mkKey( const QString &str ) {
    unsigned int key = 0;
    for( int i=0 ; i<str.size() ; i++ )
    key ^= keys[ str[i].unicode() % KEYS_SIZE ];
    return key % HASH_SIZE;
    }

    static void insert( QString &str ) {
    unsigned int key = mkKey( str );
    stack[stack_size].str = str;
    qSort( str.begin() , str.end() );
    stack[stack_size].sort = str;
    while( hash[key] && hash[key]->sort != str )
    key = (key+1) % HASH_SIZE;
    if( hash[key] ) {
    stack[stack_size].next = hash[key];
    }
    hash[key] = stack + stack_size ++;
    count[key] ++ ;
    }

    int main( int argc, char *argv[] )
    {
    qsrand(123);

    QTextStream in(stdin);
    in.setCodec("UTF-8");

    initKeys();

    QString line;

    while( ! ( line = in.readLine() ).isEmpty() ) {
    insert( line );
    }

    int max = 0;
    for( int i=1 ; i<HASH_SIZE ; i++ )
    if( count[max] < count[i] )
    max = i;
    Item *entry = hash[max];
    int nr=1;
    while( entry ) {
    printf("%d %s\n",nr++,qPrintable(entry->str));
    entry = entry->next;
    }


    return 0;
    }




strony : 1 . [ 2 ]


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: