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
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
.