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

Histogram (double pointer)

VPS Starter Arubacloud
0 głosów
475 wizyt
pytanie zadane 21 kwietnia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

Hej :)

Rozwiązuje takie oto zadanie:

Napisz funkcje wyznaczającą histogram liczb z tablicy przekazanej w parametrze oraz alokującą pamięć na tablicę typu int.

W tym celu przygotuj funkcje o następujących prototypach:

int *create_array_int(int N);
int histogram(const int *tab, int size, int **out, int *out_size, int *out_begin);
int *create_array_int(int N);
Funkcja alokuje pamięć na tablicę N liczb typu int i zwraca adres początkowy zaalokowanego obszaru pamięci. W przypadku podania błędnych danych wejściowych lub niepowodzenia alokacji pamięci funkcja zwraca NULL.

int histogram(const int *tab, int size, int **out, int *out_size, int *out_begin);
Funkcja wyznacza histogram występowania liczb całkowitych w tablicy tab o liczości size elementów. Szerokośc przedziału jest jednostkowa.

W wyniku działania funkcja tworzy histogram o liczbie elementów wynikającej z rozpiętości elementów przekazanych w tab - funkcja musi przydzielić pamięć, dokładnie tyle bajtów ile będzie zajmował histogram.

Wynik ma zostać zapisny pod wskaźniki out (histogram) oraz out_size (liczba przedziałów). Do zmiennej o adresie out_begin należy zapisać wartość pierwszego przedziału.

Parametry:

tab - wskaźnik na tablicę typu int, dla której elementów ma zostać wyznaczony histogram,
size - liczba elementów w tablicy,
out - wskaźnik na tablicę, do której ma zostać zapisany utworzony histogram,
out_size - wskaźnik na zmienną, do której ma zostać zapisana wielkość utworzonej tablicy,
out_begin - wskaźnik na zmienną, do której ma zostać zapisana dolna granica histogramu.
Wartość zwrócona:

1 - w przypadku podania błędnych danych,
2 - jeżeli nie uda się zaalokować pamięci,
0 - w przypadku sukcesu.
Przykład:

tab = { 1, -2, 3, 3, -3, -2 }; size = 6
out -> { 1, 2, 0, 0, 1, 0, 2 }
out_size -> 7
out_begin -> -3
Napisz program, który pobierze od użytkownika żądany rozmiar tablicy, a następnie wykorzystując przygotowaną funkcję zarezerwuje pamięć na tablicę i pobierze od użytkownika żądaną liczbę danych.

Następnie program powinien wyznaczyć dla niej i wyświetlić w postaci wartość - liczba wystąpień, zaczynając od przedziału o najmniejszej wartości.

W przypadku podania błędnych danych program powinien wyświetlić komunikat Incorrect input i zakończyć działanie z kodem błędu 1.
W przypadku podania danych niezgodnych z treścią zadania program powinien wyświetlić komunikat Incorrect input data i zakończyć działanie z kodem błęd 2.
Jeżeli nie uda się zarezerwować żądanego obszaru pamięci program powinien wyświetlić komunikat Failed to allocate memory i zakończyć działanie z kodem błędu 8.
Przykładowa interakcja z programem -- sukces:

Podaj rozmiar tablicy: 11⏎
Podaj liczby: 51 47 45 53 55 48 47 51 50 48 55 ⏎
45 - 1⏎
46 - 0⏎
47 - 2⏎
48 - 2⏎
49 - 0⏎
50 - 1⏎
51 - 2⏎
52 - 0⏎
53 - 1⏎
54 - 0⏎
55 - 2⏎
Przykładowa interakcja z programem -- brak pamięci: Limit sterty: 218 bajtów

Podaj rozmiar tablicy: 64⏎
Failed to allocate memory⏎
Limit starty: 305 bajtów

Podaj rozmiar tablicy: 64⏎
Podaj liczby: -6 -7 5 -1 3 -2 -9 0 -2 -9 4 10 -1 -7 6 4 -8 -6 7 0 10 8 10 8 10 -8 7 -10 9 5 1 -3 -9 -3 -5 0 2 7 9 -10 3 4 4 1 -6 7 3 -7 -2 3 10 5 1 -2 -8 5 -2 2 3 -1 -2 -3 -3 7 ⏎
Failed to allocate memory⏎
Przykładowa interakcja z programem -- błąd danych wejściowych:

Podaj rozmiar tablicy: -9⏎
Incorrect input data
Podaj rozmiar tablicy: 19⏎
Podaj liczby: zPumyk⏎
Incorrect input
Podaj rozmiar tablicy: 10⏎
Podaj liczby: -8.238777 74.637532 89.300853 -80.563206 -44.862358 -63.312259 84.332735 JywidzCS⏎
Incorrect input
Uwaga

W programie nie wolno korzystać z operatora []!

Przechodząc do mojego kodu:

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

int *create_array_int(int N);
int histogram(const int *tab, int size, int **out, int *out_size, int *out_begin);

int main()
{
    printf("Podaj rozmiar tablicy: ");
    int N;
    if(scanf("%d",&N)!=1)
    {
        printf("Incorrect input");
        return 1;
    }
    if( N <= 0)
    {
        printf("Incorrect input data");
        return 2;
    }
    int * pointer_on_table=create_array_int(N);
    if( N == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }
    int i;
    printf("Podaj liczby: ");
    for(i = 0; i < N; i++)
    {
        if(scanf("%d",(pointer_on_table + i))!=1)
        {
            printf("Incorrect input");
            return 1;
        }
    }
    int * first_pointer_on_hist;
    int ** second_on_histogram=&first_pointer_on_hist;
    int result;
    int na_poczatek = 0;;
    int na_rozmiar = 0;
    result = histogram(pointer_on_table,N,second_on_histogram,&na_rozmiar,&na_poczatek);
    for(i = na_poczatek; i <= (na_poczatek + na_rozmiar - 1);i++)
    {
        printf("%d - %d\n",i,*(first_pointer_on_hist + i) );
    }
    return 0;
}

int *create_array_int(int N)
{
    if( N <= 0 )
    {
        return NULL;
    }
    int * ps;
    ps = (int *) malloc( N * sizeof(int));
    return ps;
}

int histogram(const int *tab, int size, int **out, int *out_size, int *out_begin)
{
    if( tab == NULL || size <= 0 || out == NULL || out_size == NULL || out_begin == NULL )
    {
        return 1;
    }
    int min = *(tab + 0);
    int maks = *(tab + 0);
    int i = 0;
    for(i = 0; i < size; i++)
    {
        if( *(tab + i) < min )
        {
            min = *(tab + i);
        }
         if( *(tab + i) > maks  )
        {
            maks = *(tab + i);
        }
    }
    int s = 0;
    for(i = min; i<= maks; i++)
    {
        s++;
    }
    *out_size = s;
    *out_begin = min;
    *out = (int *) malloc(s * sizeof(int));
    if( *out == NULL )
    {
        return 2;
    }
    int j;
    int ile_od_min = 0;
    int * ps = *out;
    for( i = 0; i < *out_size; i++)
    {
        *(ps + i) = 0;
    }
    for(i = 0; i < size;i++)
    {
        for(j = min; j < *(tab + i); j++)
        {
            ile_od_min++;
        }
        *(ps + ile_od_min) = *(ps + ile_od_min) + 1;
    }

    return 0;
}

W mojej funkcji histogram poszukuje minimalną i maksymalną wartość tablicy tab. Dzięki temu znam rozmiar mojego histogramu i jego dolną granicę (a także de facto i górną). Po zalokowaniu pamięci za pomocą double pointer-a out zeruje wartości dla każdej komórki tablicy.

 for(i = 0; i < size;i++)
    {
        for(j = min; j < *(tab + i); j++)
        {
            ile_od_min++;
        }
        *(ps + ile_od_min) = *(ps + ile_od_min) + 1;
    }

Tutaj de facto sprawdzam, gdzie dla danego elementu w histogramie powinienem zwiększyć o 1 wartość wystąpienia dla danej liczby z tab.

I problem jest taki, że po odpaleniu konsoli o ile prawidłowo wyświetla po kolei liczby od dolnej granicy do górnej to nie ma ilości wystąpień, a są... adresy. Coś poknociłem na operacjach na double pointerze. Wiecie może o co chodzi?  :/

1
komentarz 21 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
    int s = 0;
    for(i = min; i<= maks; i++)
    {
        s++;
    }

Wtf? Nie wystarczy zwykłe s = (maks - min) + 1?

komentarz 21 kwietnia 2020 przez Hubertius Bywalec (2,970 p.)
@j23 Tak, chyba sobie za bardzo w tym miejscu skomplikowałem życie. Rzeczywiście, tak też mogłem zrobić. :P
1
komentarz 21 kwietnia 2020 przez j23 Mędrzec (194,920 p.)

To jeszcze to popraw:

        for (j = min; j < *(tab + i); j++) {
            ile_od_min++;
        }

 

1 odpowiedź

0 głosów
odpowiedź 21 kwietnia 2020 przez j23 Mędrzec (194,920 p.)
wybrane 21 kwietnia 2020 przez Hubertius
 
Najlepsza
int* histogram_ptr;

result = histogram(pointer_on_table, N, &histogram_ptr, &na_rozmiar, &na_poczatek);

for (i = 0; i < na_rozmiar; ++i) {
    printf("%d - %d\n", na_poczatek + i, *(histogram_ptr + i));
}

 

Podobne pytania

0 głosów
0 odpowiedzi 238 wizyt
0 głosów
2 odpowiedzi 454 wizyt
0 głosów
1 odpowiedź 124 wizyt
pytanie zadane 21 maja 2020 w C i C++ przez Marcin4 Użytkownik (570 p.)

92,453 zapytań

141,262 odpowiedzi

319,087 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...