• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przywódca ciągu

Object Storage Arubacloud
+1 głos
798 wizyt
pytanie zadane 18 grudnia 2018 w C i C++ przez BinaryMan Stary wyjadacz (12,620 p.)

Witam ! 
Sprawa dotyczy znajdowania przywódcy danego ciągu jak w temacie, otóż: 
Mamy sobie jakiś ciąg n-wyrazowy. Podajemy k i słaby przywódca (jeden z nich) jest wtedy gdy występuje więcej niż n/k razy w danym ciągu. 

Oto algorytm znajdowania przywódcy w danym ciągu: 
 

#include <iostream>

using namespace std;

int main()
{
    int n = 0, k = 0;
    cin >> n >> k;

    //int n_przez_k = n / k; // slaby przywodca musi wystapic wiecej jak ta liczba w podadnym ciagu.

    cout << n / k << endl;

    int tab[n];
    for (int i = 0; i < n; i++)
    {
        cin >> tab[i];
    }

    cout << "Tablica ma postac: " << endl;
    for (int i = 0; i < n; i++)
    {
        cout << tab[i] << " ";
    }
    cout<<endl;

    int przywodca;
    int licz = 0;

    for (int i = 0; i < n; ++i)
    {
        if (licz == 0)
        {
            przywodca = tab[i];
            ++licz;
            cout << "licz: " << licz << endl;
        }
        else if (przywodca == tab[i])
        {
            ++licz;
            cout << "licz: " << licz << endl;
        }
        else
        {
            --licz;
            cout << "licz: " << licz << endl;
        }
    }

    //cout << endl;
    cout << "Przywodca to: " << przywodca << endl;

    return 0;
}

Zasada działania: Widząc nowy element zakładamy, że jest on przywódcą i liczymy, o ile razy więcej wystąpi w stosunku do pozostałych.

Ma to swoje wady, gdyż powiedzmy dla ciągu 1 2 3 4 5 6 7 nie ma przywódcy a program "wydrukuje" 7 gdyż w ostatniej iteracji to właśnie 7 będzie przywódcą. 
Moje pytanie to jak mogę uzależnić liczbę liczników przykładowych przywódców od zmiennej k, gdyż  wydaje mi się że to jest klucz w tym zadaniu. 
Zapraszam do pogadanki w komentarzach. 
Dziękuję za odpowiedzi !

Wesołych Świąt ! smiley

 

2 odpowiedzi

+1 głos
odpowiedź 18 grudnia 2018 przez mokrowski Mędrzec (155,460 p.)
wybrane 28 grudnia 2018 przez BinaryMan
 
Najlepsza
Rozwiązanie to użycie 2 elementów biblioteki standardowej C++:

https://en.cppreference.com/w/cpp/container/unordered_map - bo niepotrzebne Ci sortowanie

https://en.cppreference.com/w/cpp/algorithm/max_element - 3 rodzaj wywołania z komparatorem

Zamkniesz się w złożoności obliczeniowej O(n)

A jak nie wiesz jak to zaimplementować (lub nie możesz użyć), to poczytaj o tych rozwiązaniach abyś nie wymyślał koła na nowo.
komentarz 18 grudnia 2018 przez Aisekai Nałogowiec (42,190 p.)
Nie wiem, czy szukanie max elementu jest konieczne. Jeżeli założeniem jest to, że funkcja ma zwracać element dla którego liczba wystąpień jest większa od n/k to wystarczy na bieżąco sprawdzać czy ilość wystąpień jest większa od n/k. Wtedy w wielu przypadkach, nawet nie będzie trzeba iterować po elementach do końca.
1
komentarz 18 grudnia 2018 przez mokrowski Mędrzec (155,460 p.)
Możliwe. Klasy algorytmu to nie zmieni. Założyłem że celem jest znalezienie najlepszego. Jeśli tylko słabego, wystarczy sprawdzać w trakcie inkrementacji wystąpienia.
komentarz 19 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
Nie do końca wiem jak zastosować dobrze tą map-ę. Wiem natomiast że mapa musi być mniejsza bądź równa k
komentarz 19 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
Jeśli dobrze zrozumiałem to robię map<int, int> pierwszy int to jest ograniczona przez wprowadzone k, a druga to zliczanie wystąpień poszczególnej liczby tak ?
komentarz 19 grudnia 2018 przez mokrowski Mędrzec (155,460 p.)
Tak. Z tym że drugi int to raczej unsigned, i raczej nie std::map tylko std::unordered_map. std::map wykonuje przy każdym wstawieniu sortowanie po kluczu które jest tu Ci zupełnie zbędne.
komentarz 19 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
OKay i to wszystko w pętli którą teraz mam, czy skasować ją i stworzyć coś innego ?
komentarz 19 grudnia 2018 przez mokrowski Mędrzec (155,460 p.)
#include <unordered_map>
#include <iostream>

int main() {
    int data[] = { 1,2,3,4,5,3,3,3,4,2};
    std::unordered_map<int, unsigned> count;
    for (auto v: data) {
        count[v]++;
    }
    for (const auto& p: count) {
        std::cout << "key: " << p.first << ' '
            << "value: " << p.second << '\n';
    }
}

 

komentarz 27 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
Kod się niestety nie kompiluje poprawnie :(
komentarz 27 grudnia 2018 przez mokrowski Mędrzec (155,460 p.)
Czas użyć kompilatora wspierającego C++11. To już 8 lat na rynku jest. Masz kompilator starszy niż gcc 4.7.1 ? https://godbolt.org/z/Lbbq3q
0 głosów
odpowiedź 18 grudnia 2018 przez Aisekai Nałogowiec (42,190 p.)
Mam poważne wątpliwości, czy ten algorytm działa. Załóżmy tak:

-tablica składa się z elementów: 2,2,3,3,3,5,5

-k dobrane tak, że n/k =  2

A więc tak. Domniemamy, że '2' jest przywódcą. Po przejściu do 2 indeksu, mamy licz=2, przywodca=2. Potem po przejściu do 5 indeksu mamy tak, że licz=1, przywodca = 3. Na samym końcu mamy, że licz=1, przywodca=5 (o ile dobrze na szybko liczę i zrozumiałem twój algorytm). Więc teoretycznie nie ma żadnego przywódcy - praktycznie jest i jest to '3'.

Nie znam wszystkich założeń zadania. Nie wiem, czy w przypadku gdy jest więcej niż jeden przywódca, to mogę zwrócić jedną liczbę czy wszystkie? Na pętlach to bym do tego nie podchodził, bo żeby to na pętlach zrobić to algorytm miałby O(n^2) - w najgorszym przypadku. Podszedł bym do tego w najprostszy sposób. W Mapie<k,v> przechowywałbym ile razy (v) wystąpił element (k). W chwili gdy v będzie większe od n/k zwróciłbym v. Przeszedłbym też na funkcje, a nie pisał wszystko w mainie.
komentarz 18 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
Mam zwrócić jednego z przywódców przywódców. Do tego mam właśnie wykorzystać algorytm wyżej. Jeśli chodzi o mapy to masz na myśli to :
http://www.cplusplus.com/reference/map/map/
komentarz 18 grudnia 2018 przez Aisekai Nałogowiec (42,190 p.)
Prawdopodobnie tak. W javie piszę, ale z tego co wiem w C++ też są mapy i też da się to zrobić na mapach
komentarz 18 grudnia 2018 przez BinaryMan Stary wyjadacz (12,620 p.)
Okay poczytam o tym i jutro coś pokombinuję. Póki co dzięki :)

Podobne pytania

0 głosów
0 odpowiedzi 150 wizyt
pytanie zadane 7 czerwca 2018 w C i C++ przez MrRed Nowicjusz (160 p.)
0 głosów
1 odpowiedź 801 wizyt
pytanie zadane 28 lutego 2018 w C i C++ przez janusz1 Początkujący (330 p.)
0 głosów
2 odpowiedzi 1,127 wizyt
pytanie zadane 7 czerwca 2018 w C i C++ przez adamus Użytkownik (860 p.)

92,579 zapytań

141,432 odpowiedzi

319,664 komentarzy

61,964 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...