ile razy liczba jest w tablicy

0

Czy ktoś wyjaśni co w tym kodzie jest źle ? Chodzi o to, że chcę sprawdzić ile razy dana liczba występuje w tablicy.

int main(void)
{
    int tab[10]={1,2,2,2,5,6,7,8,9,10};
    int liczba;
    int licznik=0;

    for(int i=0; i<10; i++){
        liczba=tab[i];

        for(int j=0; j<i; j++){
            if(liczba==tab[j]){
                std::cout << "liczba " << liczba << " wystepuje " << licznik << " razy" << std::endl;
            }
            licznik++;
        }
    }
    return 0;
}
3

Nie zerujesz licznik przy przeskakiwaniu do kolejnej liczby.

A tak swoją drogą: std::count

3

Użyj std::unordered_map<unsigned int, unsigned int>

klucz = liczba
wartość = częstotliwość(l. wystąpień)

2

Użyj std::count

#include <iostream>
#include <set>
#include <algorithm>

using namespace std;

int main()
{
    int tab[] {1,2,2,2,5,6,7,8,9,10};

    for( const auto number : set<int>(cbegin(tab),cend(tab)) )
    cout << number << " -> " << count( begin(tab) , end(tab) , number ) << endl;

    return 0;
}
2

Nie zerujesz licznik no i wypisywać powinieneś raczej po skończonym zlliaczniu a nie w trakcie. Poza tym możesz to napisać dużo krócej

int tab[]={1,2,2,2,5,6,7,8,9,10};
for(auto num : tab)
   std::cout << "liczba " << num << " wystepuje " << std::count(std::begin(tab), std::end(tab), num) << " razy\n";

Powyższy kod ma oczywiście ten minus, że wypisze również już wcześniej podliczone liczby, ale to już możesz dodać sobie sam.

0

ten powyższy algorytm nie był zbyt dobry, problem powtarzających się liczb rozwiązałem w ten sposób

int *sort(int[]);

int wiersz=9;

int main(void)
{
    int tDane[9]={4,3,3,3,2,1,1,1,4};
    int tDaneIlePowt[1][1];
    int ile_liczb=0;
    int element=0;
    int ile_danych=0;
    int z_pom;
    int *wDane;

    wDane = sort(&tDane[0]);

    for(int i=0; i<9; i++){
        z_pom = wDane[i];
        for(int j=element; j<9; j++){
            if(z_pom == wDane[j]){
                ile_liczb++;
                element++;
            }
            else{
                break;
            }
        }

        if(ile_liczb != 0){
            std::cout << "liczba " << wDane[i] << " wystepuje " << ile_liczb << " raz(y)" << std::endl;
            ile_danych++;
        }

        ile_liczb=0;
    }

    delete [] wDane;
    wDane = nullptr;

    return 0;
}

int *sort(int tSort[])
{
    int *_tSort = new int [wiersz];
    int zm_pom;

    for(int i=0; i<wiersz; i++){
        _tSort[i] = tSort[i];
    }

    for(int i=0; i<wiersz; i++){
        zm_pom = _tSort[i];

        for(int j=i+1; j<wiersz; j++){
            if(_tSort[j] < zm_pom){
                zm_pom = _tSort[j];
                _tSort[j] = _tSort[i];
                _tSort[i] = zm_pom;
            }
        }
    }

    return &_tSort[0];
}

i teraz mam pytanie - czy da radę napisać algorytm w taki sposób aby możliwe było zliczanie powtarzających się elementów ale bez sortowania ?

np - w tablicy mam takie liczby

4,3,3,3,2,1,1,1,4

czy da radę zliczyć ilość powtarzających się cyfr bez sortowania tablicy ?

Uprzedzam od razu, że nie stosuję się do standardu, co widać gołym okiem (jeszcze za wcześnie na standardy)

0

@kq kod severala zwraca to:

screenshot-20201026113735.png

za dużo tych wyników, skompiluj mój kod i zobacz jak to wygląda

3
template<typename T>
auto histogramize(T&& t) -> std::map<std::decay_t<decltype(*std::begin(t))>, size_t>
{
    std::map<std::decay_t<decltype(*std::begin(t))>, size_t> ret;
    for(auto const& el : t)
        ret[el]++;
    return ret;
}

int main()
{
    int tab[] {1,2,2,2,5,6,7,8,9,10,-1,2};

    for(auto const& [value, count] : histogramize(tab))
        cout << value << " -> " << count << "\n";

    return 0;
}

https://wandbox.org/permlink/PXjg8Q0aEyvfL7vO

0

a tak swoją drogą, ciekawe czy ktoś z was wie jak usunąć wyciek pamięci w tym przypadku ? Zadaję pytanie, ponieważ jakoś ten problem rozwiązano ? I częściowo po to ten algorytm powstał aby zrozumieć jak usuwać wycieki pamięci w różnych przypadkach - tak, wiem, że lubicie gotowe rozwiązania w postaci standardu ale ja chcę się nauczyć i zrozumieć pewne rzeczy — zkubinski dziś, 11:20

Jak? W pełni stosować C++ - a nie tylko C ze strumieniami.
Strzelam, ze być może w pięć sposobów można to pozytywnie rozwiązać. Dwa najszybciej nasuwające się: smartpointery, kontenery C++

4

Ok, co tutaj jest źle, i czemu to jest bardziej C ze strumieniami, a nie C++, to wyjaśnię (nie jest to też dobre C, ale to inna sprawa):

  1. W C++ sygnatura int main(void) jest niepoprawna (ale za to w C jest poprawna).
  2. Mieszana konwencja, z jednej strony snake case (z_pom), z drugiej camel case (wDane).
  3. Magiczne stałe (9), a można było zrobić constexpr size_t size = std::size(tDane)
  4. Nazwy typu element nic sensownego nie wyrażają, tak samo jak z_pom, która by mogła być nazwana np. previous_element.
  5. int tDaneIlePowt[1][1];? Dwuwymiarowa tablica jednoelementowa? Czym to jest w ogóle uzasadnione?
  6. tDane -> czemu służy przedrostek t?
  7. Pętla for(int j=element; j<9; j++){ if (warunek) { coś; } else {break;}} to tak naprawdę powinna być pętla while.
  8. Irracjonalne użycie pary new[] i delete[] - tutaj powinien być std::vector. Dzięki temu zyskasz RAII, jawne wyrażenie tego kiedy i przez kogo zasoby powinny być zwolnione, a także wyrażasz intencję funkcji sort, która notabene powinna mieć sygnaturę int* sort(const int[]), albo jeszcze lepiej wersję gdzie podajesz rozmiar, int* sort(const int[], size_t).
  9. Używanie własnego swapowania zamiast std::swap.
  10. &_tSort[0] zamiast _tSort
  11. W ogóle pisanie takiej funkcji sortującej tylko dla intów, a nie jako funkcja szablonowa dla dowolnych częściowo uporządkowanych typów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0