Program zliczający ilość występowań każdego elementu

0

Cześć, tak jak w temacie, potrzebuje pomcy z programem, ktory bedzie zliczal ilosc kazdego elementu, ktory wystepuje w tablicy.
Wymyśliłem coś takiego.

Tworzymy tablicę oraz drugą tablicę z identycznymi elementami. Sprawdzamy czy dany element z pierwszej tablicy jest równy elementowi, który jest iterowany za pomocą drugiej pętli. Gdy dany element z pierwszej petli będzie równy elementowi z drugiej pętli, to ma się to dodać. I tutaj się pojawia problem, nie wiem jak ogarnąć ostatnie zdanie. Co tam musze wpisać, bo przeciez nie bede tworzyl zmiennych suma_1, suma_2 etc...

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int max,min;
    int i,n,j;
    int suma = 0;
    printf("Podaj wielkosc tablicy\n");
    scanf("%d",&n);
    int array[n];
    int array1[n];
    printf("Teraz podaj elementy tej tablicy\n");
    for(i=0; i<n; i++)
    {
        scanf("%d",&array[i]);
    }
    for(i=0; i<n; i++)
    {
        array[i] = array1[i];
    }
    for(i=0; i<n; i++)
    {
        for(j = 0; i < n ; i++)
        {
            if (array[i]==array1[j])
                
            }
    }
    
}
printf("Liczba %d wystepuje %d razy \n"); // tutaj trzeba zastosować pętle?

Dzieki za pomoc :)

1

Możesz stworzyć tablicę struktur:

typedef struct
{
	int number; // Jaka liczba
	int count; // Ile razy się pojawiła
} Number;
0

W 2 miesiące nauki do struktur nie doszliśmy :P
Na ten moment operowaliśmy jedynie pętlami i stawiam, że to właśnie pętlą mam zrobić, ale mogę się mylić.

Bo teoretycznie mógłby użyć to co napisałeś, ale w praktyce nie potrafie.

0

Znaczy nie wiem czy dobrze zrozumiałem zadanie, ale nie widzę sensu w tworzeniu dwóch identycznych tablic. Chyba powinno być coś w stylu, że tworzymy tablicę jakiś elementów, zaś w drugiej tablicy przechowywane są unikalne elementy, których liczbę wystąpień będzie zliczać z tablicy pierwszej.

0

Na przykładzie - tablica zawiera {1,5,2,3,1,5}
Liczba 1 - 2
Liczba 2 - 1
Liczba 3 - 1
Liczba 5 - 2

A stworzyłem te dwie tablice z myślą taką, że jeżeli przykładowo:
array[0] = 2;
To druga pętla będzie sprawdzać czy array[0] ==array1[0], array[0] ==array1[1], array[0] ==array1[2] aż do skończenia pętli.
Tylko nie wiem jak zapisać tę sumę jeżeli tablica napotka daną liczbę.

1

Napisałem coś takiego, ale algorytm raczej nie należy do najszybszych.

typedef struct
{
    int number;
    int count;
} Number;

int has_entry(Number numbers[], int size, int number)
{
    for(int i = 0; i < size; i++)
    {
        if(numbers[i].number == number)
        {
            numbers[i].count++; // Jeżeli liczbę znaleziono zwiększ licznik o 1
            return 1;
        }
    }

    return 0; // 0 oznacza że liczby nie znaleziono
}

int main()
{
    int size;
    printf("Podaj wielkosc tablicy\n");
    scanf("%d", &size);
    int numbers[size];

    printf("Teraz podaj elementy tej tablicy\n");
    for(int i = 0; i < size; i++)
    {
        scanf("%d", &numbers[i]);
    }

    // Inicjalizacja wszystkich pól na 0
    Number counter[size];
    for(int i = 0; i < size; i++)
    {
        counter[i].number = 0;
        counter[i].count = 0;
    }
    int counter_size = 0; // Ile miejsc zostało zapełnionych
    /* Dzięki temu nie musimy lecieć przez całą tablicę i sprawdzać 0 */

    for(int i = 0; i < size; i++)
    {
        if(!has_entry(counter, counter_size, numbers[i])) // Jeżeli nie znaleziono
        {
            counter[counter_size].number = numbers[i]; // Ustaw numer
            counter[counter_size].count = 1; // Ustaw ilość wystąpień na 1
            counter_size++; // Zwiększ ilość miejsc zapełnionych
        }
    }

    for(int i = 0; i < counter_size; i++) // Wyświetlanie tablicy wystąpień
    {
        printf("%d: %d\n", counter[i].number, counter[i].count);
    }
}
0

Połowy rzeczy nie miałem z tego :D Nigdy bym na to nie wpadł. Da się jakoś mniej skomplikowanie zrobić?
Szczerze powiedziawszy, myśłałem, że wystarczy kilka linijek do mojego kodu dopisać. Nie myślałem, że będzie to aż tak rozbudowane. ;p

1

Raczej wątpię że da się prościej. Dlaczego? Dlatego że:

  • Pobierasz liczbę z tablicy
  • Lecisz pętlą przez tablicę i dodajesz 1 do jakieś zmiennej za każdym wystąpieniem danej liczby

Ale potem jest problem, bo musisz pamiętać które liczby już liczyłeś a które jeszcze nie.

A podane rozwiązanie rozwiązuje ten problem za pomocą tablicy struktur Number.

0
atmal napisał(a):

Raczej wątpię że da się prościej. Dlaczego? Dlatego że:

  • Pobierasz liczbę z tablicy
  • Lecisz pętlą przez tablicę i dodajesz 1 do jakieś zmiennej za każdym wystąpieniem danej liczby

Ale potem jest problem, bo musisz pamiętać które liczby już liczyłeś a które jeszcze nie.

A podane rozwiązanie rozwiązuje ten problem za pomocą tablicy struktur Number.

W takim razie dziwny przeskok zrobił mój ćwiczeniowiec. Zadania przed tym to były typu: wprowadź do tablicy n liczb i oblicz ich sumę bądź średnią.
Poczytam o tych strukturach w takim razie. Dzięki ;)

1

Tutaj masz dosyć fajnie opisane struktury i nie tylko -> C/Typy złożone.

1

Jeśli znasz wielkość zestawu liczb w momencie uruchomienia programu, to możesz to zrobić mając jedną tablicę z liczbami i drugą przechowującą ilość wystąpień. I wtedy zwyczajnie inkrementujesz zawartość tablicy, gdzie (aktualna liczba) == (indeks tablicy).
Oczywiście jest to metoda tak chałupnicza, że aż paskudna i rozwiązanie ze strukturami jest znacznie bardziej eleganckie, ale przypuszczam, że właśnie takiego lub podobnego rozwiązania oczekuje prowadzący, skoro nie braliście jeszcze struktur, a ogarnięte macie pętle i tablice :)

0

Tak, myślałem o tym, ale to faktycznie musiałbym wiedzieć ile tych liczb jest. Jak jest ich 1000, to mamy troche problem :P
Ale dzięki za odpowiedź i tak :D

1

No w tym wypadku musiałbyś znać wymagania prowadzącego, które powinny być podane.
Jak wspominałem, jeśli tego nie przerabialiście, to strukturami możesz go trochę zdziwić, choć obwodów mu raczej nie przepalisz. Natomiast niemal na pewno wtedy zapyta "Panie, a dlaczemu tak żeś to Pan zrobił, jak można było tak..." :P

Ale myślę, że warto. Wyjdziesz trochę przed program, a to zaprocentuje później.

0

Uwaga - tylko dla ludzi o mocnych nerwach.

#include <iostream>
#define MAX_VALUE 1000 // @forum
using namespace std;

int main()
{
    int ArraySize;
    do {
        cout << "Podaj wielkosc tablicy: ";
        cin >> ArraySize;
    } while (ArraySize <= 0);
    int MainArray[ArraySize];
    cout << "Teraz podaj elementy tej tablicy: ";
    int LoopCounter = 0;
    while (LoopCounter < ArraySize) {
        cin >> MainArray[LoopCounter];
        LoopCounter++;
    }

    int ElementCounter[MAX_VALUE] = { 0 };
    for (int i = 0; i < ArraySize; i++)
        ElementCounter[MainArray[i]]++;

    for (int j = 0; j < MAX_VALUE; j++)
        if (ElementCounter[j] > 0)
            cout << "Liczba " << j << " pojawila sie " << ElementCounter[j] << " razy." << '\n';
}
#define MAX_VALUE 1000

Trzeba zdefiniować jaką maksymalną wartość może osiągnąć element tablicy. Tworzysz drugą tablicę o wielkości MAX_VALUE wypełnioną zerami (czyli zakładasz, że domyślnie każdy element jaki wpisujesz do tablicy wystąpił zero razy). Następnie jedziesz w pętli po kolei po każdym indeksie pierwszej tablicy, i jeżeli np. w pierwszej tablicy pod pierwszym indeksem jest liczba '5', to inkrementujesz piąty indeks drugiej tablicy.

Rozwiązanie niehigieniczne głównie dlatego, bo nie ma supportu dla wpisywanych do tablicy wartości ujemnych i dlatego, bo druga tablica jest 'niepotrzebnie' wypełniona zerami. O tej godzinie trochę ciężko mi to zoptymalizować. Generalnie nie polecam.

Jeśli potrzebujesz, to możesz łatwo to przepisać z C++ na C.
img

1

@Hodor: ten kod jest błędny.

do {
        cout << "Podaj wielkosc tablicy: ";
        cin >> ArraySize;
    } while (ArraySize <= 0);
    int MainArray[ArraySize];

Standard C++ mówi, że rozmiar tablicy niedynamicznej musi być stały i znany w czasie kompilacji.
VLA C++.
Użyj np. std::vector.

0

@YooSy

  1. Nawet gdyby tam nie było pętli do...while, to rozumiem, że tamten kod nadal byłby błędny?
do {
        cout << "Podaj wielkosc tablicy: ";
        cin >> ArraySize;
    } while (ArraySize <= 0);
    int * MainArray = new int[ArraySize];
...
delete [] MainArray;

2, Pomijając wątpliwość w używanie new i delete, czy taki kod jest bardziej poprawny? Nie miałem jeszcze styczności z dynamicznymi tablicami, ani z wektorami. Trzeba się zapoznać.

Dzięki.

0
  1. Byłby błędny. Rozmiar musi być constexpr.
  2. To jest OK.

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