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? :/