Днес ще трябва да решите задачи затвърждаващи знанията ви по уроците в тази тема: Въведение в езика C++.
Задачи и решения:
Задача 1*: Имате два int[] масива от по 1000 елемента. Генерирайте съдържанието им с rand(). Като всяко число в масивите трябва да е в интервала от 1 до 100. В трети масив запишете само общите им елементи без повторения и го отпечатайте.
Решение
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int MAX_SIZE {1'000};
int arrayA[MAX_SIZE] {};
int arrayB[MAX_SIZE] {};
int arrayC_Size {0};
int arrayC[MAX_SIZE] {};
void Randomize() {
srand((unsigned) time(0));
}
int RandomInt(int min, int max) {
return min + rand() % (max - min + 1);
}
void FillArray(int arr[], int size) {
for(int i = 0; i < size; i++)
arr[i] = RandomInt(1, 100);
}
void PrintArray(const int arr[], int size) {
cout << endl;
for(int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
bool ArrayHasValue(const int arr[], int arraySize, int value) {
for(int i = 0; i < arraySize; i++)
if(arr[i] == value) return true;
return false;
}
int main() {
Randomize();
FillArray(arrayA, MAX_SIZE);
FillArray(arrayB, MAX_SIZE);
/* търсим общите елементи между arrayA и arrayB
и ги записваме в arrayC без повторения */
for(int i = 0; i < MAX_SIZE; i++) {
int value = arrayA[i];
if(ArrayHasValue(arrayB, MAX_SIZE, value)) {
if(not ArrayHasValue(arrayC, arrayC_Size, value)) {
arrayC[arrayC_Size] = value;
arrayC_Size++;
}
}
}
PrintArray(arrayC, arrayC_Size);
}Задача 2: Имате два float[] масива от по 20 елемента. Генерирайте съдържанието им с rand(). Като всяко число в масивите трябва да е в интервала от 1.0 до 100.0. Отпечатайте ги. В трети масив запишете произвседението. Например c[0] = a[0] * b[0]. Изведете масива с резултатите.
Решения
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int MAX_SIZE {20};
float arrayA[MAX_SIZE] {};
float arrayB[MAX_SIZE] {};
float arrayC[MAX_SIZE] {};
void Randomize() {
srand((unsigned) time(0));
}
float RandomFloat(int min, int max) {
return min + (double) rand() / RAND_MAX * (max - min);
}
void FillArray(float arr[], int size) {
for(int i = 0; i < size; i++)
arr[i] = RandomFloat(1, 100);
}
void PrintArray(const float arr[], int size) {
cout << endl;
for(int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
int main() {
Randomize();
FillArray(arrayA, MAX_SIZE);
FillArray(arrayB, MAX_SIZE);
// решение
for(int i = 0; i < MAX_SIZE; i++)
arrayC[i] = arrayA[i] * arrayB[i];
cout << "Array A: ";
PrintArray(arrayA, MAX_SIZE);
cout << "Array B: ";
PrintArray(arrayB, MAX_SIZE);
cout << "Array C: ";
PrintArray(arrayC, MAX_SIZE);
}Задача 3: Напишете ваша функция StringCompare, която сравнява два char[] масива и го прави лексикографски.
int StringCompare(const char a[], const char b[]);
// връща отрицателно число при a < b
// връща 0 при a == b
// връща положително число при a > bКак трябва да работи:
- Сравняваме символ по символ;
- ако
a[i] < b[i]→ първият низ е по – малък; - ако
a[i] > b[i]→ първият низ е по – голям; - ако са равни → продължаваме;
- ако стигнем края → по-късият е по – малък;
Решение
int StringCompare(const char a[], const char b[]) {
int i = 0;
while (a[i] != '\0' && b[i] != '\0') {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
i++;
}
// ако единия е по-къс
if (a[i] == '\0' && b[i] == '\0') return 0;
if (a[i] == '\0') return -1;
return 1;
}Тест на StringCompare():
#include <iostream>
using namespace std;
int StringCompare(const char a[], const char b[]) {
int i = 0;
while (a[i] != '\0' && b[i] != '\0') {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
i++;
}
// ако единия е по-къс
if (a[i] == '\0' && b[i] == '\0') return 0;
if (a[i] == '\0') return -1;
return 1;
}
int main() {
char a[] = "apple";
char b[] = "airport";
int result = StringCompare(a, b);
if (result == 0)
cout << "Equal";
else if (result < 0)
cout << "a < b";
else
cout << "a > b";
}Задача 4*: Имате масив от думи записани в char[]. Сортирайте го по метода на мехурчето и изведете сортирания масив. Използвайте функцията, която написахте в горната задача. Ето и декларацията на масива:
char* words[] = {
"apple", "parrot", "banana", "orange", "grape",
"tiger", "elephant", "computer", "keyboard", "monitor",
"school", "teacher", "student", "window", "bottle",
"phone", "camera", "river", "mountain", "cloud"
};По същество това представлява масив от указатели към char* масиви завършващи на ‘\0’. Реално при сортирането просто разменяме местата на указателите.
Решение
#include <iostream>
using namespace std;
int StringCompare(const char a[], const char b[]) {
int i = 0;
while (a[i] != '\0' && b[i] != '\0') {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
i++;
}
// ако единия е по-къс
if (a[i] == '\0' && b[i] == '\0') return 0;
if (a[i] == '\0') return -1;
return 1;
}
void BubbleSort(char* arr[], int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
// ако arr[j] > arr[j + 1]
if (StringCompare(arr[j], arr[j + 1]) > 0) {
// размяна
char* temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void PrintWords(char* arr[], int size) {
cout << endl;
for (int i = 0; i < size; i++) {
cout << arr[i] << endl;
}
cout << endl;
}
int main() {
char* words[] = {
"apple", "parrot", "banana", "orange", "grape",
"tiger", "elephant", "computer", "keyboard", "monitor",
"school", "teacher", "student", "window", "bottle",
"phone", "camera", "river", "mountain", "cloud"
};
int size = sizeof(words) / sizeof(words[0]);
BubbleSort(words, size);
PrintWords(words, size);
}Задача 5: Имате зададен масив от string[]. Сортирайте го с библиотечната функция sort. И го изведете в терминала.
string words[20] = {
"apple", "river", "mountain", "cloud", "forest",
"ocean", "sun", "moon", "star", "wind",
"fire", "stone", "tree", "flower", "grass",
"bird", "sky", "rain", "snow", "shadow"
};Решение
#include <iostream>
#include <algorithm> // за sort
#include <string>
using namespace std;
int main() {
// масива
string words[20] = {
"apple", "river", "mountain", "cloud", "forest",
"ocean", "sun", "moon", "star", "wind",
"fire", "stone", "tree", "flower", "grass",
"bird", "sky", "rain", "snow", "shadow"
};
// сортиране
sort(words, words + 20);
// извеждане
cout << endl;
for(int i = 0; i < 20; i++)
cout << words[i] << endl;
cout << endl;
}Задача 6: Имате затворен интервал от години [1981; 2026]. Това означава, че 1981 и 2026 влизат в изброяването. Изведете високосните години разделени с интервал на един ред.
Решение
#include <iostream>
using namespace std;
bool isLeap(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int main() {
for(int i = 1981; i <= 2026; i++)
if(isLeap(i))
cout << i << " ";
cout << endl;
}Задача 7**: Напишете програма с името calendar. Тя приема един параметър при извикване от командния ред. Това трябва да е число. По точно година. Програмата отпечатва календара за съответната година в терминала по месеци. И седмиците започват от Понеделник.
Напишете решение без да ползвате STL.
Това е генерална задача прилагаща всичко научено до тук.
Решение
#include <iostream>
#include <string>
using namespace std;
const string months[] = {
"Януари", "Февруари", "Март", "Април",
"Май", "Юни", "Юли", "Август",
"Септември", "Октомври", "Ноември", "Декември"
};
bool isLeap(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int daysInMonth(int month, int year) {
switch (month) {
case 1: return 31;
case 2:
// Проверка за високосна година
if (isLeap(year)) return 29;
else return 28;
case 3: return 31;
case 4: return 30;
case 5: return 31;
case 6: return 30;
case 7: return 31;
case 8: return 31;
case 9: return 30;
case 10: return 31;
case 11: return 30;
case 12: return 31;
default:
return 0;
}
}
// Връща ден от седмицата:
// 0 = Понеделник, 1 = Вторник, ..., 6 = Неделя
int dayOfWeek(int day, int month, int year) {
if (month < 3) {
month += 12;
year--;
}
int k = year % 100;
int j = year / 100;
int h = (day + (13 * (month + 1)) / 5 + k +
k / 4 + j / 4 + 5 * j) % 7;
// Алгоритъма връща h = 0 като Неделя
// Нормализиранр: h = 0 за Понеделник
return (h + 5) % 7;
}
void printMonth(int month, int year) {
cout << "\n";
cout << "======== " << months[month - 1]
<< " " << year << " ========\n";
cout << " Пон Вт Ср Чет Пет Съб Нед\n";
int firstDay = dayOfWeek(1, month, year);
int days = daysInMonth(month, year);
// Празни места преди първия ден
for (int i = 0; i < firstDay; i++) {
cout << " ";
}
for (int day = 1; day <= days; day++) {
if (day < 10)
cout << " " << day << " ";
else
cout << " " << day << " ";
if ((firstDay + day) % 7 == 0)
cout << "\n";
}
cout << "\n";
}
int main(int argc, char* argv[]) {
if (argc != 2) {
cout << "Usage: ./calendar <year>\n";
return 1;
}
int year = 0;
// Преобразуване от char* към int
for (int i = 0; argv[1][i] != '\0'; i++) {
if (argv[1][i] < '0' || argv[1][i] > '9') {
cout << "Invalid year!\n";
return 1;
}
year = year * 10 + (argv[1][i] - '0');
}
for (int month = 1; month <= 12; month++)
printMonth(month, year);
}Задача 8: Напишете програма която намира първите 1000 прости числа. И ги извежда в терминала. Тук ще използваме функцията:
bool isPrime(int n) {
if (n < 2) return false;
// търсим до корен втори (оптимизация)
for (int i = 2; (i * i) <= n; i++)
if (n % i == 0) return false;
return true;
}Обърнете внимание на (i * i)!
Решение
#include <iostream>
using namespace std;
bool isPrime(int n) {
if (n < 2) return false;
// търсим до корен втори (оптимизация)
for (int i = 2; (i * i) <= n; i++)
if (n % i == 0) return false;
return true;
}
int main() {
int count = 1;
int num = 2;
while (count <= 1000) {
if (isPrime(num)) {
cout << "Prime [" << count << "] = " << num << endl;
count++;
}
num++;
}
}Задача 9: Напишете програма намираща решение на квадратни уравнения от вида Ax^2 + Bx + C = 0
Решение
#include <iostream>
#include <cmath>
using namespace std;
int main() {
double A, B, C;
cout << "Въведете A, B и C: " << endl;
cout << "A = "; cin >> A;
cout << "B = "; cin >> B;
cout << "C = "; cin >> C;
// проверка дали е квадратно уравнение
if (A == 0) {
cout << "Това не е квадратно уравнение." << endl;
return 0;
}
double D = B * B - 4 * A * C;
cout << "Дискриминанта D = " << D << endl;
// два реални корена
if (D > 0) {
double x1 = (-B + sqrt(D)) / (2 * A);
double x2 = (-B - sqrt(D)) / (2 * A);
cout << "x1 = " << x1 << endl;
cout << "x2 = " << x2 << endl;
}
// един реален корен
else if (D == 0) {
double x = -B / (2 * A);
cout << "x = " << x << endl;
}
// няма реални корени
else {
cout << "Уравнението няма реални корени." << endl;
}
}Задача 10*: Използвайте реда на Leibniz, за да изчислите числото Pi. Трябва да завъртите циклъл и да спрете когато точността на получения резултат стане по – малка от 10-9. После направете необходимите преобразувания, за да получите реалната стойност на Pi.

Решение
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
double pi = 0.0;
double term;
int sign = 1;
int n = 1;
const double EPS = 10e-9;
int iterCount = 0;
do {
term = sign * (1.0 / n);
pi += term;
sign *= -1;
n += 2;
iterCount++;
} while (fabs(term) > EPS);
pi *= 4;
cout << "pi = "
// това фиксира формата до 10-9
<< fixed << setprecision(9)
<< pi << endl;
cout << "-- Диагностика --" << endl;
cout << "Необходим брой итерации: " << iterCount << endl;
}Това са 50 000 000 итерации? От този малък код… Програмата замръзна за ~ 1/2 секунда преди да изплюе отговора. И не съм задал флагове за оптимизация. Не ми се мисли колко време ще отнеме подобен код написан на някой интерпретатор 🙂
Поздравления!
Завършихте част първа от уроците!
На този етап не се очаква от вас да решите всичко, като по учебник. Ако сте решили всички задачи без звездичка минавате. Една решена задачка с * е отличен. А ако успеете да напишете кода на calendar сте на ниво PRO!
Отне ми време да обмисля сложни условия на задачите. Всяка задача иска обмисляне. В някои задачи въвеждаме нови знания без да сме ги обяснили. Това е най – добрия начин за интуитивно учене (проба – грешка). Първо покажи, че го има и работи. После обясни.