Nauki ciąg dalszy... Tym razem zadaniem domowym była implementacja funkcji filtrującej kontener z danymi. Funkcja przyjmuje wskaźnik na kontener, jego rozmiar oraz wskaźnik na funkcję filtrującą. Funkcja zwraca wskaźnik na zaalokowaną pamięć z przefiltrowanymi danymi oraz ilość elementów tychże danych. W kodzie obecne są dwie wersje funkcji filtrującej, czyli iteracyjna i rekurencyjna. Nie jestem pewien, czy w bezpieczny sposób użyłem realloc, ale to już ocenią mądrzejsi ode mnie. Oto kod:
Kod: Zaznacz cały
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <malloc.h>
/* typedef funkcji wartościującej */
typedef bool (PredicateType)(const int src);
/* typedef rezultatu zwracanego przez filtr */
typedef struct
{
int * output;
size_t size;
}FilterOutputType;
/* Przykładowa funkcja wartościująca */
bool isGreaterThan200(int src)
{
return (src > 200);
}
/* Filtr - wersja iteracyjna */
FilterOutputType filter(const int *src, size_t size, PredicateType *predicate)
{
FilterOutputType out =
{
.output = NULL,
.size = 0
};
out.output = (int*) malloc(size * sizeof(src[0]));
if (out.output == NULL)
{
perror("Memory allocation error\n");
return out;
}
for (size_t i = 0; i < size; ++i)
{
if (predicate(src[i]) == false)
{
out.output[out.size++] = src[i];
}
}
if (out.size < size)
{
realloc(out.output, out.size * sizeof(src[0]));//moze jakas kontrola alokacji?
}
return out;
}
/* Funkcja pomocnicza dla filter_r */
void do_filter(const int *src, int *dst, size_t size, size_t *count, PredicateType *fun)
{
if (size > 0)
{
if (fun(*src) == false)
{
*dst = *src;
dst++;
*count = *count + 1;
}
do_filter(src + 1, dst, --size, count, fun);
}
}
/* Filtr - wersja rekurencyjna */
FilterOutputType filter_r(const int *src, size_t size, PredicateType *predicate)
{
FilterOutputType out =
{
.output = NULL,
.size = 0
};
out.output = (int*) malloc(size * sizeof(src[0]));
if (out.output == NULL)
{
perror("Memory allocation error\n");
return out;
}
/* czary mary, czyli wywołanie funkcji rekurencyjnej */
do_filter(src, out.output, size, &out.size, predicate);
if (out.size < size)
{
realloc(out.output, out.size * sizeof(src[0]));//moze jakas kontrola alokacji?
}
return out;
}
/* Pomocnicza funkcja do prezentacji danych */
void showData(const int *src, const size_t size)
{
printf("\n\tCalkowita ilosc elementow wynosi %d\n\n", size);
for (size_t i = 0; i < size; ++i)
{
printf("Wartosc elementu o indeksie %6d wynosi %6d\n", i, src[i]);
}
}
int main(void)
{
/* Jakieś tam dane... */
int samples[] = { 100, 200, 300, -1000, 23, 750, 13456, 0, -32767, 200, 13, 80 };
FilterOutputType result;
/* Prezentacja danych wejsciowych */
showData(samples, sizeof(samples) / sizeof(samples[0]));
/* filtr iteracyjny usunie wszystkie elementy o wartosci powyzej 200 */
result = filter(samples, sizeof(samples) / sizeof(samples[0]), isGreaterThan200);
/* Prezentacja danych wyjsciowych */
printf("\n\n\t Dane po przejsciu przez filtr iteracyjny:\n");
showData(result.output, result.size);
free(result.output);
/* filtr rekurencyjny usunie wszystkie elementy o wartosci powyzej 200 */
result = filter_r(samples, sizeof(samples) / sizeof(samples[0]), isGreaterThan200);
/* Ponowna prezentacja danych wyjsciowych */
printf("\n\n\t Dane po przejsciu przez filtr rekurencyjny:\n");
showData(result.output, result.size);
free(result.output);
int key = getchar();
return EXIT_SUCCESS;
}
Śmiało wytykać błędy
Pozdrawiam.