-
Kerdo Kurs authoredKerdo Kurs authored
main.cpp 7.21 KiB
#include <iostream>
#include <random>
#include <sstream>
#include <string>
// Ülesanne 1.
// Kirjuta funktsioon `is_palindrome`, mis kontrollib kas sõne on palindroom
// (https://et.wikipedia.org/wiki/Palindroom). Ignoreeri tühikuid (whitespace)
// ja suurtähelisust, s.t et "a A" on palindroom.
//
// Kasuta funktsioonide üle defineerimist, et funktsioon kasutaks mõlemat
// tüüpi argumente, nii `std::string` kui ka C-tüüpi sõne `const char*`.
// Mõlemad üle defineerimised peavad tagastama tõeväärtustüübi `bool`.
//
// Näide:
// is_palindrome("racecar") tagastab true
// is_palindrome(std::string("racecar")) tagastab true
// is_palindrome("") tagastab true
// is_palindrome("ab") tagastab false
//
// NB! Pane tähele, et ainult `bool is_palindrome(std::string)` loomisel
// töötavad mõlemat tüüpi argumendid. Uuri iseseisvalt lähemalt miks see nii
// juhtub.
bool is_palindrome(const char *s) {
size_t left = 0;
auto length = std::strlen(s);
if (length == 0) {
return true;
}
size_t right = length - 1;
while (left < right) {
if (left < right && std::tolower(s[left]) != std::tolower(s[right])) {
return false;
}
left++;
right--;
}
return true;
}
bool is_palindrome(std::string s) { return is_palindrome(s.c_str()); }
// Ülesanne 2.
// Kirjuta funktsioon `word_count`, mis loeb sõnade arvu antud sõnes.
// Siin kontekstis tähendab sõna tühikutega (whitespace) eraldatud karakterite
// jada. Tühjas sõnes on 0 sõna.
//
// Näide:
// word_count("Tere maailm!") tagastab 2 ja toimib järgmiselt:
// 1. sõna on "Tere"
// 2. sõna on "maailm!"
size_t word_count(std::string s) {
std::stringstream ss(s);
size_t count = 0;
std::string sona;
while (ss >> sona) {
count++;
}
return count;
}
// Ülesanne 3.
// Kirjuta funktsioon `words`, mis tagastab konteineri
// `std::vector<std::string>`, ning tagastab iga sõna antud sõnes. Sõna on siin
// kontekstis sama, mis ülesandes 2.
//
// Näide:
// words("Tere maailm!") tagastab vektori, kus on sõnad "Tere" ja "maailm!"
// words("a b c d ") tagastab vektori, kus on sõnad "a", "b", "c" ja "d"
// Pane tähele, et viimane sõna on "d" mitte "", s.t ignoreeri ülejäänud
// tühikuid
//
// Vihje: Proovi kasutada klassi `std::stringstream`
std::vector<std::string> words(std::string s) {
std::vector<std::string> words;
std::stringstream ss(s);
std::string sona;
while (ss >> sona) {
words.push_back(sona);
}
return words;
}
// Ülesanne 4.
// Kirjuta funktsioon `random_diff`, mis saab argumendiks täisarvu n ning
// konstrueerib 2 täisarvuvektorit (`std::vector<int>`). Seejärel lisab
// funktsioon mõlemasse vektorisse juhuslikke arve senikaua kuni mõlema vektori
// pikkus on n. Vali ise, mille alusel vektoreid täita. Funktsioon tagastab
// vektori vastavate elementide vahede summa. See tähendab, et kui vektor a =
// {1, 2, 3} ja b = {4, 5, 6} siis tagastatakse sum({1 - 4, 2 - 5, 3 - 6}) = -9
// Üleval toodud näidis on pseudokood ja ei ole valiidne C++ keeles.
//
// NB! Ära kasuta funktsiooni `rand()`.
// NB! Ülesannet on võimalik lahendada ilma vektoriteta, aga lahenda siiski
// kasutades vektoreid.
int random_diff(int n) {
std::vector<int> v1(n);
std::vector<int> v2(n);
std::default_random_engine gen;
std::uniform_int_distribution<int> jaotus(-100, 100);
for (int i = 0; i < n; ++i) {
v1[i] = jaotus(gen);
v2[i] = jaotus(gen);
}
std::vector<int> diffs(n);
for (int i = 0; i < n; ++i) {
diffs[i] = v1[i] - v2[i];
}
int sum = 0;
for (int i = 0; i < n; ++i) {
sum += diffs[i];
}
// Võimalus, kuidas vektori elemendid kokku liita
// return std::reduce(diffs.begin(), diffs.end(), 0);
return sum;
}
// Ülesanne 5.
// Kirjuta funktsioon `randomize`, mis saab argumendiks C-tüüpi täisarvude
// massiivi ning selle pikkuse (tüüpi size_t). Seejärel täidab fuktsioon antud
// massiivi juhuslike arvudega ning tagastab nende arvude summa. Võid eeldada,
// et n > 0
//
// Näide:
// int arr[10] = {0};
// size_t size = 10;
// int sum = randomize(arr, size);
// // nüüd on massiivis juhuslikud arvud ja sum võrdne nende summaga
int randomize(int *arr, size_t n) {
auto sum = 0;
std::default_random_engine gen;
std::uniform_int_distribution<int> jaotus(-100, 100);
for (size_t i = 0; i < n; i++) {
auto x = jaotus(gen);
arr[i] = x;
sum += x;
}
return sum;
}
// Ülesanne 6.
// Kirjuta funktsioon `average`, mis saab argumendiks konteineri
// `std::array<int, 10>` ning tagastab nende arvude aritmeetilise keskmise.
//
// Näide:
// std::array<int, 10> arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// average(arr) tagastab keskmise 5.5
//
// NB! Pane tähele, et funktsioon aktsepteerib argumendina ainult `std::array`
// konteinereid mille pikkus on 10. Selle piirangu eemaldamist vaatame tulevatel
// nädalatel.
//
// Mõtle std::array ja C-tüüpi massiivide erisuse peale
float average(std::array<int, 10> arr) {
return std::reduce(arr.begin(), arr.end(), 0) /
static_cast<float>(arr.size());
}
// Ära neid muutujaid ja funktsioone redigeeri.
static int g_TotalTestCount = 0;
static int g_SuccessfulTestCount = 0;
#define TEST(condition) testAssert(condition, __FILE__, __LINE__)
void testAssert(bool condition, const char *file, int line) {
g_TotalTestCount++;
if (!condition) {
std::cout << "VIGA: Kontroll asukohas " << file << ":" << line
<< " ei olnud õige.\n";
} else {
g_SuccessfulTestCount++;
}
}
auto equal(auto a, auto b) {
if (a.size() != b.size()) {
return false;
}
return std::equal(a.begin(), a.end(), b.begin());
}
template <typename T> auto all(T *ptr, size_t count, T comp) {
return std::all_of(ptr, ptr + count, [comp](auto v) { return v == comp; });
}
int main() {
// Ülesanne 1. Palindroom
TEST(is_palindrome("racecar") == true);
TEST(is_palindrome("raCecaR") == true);
TEST(is_palindrome(std::string("racecar")) == true);
TEST(is_palindrome(std::string("")) == true);
TEST(is_palindrome(std::string("aa")) == true);
TEST(is_palindrome(std::string("ab")) == false);
TEST(is_palindrome(std::string("()()")) == false);
TEST(is_palindrome(std::string("())(")) == true);
// Ülesanne 2. Sõnade arv
TEST(word_count("") == 0);
TEST(word_count("A B") == 2);
TEST(word_count("A B ") == 2);
TEST(word_count("Tere maailm!") == 2);
// Ülesanne 3. Sõnad
using StrVector = std::vector<std::string>;
TEST(words("").empty());
TEST(equal(words("A B"), StrVector{"A", "B"}));
TEST(equal(words("A B "), StrVector{"A", "B"}));
TEST(equal(words("a b c d"), StrVector{"a", "b", "c", "d"}));
// Ülesanne 4. Suvalised arvud
// NB! Korrektset tulemust on pisut keerukam testida. Proovi mõelda, kuidas
// sina seda testiksid.
TEST(random_diff(10) != std::numeric_limits<int>::min());
{
int arr[10] = {0};
size_t size = 10;
int sum = randomize(arr, size);
// Statistiliselt ei tohiks summa olla 0.
TEST(sum > 0);
// Arvud ei tohiks olla 0.
TEST(!all(arr, size, 0));
}
// Ülesanne 5. Keskmine väärtus
{
std::array arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TEST(average(arr) == 5.5f);
}
std::cout << "Testide tulemus: " << g_SuccessfulTestCount << "/"
<< g_TotalTestCount << '\n';
return 0;
}