Kurs podstawy programowania UMCS, zdjęcie laptopa.

PP – Laboratorium 9

Wejściówka

Napisz program w języku C++, który stworzy 10-cio elementową tablicę liczb całkowitych i wypełni ją dowolnymi wartościami. Użyj dynamicznej alokacji pamięci.

Rozwiązanie:
int main() {
    int *arr = new int[10];
    for(int i = 0; i < 10; ++i) arr[i] = i;
    delete[] arr;
    return 0;
}

Zadanie 1

Napisz funkcję w języku C++, która przyjmie jako argumenty dwa napisy – przeszukiwany i poszukiwany. Jeżeli w napisie przeszukiwanym znajduje się napis będący zgodny z napisem poszukiwanym, funkcja powinna zwrócić wskaźnik na indeks pierwszego znaku odnalezionego pod-napisu. W przeciwnym razie funkcja powinna zwrócić nullptr. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <iostream>

char *search(char str[], char str1[]) {
    bool found;
    for(int i = 0; str[i]; ++i) {
        found = true;
        for(int j = 0; str1[j] && str[i + j]; ++j)
            if(str[i + j] != str1[j]) {
                found = false;
                break;
            }
        if(found) return str + i;
    } return nullptr;
}

int main() {
    char str[] = "Ala ma kota.", str1[] = "kota";
    char *found = search(str, str1);

    if(found) 
        std::cout << found << " , index:" << found - str << std::endl;
    else 
        std::cout << "not found\n";

    return 0;
}

Zadanie 2

Napisz program w języku C++, który wczyta od użytkownika wymiary prostokątnego pola bitwy NxM, a następnie dla każdego pola dwie wartości całkowite A oraz D. Na każdym polu znajduje się działo: A definiuje jego moc ataku, zaś D jego obronę. Działa strzelają do siebie nawzajem, jeśli działo atakujące ma większą wartość ataku niż wartość defensywy przeciwnika, to wygrywa walkę i niszczy działo atakowane. W przeciwnym wypadku wygrywa działo broniące się, niszcząc działo atakujące. Program po wczytaniu pola bitwy powinien wczytać wartość nieujemnej zmiennej całkowitej C, a następnie C sekwencji danych: ax, ay, dx, dy, gdzie ax, ay to współrzędne działa atakującego, zaś dx, dy działa broniącego się, po każdej operacji z pola bitwy powinno zniknąć jedno działo. Na koniec program powinien wyświetlić stan pola bitwy w formie:
0 X 0 0 0
0 0 0 X 0
X X 0 0 0

,gdzie X – oznacza działo zniszczone, a O – działo, które pozostało na polu bitwy. Użyj dynamicznej alokacji pamięci, rozwiązanie powinno być rozwiązaniem optymalnym. (Optymalne: pole bitwy powinno być spójnym obszarem pamięci.)
Przykład:
5 3
1 5 2 6 9 2
1 5 7 1 2 2
5 3 2 8 9 5
6 6 8 2 4 1
3 6 4 2 8 3
3
0 0 4 2
4 2 0 2
1 1 2 1

Rozwiązanie:
//Version 1.0
#include <cstdio>
typedef unsigned int uint;

void print_arr(int ***arr, uint n, uint m) {
    for(uint i = 0; i < n; ++i) {
        for(uint j = 0; j < m; ++j)
            printf("%c ", arr[i][j][0] == -1 && arr[i][j][1] == -1 ? 'X' : 'O');
        printf("\n");
    }
}

void f(int ***arr, uint ax, uint ay, uint dx, uint dy) {
    if(arr[ax][ay][0] > arr[dx][dy][1]) arr[dx][dy][0] = arr[dx][dy][1] = -1;
    else arr[ax][ay][0] = arr[ax][ay][1] = -1;
}

int main() {
    uint n, m, c, ax, ay, dx, dy;
    scanf("%u%u", &n, &m);

    int ***battlefield = new int**[n];
    for(uint i = 0; i < n; ++i) {
        battlefield[i] = new int*[m];
        for(uint j = 0; j < m; ++j)
            battlefield[i][j] = new int[2](); //() - inicjalizacja zerami
    }
    print_arr(battlefield, n, m);

    for(uint i = 0; i < n; ++i)
        for(uint j = 0; j < m; ++j)
            scanf("%d%d", &battlefield[i][j][0], &battlefield[i][j][1]);

    scanf("%u", &c);
    for(uint i = 0; i < c; ++i) {
        scanf("%u%u%u%u", &ax, &ay, &dx, &dy);
        f(battlefield, ax, ay, dx, dy);
    }

    print_arr(battlefield, n, m);
    for(uint i = 0; i < n; ++i) {
        for(uint j = 0; j < m; ++j)
            delete[] battlefield[i][j];
        delete[] battlefield[i];
    } delete[] battlefield;

    return 0;
}
//Version 2.0
#include <cstdio>
typedef unsigned int uint;

void print_arr(int *arr, uint n, uint m) {
    for(uint i = 0; i < n; ++i) {
        for(uint j = 0; j < m; ++j)
            printf("%c ", arr[i * m * 2 + j * 2 + 0] == -1 && arr[i * m * 2 + j * 2 + 1] == -1 ? 'X' : 'O');
        printf("\n");
    }
}

void f(int *arr, uint ax, uint ay, uint dx, uint dy, uint n, uint m) {
    if(arr[ax * m * 2 + ay * 2 + 0] > arr[dx * m * 2 + dy * 2 + 1]) 
        arr[dx * m * 2 + dy * 2 + 0] = arr[dx * m * 2 + dy * 2 + 1] = -1;
    else 
        arr[ax * m * 2 + ay * 2 + 0] = arr[ax * m * 2 + ay * 2 + 1] = -1;
}

int main() {
    uint n, m, c, ax, ay, dx, dy;
    scanf("%u%u", &n, &m);

    int *battlefield = new int[n * m * 2];

    for(uint i = 0; i < n; ++i)
        for(uint j = 0; j < m; ++j)
            scanf("%d%d", &battlefield[i * m * 2 + j * 2 + 0], &battlefield[i * m * 2 + j * 2 + 1]);

    scanf("%u", &c);
    for(uint i = 0; i < c; ++i) {
        scanf("%u%u%u%u", &ax, &ay, &dx, &dy);
        f(battlefield, ax, ay, dx, dy, n, m);
    }
    print_arr(battlefield, n, m);

    delete[] battlefield;
    return 0;
}

Zadanie 3

Napisz program w języku C++, który zaalokuje 32 bajtową tablicę, wprowadzi do niej wartości całkowite, a następnie wyświetli elementy tej tablicy jako zmienne typu int.

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

int main() {
    char *arr = new char[32];
    int size = 32 / sizeof(int);

    for(int i = 0; i < size; ++i)
        *((int *)arr + i) = INT_MAX - i;

    for(int i = 0; i < size; ++i)
        std::cout << *((int *)arr + i) << " ";
    std::cout << std::endl;

    for(int i = 0; i < 32; ++i)
        std::cout << (int)arr[i] << " ";
    std::cout << std::endl;

    delete[] arr;
    return 0;
}

Zadanie 4

Napisz funkcję w języku C++, która przyjmuje jednowymiarową tablicę liczb zmiennoprzecinkowych. Funkcja powinna zwracać wyznacznik macierzy dla tej tablicy, intepretowanej jako macierzy 3x3. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <iostream>

float det(float *matrix) {
	return matrix[0] * matrix[4] * matrix[8] +  
	       matrix[1] * matrix[5] * matrix[6] +  
	       matrix[2] * matrix[3] * matrix[7] - 
	      (matrix[2] * matrix[4] * matrix[6] +  
	       matrix[0] * matrix[5] * matrix[7] +  
	       matrix[1] * matrix[3] * matrix[8]);
	/*		 
	return matrix[0*3 + 0] * matrix[1*3 + 1] * matrix[2*3 + 2] + 
	       matrix[0*3 + 1] * matrix[1*3 + 2] * matrix[2*3 + 0] +  
	       matrix[0*3 + 2] * matrix[1*3 + 0] * matrix[2*3 + 1] - 
	      (matrix[0*3 + 2] * matrix[1*3 + 1] * matrix[2*3 + 0] +  
	       matrix[0*3 + 0] * matrix[1*3 + 2] * matrix[2*3 + 1] +  
	       matrix[0*3 + 1] * matrix[1*3 + 0] * matrix[2*3 + 2]);
	*/
}

int main() {
	float arr[] = {5, 4, -7, 1, 3, -1, 2, 0, -3};
	std::cout << det(arr) << std::endl;
	return 0;
}

Zadanie 5

Napisz funkcję w języku C++, która przyjmuje jednowymiarową tablicę liczb zmiennoprzecinkowych – matrix, liczbę całkowitą – n, liczbę całkowitą – m i liczbę zmiennoprzecinkową – s. Funkcja powinna zapisać do matrix wynik mnożenia macierzy – matrix, o wymiarach n na m, przez skalar s. Napisz program w języku C++, który przetestuje działanie tej funkcji.

Rozwiązanie:
#include <iostream>

void product_with_scalar(float *matrix, int n, int m, float s) {
    for(int i = 0; i < n * m; ++i) matrix[i] *= s;
}

void print_arr(float *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";
    }
}

int main() {
    float arr[] = {5, 4, -7, 1, 3, -1, 2, 0, -3};
    product_with_scalar(arr, 3, 3, 2.4f);
    print_arr(arr, 3, 3);
    return 0;
}

Zadanie 6

Napisz funkcje w języku C++, które obliczają: a) sumę wektorów, b) różnicę wektorów, c) iloczyn wektora przez skalar, d) iloczyn skalarny wektorów, e) iloczyn wektorowy wektorów w trójwymiarowej przestrzeni euklidesowej. Napisz program w języku C++, który przetestuje działanie tych funkcji.

Rozwiązanie:
#include <iostream>

float *add(float *v1, float *v2) {
    int n = 3;
    for(int i = 0; i < n; ++i) v1[i] += v2[i];
    return v1;
}

float *sub(float *v1, float *v2) {
    int n = 3;
    for(int i = 0; i < n; ++i) v1[i] -= v2[i];
    return v1;
}

float *mul(float *v1, float s) {
    int n = 3;
    for(int i = 0; i < n; ++i) v1[i] *= s;
    return v1;
}

float dot(float *v1, float *v2) {
    int n = 3;
    float temp = 0.f;
    for(int i = 0; i < n; ++i) temp += v1[i] * v2[i];
    return temp;
}

float *cross(float *v1, float *v2) {
    int n = 3;
    float *temp = new float[n];
    temp[0] = v1[1] * v2[2] - v1[2] * v2[1];
    temp[1] = v1[2] * v2[0] - v1[0] * v2[2];
    temp[2] = v1[0] * v2[1] - v1[1] * v2[0];
    for(int i = 0; i < n; ++i) v1[i] = temp[i];
    delete[] temp;
    return v1;
}

void print_vector(float *v) {
    std::cout << v[0] << " " << v[1] << " " << v[2] << std::endl;
}

int main() {
    float s = 3.f, v[3] = {1.1f, 2.2f, 3.3f}, u[3] = {1.f, 2.f, 1.f};
    print_vector(add(v, u));
    print_vector(sub(v, u));
    print_vector(mul(v, s));
    std::cout << dot(v, u) << std::endl;
    print_vector(cross(v, u));
    return 0;
}

Zadanie 7

Napisz funkcję mul w języku C++, która mnoży dwie macierze oraz funkcję print_matrix, która wyświetla macierz. Napisz program w języku C++, który przetestuje działanie tych funkcji.

Rozwiązanie:
#include <iostream>

void mul(float *m1, int r1, int c1, float *m2, int r2, int c2, float *result) {
    for(int i = 0; i < r1; ++i)
        for(int j = 0; j < c2; ++j)
            for(int k = 0; k < c1; ++k)
                result[i * c2 + j] += m1[i * c1 + k] * m2[k * c2 + j];
}

void print_matrix(float *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";
    }
}

int main() {
    float A[] = {1,3,5,7, 2,4,6,8}; //2x4
    float B[] = {1,8,9, 2,7,10, 3,6,11, 4,5,12}; //4x3
    float R[2 * 3]; //2x3
    mul(A, 2, 4, B, 4, 3, R);
    print_matrix(R, 2, 3);
    return 0;
}

Zadanie 8

Napisz program w języku C++, który stworzy tablicę dowolnych liczb całkowitych. Następnie program powinien przekopiować dane z tej tablicy do tablicy tymczasowej temp, przesunąć wszystkie elementy o 2 w lewo (Dwa pierwsze elementy powinny pojawić się na końcu tablicy). (memcpy, memmove)

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

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

int main() {
    const int n = 5;
    int a[n] = {0, 0 ,0 ,0 ,0}, b[n] = {1, 2, 3, 4, 5};

    print_arr(a, n);
    print_arr(b, n);
    memcpy(a, b, n * sizeof(int)); //memcpy(a, b, sizeof b);
    print_arr(a, n);
    print_arr(b, n);
    int tmp1 = a[0], tmp2 = a[1];
    memmove(a, a + 2, (n - 2) * sizeof(int));
    a[n - 2] = tmp1; a[n - 1] = tmp2;
    print_arr(a, n);
    print_arr(b, n);

    return 0;
}
Omówienie:
char a[16];
char b[16];

memcpy(a,b,16);           // poprawne
memmove(a,b,16);          // poprawne ale wolniejsze niż memcpy
memcpy(&a[0], &a[1],10);  // niepoprawne, bo zachodzi na siebie
memmove(&a[0], &a[1],10); // poprawne 

Zadanie 9

Napisz program w języku C++, który zaalokuje dynamicznie tablicę wskaźników na liczby całkowite o rozmiarze n. Program do każdej komórki tej tablicy powinien przypisać wskaźnik do dynamicznie zaalokowanej tablicy liczb całkowitych o rozmiarze m. Następnie program powinien wypełnić tablicę danymi indeksując ją tak, jakby była dwuwymiarową tablicą liczb całkowitych. Na koniec należy zwrócić uwagę na odpowiednie zwalnianie pamięci zajmowanej przez te tablice.

Rozwiązanie:
int main() {
    int n = 5, m = 10;
    int **arr_2d = new int*[n];
    for(int i = 0; i < n; ++i)
        arr_2d[i] = new int[m];
        
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
            arr_2d[i][j] = i * m + j;
            
    for(int i = 0; i < n; ++i)
        delete[] arr_2d[i];
    delete[] arr_2d;
    return 0;
}

Zadanie 10

W analogiczny sposób jak w poprzednim zadaniu utwórz tablicę reprezentującą macierz górnotrójkątną. Liczba n powinna odpowiadać liczbie wierszy, a w przypadku pierwszego wiersza, także kolumn. Każdy kolejny wiersz powinien mieć o jeden element mniej niż poprzedni. Napisz dwie funkcje w języku C++, które przyjmą jako parametr wskaźnik na tę tablicę oraz rozmiar n. Jedna z funkcji powinna zapisać w tablicy niepowtarzającą się część tabliczki mnożenia. Druga funkcja powinna wyświetlić tabliczkę mnożenia z tablicy, tworząc jednak pełny kwadrat. Do indeksowania tablic używaj operacji dereferencji i arytmetyki wskaźników. Pamiętaj o zwolnieniu pamięci zajmowanej przez tablice.

Rozwiązanie:
#include <iostream>

void fill_matrix(int **arr_2d, int n) {
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n - i; ++j)
            *(*(arr_2d + i) + j) = (i + 1) * (j + 1);
}

void print_matrix(int **arr_2d, int n) {
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n - i; ++j)
            std::cout << *(*(arr_2d + i) + j) << " ";
        for(int j = 0; j < i; ++j)
            std::cout << "0 ";
        std::cout << std::endl;
    }
}

int main() {
    int n = 5, m = 10;
    int **arr_2d = new int*[n];
    for(int i = 0; i < n; ++i)
        *(arr_2d + i) = new int[n - i];
        
    fill_matrix(arr_2d, n);
    print_matrix(arr_2d, n);
            
    for(int i = 0; i < n; ++i)
        delete[] arr_2d[i];
    delete[] arr_2d;
    return 0;
}

Zadanie 11

Napisz funkcję w języku C++, która przyjmie tablicę napisów (wskaźników na znaki), z których część ma wartość nullptr. Jeżeli taka wartość się pojawi, funkcja powinna: (1) dynamicznie utworzyć napis, (2) przepisać tam napis z poprzedniego wiersza pomijając co drugi znak, (3) przypisać powstały napis do komórki tablicy wskaźników. Rozmiar utworzonego napisu powinien być optymalny. Zakładamy, że pierwsza komórka tablicy nie zawiera nullptr.

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

int str_len(char *str) {
    int result = 0;
    for(;str[result];++result);
    return result;
}

void parse_arr(char *arr[], int n) {
    int tmp_size = 0;
    for(int i = 0; i < n; ++i) {
        if(not arr[i]) {
            tmp_size = std::ceil(str_len(arr[i - 1]) / 2.f) + 1;
            arr[i] = new char[tmp_size]();
            for(int j = 0; arr[i - 1][j]; j += 2)
                arr[i][j / 2] = arr[i - 1][j];
        }
                
    }
    
}

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

int main() {
    int n = 4;
    char *arr[n] = {"Ala ma kota.", nullptr, "test2", nullptr};
    parse_arr(arr, n);
    print_arr(arr, n);
    return 0;
}

Zadanie 12

Napisz program w języku C++, który wyświetli parametry wiersza poleceń, z którymi został uruchomiony.

Rozwiązanie:
#include <iostream>

int main(int argc, char *argv[]) {
    for(int i = 0; i < argc; ++i)
        std::cout << argv[i] << std::endl;
    return 0;
}

Zadanie 13

Napisz program w języku C++, który wczytuje ze standardowego wejścia trzy liczby naturalne n, m i o, a następnie alokuje pamięć dla trzywymiarowej tablicy n x m x o. Wypełnij tę tablicę dowolnymi wartościami a następnie usuń z pamięci.

Rozwiązanie:
int main() {
    unsigned int n, m, o;
    int ***arr = nullptr;
    std::cin >> n >> m >> o;
    
    arr = new int**[n];
    for(unsigned int i = 0; i < n; ++i) {
        arr[i] = new int*[m];
        for(unsigned int j = 0; j < m; ++j)
            arr[i][j] = new int[o];
    }
    
    for(unsigned int i = 0; i < n; ++i)
        for(unsigned int j = 0; j < m; ++j)
            for(unsigned int k = 0; k < o; ++k)
                arr[i][j][k] = i * j + k;
    
    for(unsigned int i = 0; i < n; ++i) {
        for(unsigned int j = 0; j < m; ++j)
            delete[] arr[i][j];
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

Zadanie 14

Stwórz projekt wieloplikowy, który będzie się składał z 3 jednostek translacji: main.cpp, date_time.cpp oraz trigonometry.cpp. W pliku date_time.cpp zdefiniuj:
– funkcję print_time(), która wydrukuje na standardowym wyjściu aktualną datę i godzinę,
– funkcję start_measure(), która rozpocznie pomiar czasu procesora,
– funkcję elapsed_measure(), która wyświetli na ekranie czas w sekundach, który upłyną od ostatniego wywołania funkcji start_measure().
W pliku trigonometry.cpp zdefiniuj:
– funkcję deg2rad(), która skonwertuje wartość kąta w stopniach na wartość w radianach zgodnie z wyrażeniem: rad = deg * PI / 180.
– funkcję sinus(), która w parametrze przyjmie wartość kąta w radianach i zwróci wartość sinusa dla tego kąta. Napisz własną implementację wyznaczania funkcji sinus z rozwinięcia w szereg Taylora zgodnie z wyrażeniem: sin(x) = x - x3/3! + x5/5! - x7/7! + ...
Ilość wyrazów rozwinięcia określ tak żeby różnica w stosunku do bibliotecznej funkcji std::sin() była mniejsza niż eps < 10-4. Ogranicz się tylko do kątów z przedziału <0,180> stopni. W funkcji głównej programu main(), porównaj czasy wykonania własnej implementacji funkcji sinus i implementacji z biblioteki cmath std::sin(). Jakie zaproponujesz pliki nagłówkowe i jakie w nich umieścisz deklaracje funkcji i zmiennych dla tak postawionego problemu? Jak można zoptymalizować implementację szacowania funkcji sinus?

Rozwiązanie:
//data_time.h
#ifndef DATE_TIME_H
#define DATE_TIME_H

void print_time();
void start_measure();
void elapsed_measure();

#endif // DATE_TIME_H
//data_time.cpp
#include "date_time.h"
#include <iostream>
#include <chrono>

std::chrono::high_resolution_clock::time_point start;

void print_time() {
    auto now = std::chrono::system_clock::now();
    time_t now_c = std::chrono::system_clock::to_time_t(now);
    std::cout << asctime(localtime(&now_c));
}

void start_measure() {
    start = std::chrono::high_resolution_clock::now();
}

void elapsed_measure() {
    auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count();
    std::cout << elapsed / 60.  << "s\n";
}
//trigonometry.h
#ifndef TRIGONOMETRY_H
#define TRIGONOMETRY_H

double deg2rad(double deg);
double sinus(double x);

#endif // TRIGONOMETRY_H
//trigonometry.cpp
#include "trigonometry.h"
#include <cmath>

double deg2rad(double deg) {
    return deg * M_PI / 180.0;
}

double sinus(double x) {
    double sum = x, term = x, eps = 1e-4;
    for(int i = 1; fabs(term) > eps; ++i) {
        term *= -x * x / ((2 * i) * ( 2 * i + 1));
        sum += term;
    }
    return sum;
}
//main.cpp
#include "date_time.h"
#include "trigonometry.h"
#include <iostream>
#include <cmath>

int main() {
    double result, deg = 30, rad = deg2rad(deg);

    start_measure();
    for(int i = 0; i < 1000000; ++i)
    result = std::sin(rad);
    elapsed_measure();
    std::cout << "sinus z biblioteki cmath: " << result << "\n";

    start_measure();
    for(int i = 0; i < 1000000; ++i)
    result = sinus(rad);
    elapsed_measure();
    std::cout << "sinus z własnej implementacji: " << result << "\n";

    return 0;
}

Zadanie 15

Napisz funkcję w języku C++, która dostaje jako parametr dynamiczną dwuwymiarową tablicę liczb całkowitych i jej wymiary n, m. Funkcja ma zwrócić 0, jeśli na brzegach (tzn. w pierwszym i ostatnim wierszu oraz w pierwszej i ostatniej kolumnie) tablicy występują wartości tylko zerowe; w przeciwnym razie funkcja ma zwrócić 1.

Rozwiązanie:
int check_borders(int **arr, int n, int m) {
    for(int i = 0; i < n; ++i)
        if (arr[i][0] || arr[i][m - 1])
            return 1;
    for(int j = 0; j < m; ++j)
        if (arr[0][j] || arr[n - 1][j])
            return 1;
    return 0;
}

Zadanie 16

Napisz funkcję w języku C++, która dostaje jako argumenty dwuwymiarową tablicę tablic o elementach typu int oraz jej wymiary, i zmienia kolejność wierszy w tablicy w taki sposób, że wiersz pierwszy ma się znaleźć na miejscu drugiego, wiersz drugi ma się znaleźć na miejscu trzeciego itd., natomiast ostatni wiersz ma się znaleźć na miejscu pierwszego (przyjmujemy, że elementy w wierszu są umieszczone w pamięci obok siebie).

Rozwiązanie:
#include <iostream>

void print_arr(int **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 << std::endl;
    }
}

void change_order(int **arr, int n, int m) {
    for (int i = n - 1; i > 0; --i)
        std::swap(arr[i], arr[i - 1]);
}

int main() {
    int n = 5, m = 10;
    int **arr = new int*[n];
    for(int i = 0; i < n; ++i) {
        arr[i] = new int[m];
        for(int j = 0; j < m; ++j)
            arr[i][j] = i * j;
    }
    
    print_arr(arr, n, m);
    change_order(arr, n, m);
    print_arr(arr, n, m);
    
    for(int i = 0; i < n; ++i)
        delete[] arr[i];
    delete[] arr;
    return 0;
}

Zadanie 17

Napisz funkcję w języku C++, która obliczy (zwróci) iloczyn diadyczny dwóch wektorów o dowolnej ilości współrzędnych. Wektory mają być reprezentowane za pomocą jednowymiarowych dynamicznie alokowanych tablic a macierz przez dynamicznie alokowaną tablicę dwuwymiarową.

Rozwiązanie:
#include <iostream>

void calculate_dyadic_product(int* vector1, int* vector2, int n, int **result) {
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
            result[i][j] = vector1[i] * vector2[j];
}

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

int main() {
    int n = 3;
    int *vec_0 = new int[n]{1, 2, 3}, *vec_1 = new int[n]{4, 5, 6};
    int **result = new int*[n];
    for(int i = 0; i < n; ++i) result[i] = new int[n]();

    calculate_dyadic_product(vec_0, vec_1, n, result);
    print_matrix(result, n);

    for (int i = 0; i < n; ++i) delete[] result[i];
    delete[] result;
    delete[] vec_0;
    delete[] vec_1;
    return 0;
}

Przygotuj się na kolejne laboratorium!

W celu przygotowania się na kolejne zajęcia, spróbuj wykonać poniższe zadania samodzielnie.

Zadanie 1

Napisz funkcję w języku C++, która dodaje i zwraca wynik sumy dwóch liczb całkowitych przekazanych w argumentach funkcji. Napisz także analogiczną funkcję odejmującą dwie liczby. Napisz program w języku C++, w którym utworzony zostanie odpowiadający tym funkcjom wskaźnik do funkcji. Przypisz temu wskaźnikowi funkcję dodającą i wywołaj ją przez ten wskaźnik. Następnie zrób to samo z funkcją odejmującą.

Zadanie 2

Napisz dwie funkcje w języku C++, zwracającą (1) minimum i (2) maksimum z dwóch liczb całkowitych.

Zadanie 3

Napisz funkcję w języku C++, która liczy i zwraca ekstremum (minimum lub maksimum) liczb z tablicy. Funkcja powinna przyjmować tablicę, jej rozmiar oraz wskaźnik na funkcję liczącą maksimum lub minimum. Wywołaj funkcję dwukrotnie przekazując najpierw wskaźnik na funkcję minimum, a następnie maksimum.

Zadanie 4

Wykorzystaj funkcję qsort do posortowania tablicy liczb całkowitych rosnąco pod względem liczebności cyfry 0 w liczbach.

Zadanie 5

Zmodyfikuj poprzednie rozwiązanie tak, aby wykorzystało funkcję std::sort. Użyj jej zamiast qsort.

Dodaj komentarz

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