diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp new file mode 100644 index 0000000..bf07214 --- /dev/null +++ b/exercise/01/containers.cpp @@ -0,0 +1,87 @@ +#include "containers.h" +#include + +void remove_element(std::vector& v, int index) +{ + v.erase(v.begin() + index); +} + +void input_element(std::vector& v, int index, const std::wstring& value) +{ + v.insert(v.begin() + index, value); +} + +int list_nth_element(const std::list& c, int index) +{ + std::list::const_iterator it = c.begin(); + + std::advance(it, index); + + return *it; +} + +void list_sort_desc(std::list& c) +{ + c.sort(); + c.reverse(); +} + +int unique_numbers(std::wistream& stream) +{ + std::set UniqueNumbers; + int NewNumber; + + while (stream >> NewNumber) + { + UniqueNumbers.insert(NewNumber); + } + + return UniqueNumbers.size(); +} + + +//////////////////////////////////////////////////////////////////////////// +word_frequency::word_frequency(std::wistream& stream) +{ + std::wstring InputString; + + while (stream >> InputString) + { + CastToLower(InputString); + + if (m_Words.find(InputString) != m_Words.end()) + { + m_Words[InputString]++; + } + else + { + m_Words[InputString] = 1; + } + } +} + + +int word_frequency::count() +{ + return m_Words.size(); +} + + +int word_frequency::frequency(const std::wstring& word) +{ + if (m_Words.find(word) != m_Words.end()) + { + return m_Words[word]; + } + + return 0; +} + + +void CastToLower(std::wstring& Word) +{ + for (wchar_t& Char : Word) + { + Char = std::towlower(Char); + } +} diff --git a/exercise/01/containers.h b/exercise/01/containers.h index 8e1b172..46ec87b 100644 --- a/exercise/01/containers.h +++ b/exercise/01/containers.h @@ -2,6 +2,9 @@ #include #include #include +#include +#include + void remove_element(std::vector& v, int index); void input_element(std::vector& v, int index, const std::wstring& value); @@ -10,11 +13,16 @@ int list_nth_element(const std::list& c, int index); void list_sort_desc(std::list& c); int unique_numbers(std::wistream&); +void CastToLower(std::wstring& word); class word_frequency { public: - word_frequency(std::wistream&); - int frequency(const std::wstring& s); + word_frequency() = default; + word_frequency(std::wistream& stream); + int frequency(const std::wstring& word); int count(); + +private: + std::map m_Words; }; diff --git a/exercise/01/e01.vcxproj b/exercise/01/e01.vcxproj index 8db291c..6bd4d49 100644 --- a/exercise/01/e01.vcxproj +++ b/exercise/01/e01.vcxproj @@ -1,97 +1,97 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {DD752318-EA08-4316-9EFE-C1A42F5526F4} - Win32Proj - e01 - 10.0.17134.0 - - - - DynamicLibrary - true - v141 - Unicode - false - - - DynamicLibrary - false - v141 - true - Unicode - false - - - - - - - - - - - - - true - . - - - true - . - - - - NotUsing - Level3 - Disabled - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;%(PreprocessorDefinitions) - true - - - Windows - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - NotUsing - MaxSpeed - true - true - $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;%(PreprocessorDefinitions) - true - - - Windows - true - true - true - $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {DD752318-EA08-4316-9EFE-C1A42F5526F4} + Win32Proj + e01 + 10.0.17134.0 + + + + DynamicLibrary + true + v141 + Unicode + false + + + DynamicLibrary + false + v141 + true + Unicode + false + + + + + + + + + + + + + true + . + + + true + . + + + + NotUsing + Level3 + Disabled + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + NotUsing + MaxSpeed + true + true + $(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + \ No newline at end of file diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 9df3595..6d5870f 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -8,6 +8,14 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; #include #include + +int IncrementingBy2(void) +{ + static int number = 0; + return number++*2 + 1; +} + + TEST_CLASS(test_standard_algorithms_usage) { public: @@ -15,19 +23,22 @@ TEST_CLASS(test_standard_algorithms_usage) { std::wstringstream ss(L"14 -78 22"); std::vector v; - // TODO: read values from input stream into vector + + v.assign(std::istream_iterator(ss), std::istream_iterator()); Assert::AreEqual(3u, v.size()); Assert::AreEqual(14, v[0]); Assert::AreEqual(-78, v[1]); Assert::AreEqual(22, v[2]); - } TEST_METHOD(test_02a) { std::vector v(10); + // TODO: fill vector with incremental values - Assert::AreEqual(10u, v.size()); + std::iota(v.begin(), v.end(), 1); + + Assert::AreEqual(10u, v.size()); Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); Assert::AreEqual( 1, v[0]); Assert::AreEqual(10, v[9]); @@ -36,8 +47,11 @@ TEST_CLASS(test_standard_algorithms_usage) { // generate std::vector v(10); + // TODO: fill vector with incremental values (by 2) - Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); + std::generate(v.begin(), v.end(), IncrementingBy2); + + Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); Assert::IsTrue(v.cend() == std::adjacent_find(v.cbegin(), v.cend(), [](int a, int b) { return b - a != 2; })); Assert::AreEqual(1, v[0]); Assert::AreEqual(19, v[9]); @@ -46,8 +60,11 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_03a) { std::vector v = { 1, 5, 10 } ; - // TODO: change all values in a vector - Assert::AreEqual(3u, v.size()); + + // TODO: change all values in a vector + std::transform(v.begin(), v.end(), v.begin(), [](int a) {return a*a*a; }); + + Assert::AreEqual(3u, v.size()); Assert::AreEqual(1, v[0]); Assert::AreEqual(125, v[1]); Assert::AreEqual(1000, v[2]); @@ -59,7 +76,10 @@ TEST_CLASS(test_standard_algorithms_usage) std::vector d; // TODO: calculate distances from origin (from x and y collections) to new vector - Assert::AreEqual(3u, d.size()); + std::transform(std::begin(x), std::end(x), y.begin(), std::back_inserter(d), [](int a, int b) + { return std::sqrt(a*a + b*b); } ); + + Assert::AreEqual(3u, d.size()); Assert::AreEqual(5., d[0]); Assert::AreEqual(13., d[1]); Assert::AreEqual(sqrt(200), d[2]); @@ -67,68 +87,95 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_04a) { std::wstringstream ss(L"1.5 2.5 3.5"); - auto res = // TODO: sum of all values in input stream - Assert::AreEqual(7.5, res); + + // TODO: sum of all values in input stream + auto res = std::accumulate(std::istream_iterator(ss), std::istream_iterator(), 0.0); + + Assert::AreEqual(7.5, res); } TEST_METHOD(test_04b) { std::vector v { L"A", L"V", L"L", L"!" }; - auto res = // TODO: concatenated string with additional prefix - Assert::AreEqual(L"GO AVL!", res.c_str()); + + // TODO: concatenated string with additional prefix + auto res = std::accumulate(v.begin(), v.end(), static_cast(L"GO ")); + + Assert::AreEqual(L"GO AVL!", res.c_str()); } TEST_METHOD(test_04c) { struct person { std::wstring name; int age; }; std::vector v{ {L"Pero", 33}, {L"Iva", 25} }; - auto total_age = // TODO: sum of all ages - Assert::AreEqual(58, total_age); + + // TODO: sum of all ages + auto total_age = std::accumulate(v.begin(), v.end(), 0, [](int a, person& P) {return a + P.age; }); + + Assert::AreEqual(58, total_age); } - TEST_METHOD(test_05a) { std::vector v { -5, 8, 11, 0, -9, 77, -4 }; - auto number_of_negative = // TODO: - Assert::AreEqual(3, number_of_negative); + + auto number_of_negative = std::count_if(v.begin(), v.end(), [](int n) {return n < 0 ? true : false; }); + + Assert::AreEqual(3, number_of_negative); } TEST_METHOD(test_05b) { std::vector v { 1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - auto number_of_invalid = // TODO: - Assert::AreEqual(3, number_of_invalid); + + auto number_of_invalid = std::count(v.begin(), v.end(), 1e10); + + Assert::AreEqual(3, number_of_invalid); } TEST_METHOD(test_05c) { struct point { int x, y; }; std::vector v{ {1,1}, {-5,3}, {2,2}, {-7,-6}, {9,-4} }; - auto number_in_first_quadrant = // TODO: - Assert::AreEqual(2, number_in_first_quadrant); + + auto number_in_first_quadrant = std::count_if(v.begin(), v.end(), [](point P) {return ((P.x > 0) && (P.y > 0)); }); + + Assert::AreEqual(2, number_in_first_quadrant); } TEST_METHOD(test_06) { std::vector v { 33, 16, 24, 41, 25, 19, 9 }; - auto first_prime = // TODO: - Assert::AreEqual(41, first_prime); + + auto first_prime = *std::find_if(v.begin(), v.end(), [](int num) + {bool IsPrime = false; for (int i = 2; i < num - 1; i++) { if (num%i == 0) return false; } return true; } ); + + Assert::AreEqual(41, first_prime); } TEST_METHOD(test_07a) { std::vector v{ 1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - // TODO: change every invalid value (1e10) with -1 - Assert::AreEqual(-1., v[0]); + + // TODO: change every invalid value (1e10) with -1 + std::replace_if(v.begin(), v.end(), [](double num) {return num == 1e10 ? true : false; }, -1.0); + + Assert::AreEqual(-1., v[0]); Assert::AreEqual(-1., v[4]); Assert::AreEqual(-1., v[6]); } TEST_METHOD(test_07b) { std::wstring s(L"ponedjeljak"); - // TODO: change every vowel with x - Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); + + // TODO: change every vowel with x + std::replace_if(s.begin(), s.end(), [](wchar_t& letter) + { return ((letter == L'a') || (letter == L'e') || (letter == L'i') || (letter == L'o') || (letter == L'u')); }, L'x'); + + Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); } TEST_METHOD(test_08a) { std::vector v{ 1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - // TODO: delete all invalid values (1e10) - Assert::AreEqual(5u, v.size()); + + // TODO: delete all invalid values (1e10) + v.erase(std::remove_if(v.begin(), v.end(), [](double num) {return num == 1e10 ? true : false; }), v.end()); + + Assert::AreEqual(5u, v.size()); Assert::AreEqual(8., v[0]); Assert::AreEqual(99., v[4]); } @@ -136,15 +183,23 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_08b) { std::wstring s(L"ponedjeljak"); - // TODO: delete all vowels - Assert::AreEqual(L"pndjljk", s.c_str()); + + // TODO: delete all vowels + s.erase(std::remove_if(s.begin(), s.end(), [](wchar_t& letter) + { return ((letter == L'a') || (letter == L'e') || (letter == L'i') || (letter == L'o') || (letter == 'u')); }), s.end()); + + Assert::AreEqual(L"pndjljk", s.c_str()); } TEST_METHOD(test_09) { struct exam { std::wstring name; int points, grade; }; std::vector v{ {L"Pero", 55, 2}, {L"Iva", 93, 5}, {L"Marko", 89, 5} }; - // TODO: sort vector by grade, then by points - Assert::AreEqual(L"Iva", v[0].name.c_str()); + + // TODO: sort vector by grade, then by points + std::sort(v.begin(), v.end(), [](const exam& ex1, const exam& ex2) + { return ex1.grade == ex2.grade ? ex1.points > ex2.points : ex1.grade > ex2.grade; }); + + Assert::AreEqual(L"Iva", v[0].name.c_str()); Assert::AreEqual(L"Marko", v[1].name.c_str()); Assert::AreEqual(L"Pero", v[2].name.c_str()); @@ -162,8 +217,11 @@ TEST_CLASS(test_standard_algorithms_usage) using namespace std::chrono; auto t1 = steady_clock::now(); - // TODO: put median value in the middle of vector. fast. - auto t2 = steady_clock::now(); + + // TODO: put median value in the middle of vector. fast. + std::nth_element(v.begin(), v.begin() + v.size()/2, v.end()); + + auto t2 = steady_clock::now(); auto dur = duration_cast(t2 - t1); Assert::AreEqual(1000., v[v.size() / 2]); // median value Assert::IsTrue(dur.count() < 1000, std::to_wstring(dur.count()).c_str()); // faster than 1 second @@ -172,23 +230,35 @@ TEST_CLASS(test_standard_algorithms_usage) { struct employee { std::wstring name; int salary; }; std::vector v{ {L"Iva", 2000}, {L"Pero", 1000}, {L"Marko", 10000} }; - // TODO: put employee with median salary in the middle of vector - std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) { return a.salary < b.salary; }); + + // TODO: put employee with median salary in the middle of vector + std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), + [](const employee& e1, const employee& e2) { return e1.salary < e2.salary; }); + + + std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) { return a.salary < b.salary; }); Assert::AreEqual(L"Iva", v[v.size() / 2].name.c_str()); // median_salary } TEST_METHOD(test_12) { std::vector v{ 11, 0.5, -97.23, -23.11, 48.78, 22.96, -77 }; - auto smallest_value = // TODO: - Assert::AreEqual(-97.23, smallest_value); - auto largest_value = // TODO: - Assert::AreEqual(48.78, largest_value); + + auto smallest_value = *std::min_element(v.begin(), v.end()); + + Assert::AreEqual(-97.23, smallest_value); + + auto largest_value = *std::max_element(v.begin(), v.end()); + + Assert::AreEqual(48.78, largest_value); } TEST_METHOD(test_13) { std::vector atp_points { 8445, 7480, 6220, 5300, 5285 }; - // the most interesting match is the one with the smallest difference - auto smallest_difference = // TODO: - Assert::AreEqual(15, smallest_difference); + + // the most interesting match is the one with the smallest difference + std::adjacent_difference(atp_points.rbegin(), atp_points.rend(), atp_points.rbegin()); + auto smallest_difference = *std::min_element(atp_points.begin(), atp_points.end()); + + Assert::AreEqual(15, smallest_difference); } };