PP – Laboratorium 11

Wejściówka

Napisz program w języku C++, który za pomocą wskaźnika do funkcji wywoła funkcję f. Funkcja f powinna przyjmować dwa argumenty typu całkowitego oraz zwracać wynik operacji sqrt(a * b / 3).

Rozwiązanie:
#include <cmath>

float f(int a, int b) {
	return sqrt(a * b / 3.f);
}

int main() {
    float (*fun)(int, int);
    fun = f;
	fun(10, 10);
    return 0;
}

Zadanie 1

Napisz program w języku C++, który zmienia kolejność elementów w posortowanej tablicy liczb całkowitych, w następujący sposób:
– pierwszym elementem powinna być maksymalna wartość,
– drugim elementem powinna być minimalna wartość,
– trzecim elementem powinna być druga maksymalna wartość,
– czwartym elementem powinna być druga minimalna wartość,
i tak dalej.

Rozwiązanie:
#include <iostream>

void rearrange_max_min(int *nums, int n) {
    int *temp = new int[n];
    int min_num = 0, max_num = n - 1;
    int result = true;

    for (int i = 0; i < n; ++i) {
        if (result) temp[i] = nums[max_num--];
        else temp[i] = nums[min_num++];
        result = !result;
    }
    for (int i = 0; i < n; ++i) nums[i] = temp[i];

    delete[] temp;
}

void print_arr(int *arr, int n) {
    for(int i = 0; i < n; ++i) 
        std::cout << arr[i] << " "; 
    std::cout << "\n";
}

int main() {
    int nums[] = {0, 1, 3, 4, 5, 6, 7, 8, 10};
    int n = sizeof(nums) / sizeof(nums[0]);
    rearrange_max_min(nums, n);
    print_arr(nums, n);
    return 0;
}

Zadanie 2

Napisz funkcję w języku C++, która przyjmuje następujące argumenty: wskaźnik na tablicę liczb całkowitych – arr, liczbę całkowitą będącą rozmiarem tej tablicy – n, liczbę całkowitą – k oraz wskaźnik na tablicę liczb całkowitych – result. Funkcja powinna wprowadzić do tablicy result k największych elementów z nieposortowanej tablicy arr przekazanej w argumencie. Funkcja nie powinna modyfikować oryginalnej tablicy. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <algorithm>
#include <iostream>
#include <cstring>

bool compare(int a, int b) {
    return a > b;
}

void top_k_elements(int *arr, int n, int k, int *result) {
    int *cpy = new int[n];

    memcpy(cpy, arr, n * sizeof(int));
    std::sort(cpy, cpy + n, compare);
    memcpy(result, cpy, k * sizeof(*cpy));

    delete[] cpy;
}

void print_arr(int *arr, int n) {
    for(int i = 0; i < n; ++i) 
        std::cout << arr[i] << " "; 
    std::cout << "\n";
}

int main() {
    int nums[] = {4, 5, 9, 12, 9, 22, 45, 7};
    int n = sizeof(nums) / sizeof(nums[0]), k = 3;
    int *result = new int[k];

    top_k_elements(nums, n, k, result);
    print_arr(result, k);

    delete[] result;
    return 0;
}

Zadanie 3

Napisz program w języku C++, który wczyta od użytkownika liczbę, jako napis. Liczba powinna mieć co najwyżej 10 znaków. Następnie program powinien zwiększyć tą liczbę o 0.123 i ją wyświetlić.

Rozwiązanie:
#include <iostream>
#include <cstdlib>

int main() {
    char dig[11] = {0};
    std::cin >> dig;
    char *p;
    float f = strtod(dig, &p);
    if(p > dig) 
        std::cout << f + 0.123f << "\n";
    else 
        std::cout << " Konwersja się nie udała.\n";
    return 0;
}

Zadanie 4

Napisz funkcję w języku C++, która znajduje element pojawiający się w tablicy tylko raz, gdy inne elementy pojawiają się dwukrotnie. Funkcja w argumencie powinna przyjąć wskaźnik na tablicę liczb całkowitych oraz rozmiar tej tablicy. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <iostream>

int search_single_element(int *arr, int n) {
    int result = arr[0];
    for (int i = 1; i < n; ++i) 
        result ^= arr[i];
    return result;
}


int main() {
    int array[] = {3, 1, 5, 1, 5, 7, 9, 7, 9};
    int n = sizeof(array) / sizeof(array[0]);
    std::cout << search_single_element(array, n) << std::endl;
    return 0;
}

Zadanie 5

Wykorzystując wskaźniki na funkcje napisz program w języku C++, który w zależności od wywołania funkcji f wykona dodawanie lub odejmowanie dwóch macierzy kwadratowych. Spróbuj użyć wskaźników na funkcję tak, aby powtórzyć jak najmniej kodu w zaproponowanej implementacji (zasada DRY). Dodatkowo funkcja f powinna wyświetlić wynik wybranej operacji. Wynik operacji na macierzach powinien być zapisany do pierwszej tablicy. Operacje na tablicach powinny być przeprowadzone za pomocą arytmetyki wskaźników.

Rozwiązanie:
#include <iostream>

typedef int (*p_fun)(int, int);

int add(int a, int b) {
    return a + b;
}

int sub(int a, int b) {
    return a - b;
}

void print_matrix(int *matrix, int n, int m) {
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j)
            std::cout << *(matrix + i * m + j) << " ";
        std::cout << "\n";
    }
}

void f(int *a, int *b, int n, p_fun fun) {
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
            *(a + i * n + j) = fun(*(a + i * n + j), *(b + i * n + j));
    print_matrix(a, n, n);
}

int main() {
    int arr1[]={1, 2, 3, 5, 15, 0, 12, 13, 5};
    int arr2[]={1, 2, 3, 5, 15, 0, 12, 13, 5};
    f(arr1, arr2, 3, add);
    f(arr1, arr2, 3, sub);
    f(arr1, arr2, 3, sub);
    return 0;
}

Zadanie 6

Zdefiniuj funkcję f w języku C++, która w argumencie przyjmuje nieujemną liczbę całkowitą n, tablicę liczb całkowitych arr oraz wskaźnik na liczbę zmiennoprzecinkową result. Funkcja powinna zwrócić, za pomocą argumentu result, wynik następującej sumy:
f(n) = Σ(0<=a<=n) (x*(x-a))
gdzie dla arr[a] podzielnego przez 5 x = a3 lub x = sqrt(a) w przeciwnym razie. Napisz program, który sprawdzi działanie tej funkcji. Program powinien wczytać ze standardowego wejścia nieujemną liczbę całkowitą n, zaalokować pamięć, wypełnić ją losowymi wartościami z przedziału <0;15> i wyświetlić na standardowym wyjściu wynik funkcji f.

Rozwiązanie:
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>

const int MIN = 0;
const int MAX = 15;

void fill_arr(int *arr, int n) {
    for(int i = 0; i < n; ++i) 
        arr[i] = MIN + rand() / (RAND_MAX / (MAX - MIN + 1));
}

void f(unsigned int n, int *arr, float *result) {
    *result = 0.f;
    for(unsigned int a = 0; a <= n; ++a) 
        *result += !(arr[a] % 5) ? pow(a, 3) : sqrt(a);
}

int main() {
    srand(time(0));
    unsigned int n;
    std::cin >> n;
    float r = 0.f;
    int *arr = new int[n];
    fill_arr(arr, n);
    f(n, arr, &r);
    std::cout << r << std::endl;
    delete[] arr;
    return 0;
}

Zadanie 7

Zaprojektuj i zdefiniuj funkcję transpose w języku C++, która w parametrze przyjmie macierz liczb zmiennoprzecinkowych o wielkości n x n. Zadaniem tej funkcji będzie wykonanie transpozycji tej macierzy. Forma reprezentacji macierzy oraz sposób jej przekazania do funkcji i zwrócenia wartości do samodzielnego określenia. W funkcji głównej pokaż użycie tej funkcji. Macierz transponowana macierzy A to macierz AT, która powstaje poprzez zamianę jej wierszy na kolumny i kolumn na wiersze. Napisz program w języku C++, który przetestuje działanie tej funkcji, dynamicznie zaalokuje pamięć dla dwuwymiarowej macierzy i wypełni ją dowolnymi wartościami.

Rozwiązanie:
#include <iostream>

void fill_matrix(float **arr, int n, int m) {
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j) 
            arr[i][j] = i * m + j;
}

void print_matrix(float **arr, int n, int m) {
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) 
            std::cout << arr[i][j] << " "; 
        std::cout << "\n";
    }
}

void transpose(float **mat, int n, int m) {
    for(int i = 0; i < n; ++i)
        for(int j = i + 1; j < m; ++j)
            std::swap(mat[i][j], mat[j][i]);
}

int main() {
    int n = 4;
    float **arr = new float*[n];
    for(int i = 0; i < n; ++i) 
        arr[i] = new float[n];
    
    fill_matrix(arr, n, n);
    print_matrix(arr, n, n);
    transpose(arr, n, n);
    print_matrix(arr, n, n);
    
	for(int i = 0; i < n; ++i) 
	    delete[] arr[i]; 
	delete[] arr;
    return 0;
}

Zadanie 8

Napisz funkcję w języku C++, która przyjmuje wskaźnik na void oraz liczbę całkowitą ptrsize. ptrsize jest liczbą bajtów, która reprezentuje zmienną. Funkcja powinna odpowiednio zrzutować zmienną na typ char lub int, a następnie zwiększyć jej wartość o jeden. Napisz program w języku C++, który sprawdzi działanie tej funkcji dla obu tych typów.

Rozwiązanie:
#include <iostream>

void increase(void *data, int ptrsize) {
    if(ptrsize == sizeof(char)) {
        char *ptrchar;
        ptrchar = (char*)data;
        (*ptrchar)++;
    } else if(ptrsize == sizeof(int)) {
        int *ptrint;
        ptrint = (int*)data;
        (*ptrint)++;
    }
}

int main()  {
    char c = 'x';
    int i = 10;
    increase(&c, sizeof(c));
    std::cout << c <<"\n";
    increase(&i, sizeof(i));
    std::cout << i <<"\n";
    return 0;
}

Zadanie 9

Napisz funkcję w języku C++, który znajdzie najmniejszy i drugi najmniejszy element w dowolnej tablicy liczb całkowitych. Wartość najmniejszego i drugiego najmniejszego elementu powinny zostać zwrócone za pomocą argumentów funkcji. Do operowania na tablicy użyj arytmetyki wskaźników. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <iostream>

void find(int *array, int n, int &s, int &ss) {
    if(*array < *(array + 1)) {
        s = *array;
        ss = *(array + 1);
    } else {
        s = *(array + 1);
        ss = *array;
    }

    for(int i = 0; i < n; ++i) {
        if (s > *(array + i)) {
            ss = s;
            s = *(array + i);
        } else if (*(array + i) < ss) {
            ss = *(array + i);
        }
    }
}

int main() {
    int s, ss, array[7] = {5, 6, 7, 2, 3, 4, 12};
    find(array, 7, s, ss);
    std::cout << s << " " << ss << "\n";
    return 0;
}

Zadanie 10

Napisz program w języku C++, który zaalokuje pamięć dla dwóch 10-elementowych tablic liczb całkowitych: a i b. Następnie program powinien wczytać od użytkownika wartość całkowitą x i wypełnić nią tablicę a, zaś tablica b powinna być uzupełniona wartością x, powiększoną o 2. Na koniec program powinien wyświetlić obie tablice, zaimplementowane rozwiązanie nie powinno używać pętli.

Rozwiązanie:
#include <iostream>
#include <algorithm>

void print_elem(int i) {
    std::cout << i << " ";
}

int op_increase(int i) {
    return i + 2;
}

int main() {
    int x, *a = new int[10], *b = new int[10];
    std::cin >> x;
    std::fill(a, a + 10, x);
    std::transform(a, a + 10, b, op_increase);
    // lub fill(b, b + 10, x + 2);
    std::for_each(a, a + 10, print_elem); 
    std::cout << "\n";
    std::for_each(b, b + 10, print_elem); 
    std::cout << "\n";
    return 0;
}

Zadanie 11

Zaprojektuj funkcję w języku C++, która dla wprowadzonej tablicy liczb rzeczywistych znajdzie podaną w argumencie wartość. Funkcja powinna zwrócić do niej wskaźnik, lub wskaźnik na NULL, jeśli nie znajdzie jej w tablicy. Zaimplementowane rozwiązanie nie powinno wykorzystywać pętli.

Rozwiązanie:
#include <algorithm>

float *f(float *arr, int n, float x) {
	float *p = std::find(arr, arr + n, x);
	if(p != arr + n) return p;
	else return nullptr;
}

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *