diff --git a/README.md b/README.md index b5fc39d..c219b1b 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,13 @@ **Project Hierarchy** ``` -includes/ → Header files (.h, .hpp) -src/ → Source files (.cpp) -tests/ → GoogleTest test cases +includes/ -> Header files (.h, .hpp) +src/ -> Source files (.cpp) +tests/ -> GoogleTest test cases +docs/ -> Documents ``` +--- ## 2. Dependencies Make sure the following tools are installed before building the project: - **g++ / gcc** @@ -20,21 +22,20 @@ Make sure the following tools are installed before building the project: - **cppcheck** (for static analysis) - **Optional:** Install `clang-format` to format C++ code. -**Linux** -```bash -sudo apt install clang-format -find . -regex '.*\.\(cpp\|h\|hpp\)' -exec clang-format -i {} \; -``` -**Windows** -```bash -# Install clang-format via Chocolatey -choco install clang-format -# Apply clang-format recursively to .cpp, .h, .hpp files -Get-ChildItem -Recurse -Include *.cpp, *.h, *.hpp | ForEach-Object { clang-format -i $_.FullName } -``` -## 3. Setup -### 3.1. Setup the Local Test Environment +> Apply clang-format recursively to .cpp, .h, .hpp files + **Linux** + ```bash + sudo apt install clang-format + find . -regex '.*\.\(cpp\|h\|hpp\)' -exec clang-format -i {} \; + ``` + **Windows** + ```bash + Get-ChildItem -Recurse -Include *.cpp, *.h, *.hpp | ForEach-Object { clang-format -i $_.FullName } + ``` +--- +## 3. Setup Environment +### 3.1. Dev - **Ubuntu system** * Install `gcc`, `cmake`, `git`, and `pthread` (Skip this step if you already install) ```bash @@ -101,7 +102,7 @@ Get-ChildItem -Recurse -Include *.cpp, *.h, *.hpp | ForEach-Object { clang-forma * `cpp-lab:latest`: the image you built earlier. * `/bin/bash`: the command to execute inside the container (opens a Bash shell). -### 3.2 Config C/C++ Debugging (VS Code) +### 3.2 Debug - C/C++ Debugging (VS Code) #### 3.2.1. Launch Configuration @@ -235,7 +236,7 @@ Notes: ### 3.3 Documentation with `doxygen` TBD - Refer to this [Documentation with doxygen](https://www.labri.fr/perso/fleury/posts/programming/using-cmake-googletests-and-gcovr-in-a-c-project.html#:~:text=of%20the%C2%A0project.-,Documentation%20with%20doxygen,-Code%20embedded%20documentation) -## 5. Update Docker Image +## 4. Docker Image ```bash # Navigate to the project that contain your Dockerfile cd cpp-lab @@ -250,11 +251,11 @@ docker image ls docker push DOCKER_USERNAME/cpp-lab ``` -## 6. TroubleShooting +## 5. TroubleShooting 1. `push access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed` => docker login / Docker Desktop login -## 7. Evaluate Executable +## 6. Evaluate Executable - List all sections: ```bash $ size ./build/cpp-lab diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..2504c53 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,29 @@ +# CPP Lab Docs + +## Core + +1. [Basic](../src/core/basics/README.md) +2. [Class](../src/core/class/README.md) +3. [Concurrency](../src/core/concurrency/README.md) +4. [Container](../src/core/container/README.md) +5. [Date time](../src/core/datetime/README.md) +6. [Exception](../src/core/exception/README.md) +7. [Expression](../src/core/expression/README.md) +8. [File handle](../src/core/filehandle/README.md) +9. [Smart pointer](../src/core/smart_pointer/README.md) +10. [String](../src/core/string/README.md) + +## Design Patterns + +11. [Behavioral](../src/dp/behavioral/README.md) +12. [Structural](../src/dp/structural/README.md) +13. [Creational](../src/dp/creational/README.md) + +## Architecture Patterns + +14. [MVC/MVVM](../src/ap/README.md) + +## Other + +15. [Socket](../src/socket/README.md) +16. [Google Test](../tests/README.md) \ No newline at end of file diff --git a/docs/uml/ap/ap_mvvm_example.drawio.svg b/docs/uml/ap/ap_mvvm_example.drawio.svg new file mode 100644 index 0000000..6de5c09 --- /dev/null +++ b/docs/uml/ap/ap_mvvm_example.drawio.svg @@ -0,0 +1,4 @@ + + + +
VM
M
V
Data
Event
Data
View Changed
Write
Read
Model Changed
ViewModel Changed
Data Binding Mechanism

<<Interface>>
IObserver


+ onDataChanged(const string& newData)



SharedData
- data_: string
- observers_: vector<IObserver*>

- notifyObservers(): void
+ SharedData()
+ addObserver(IObserver* obs): void

+set/getData
model
 setData(data):
this->data_ = data;
notifyObservers()

 notifyObserver:
for( IObserver o : observers_)
 o-> onDataChanged(data_)


viewmodel
SharedDataVM
- model_: shared_ptr<Model>
- view_observers_: vector<IObserver*>
+ SharedDataVM(shared_ptr<SharedData> model);

+ submitText(const string& text)
+ std::string getCurrentText()


1
 submitText(text):
model_->setData(text)
 getCurrentText:
model_->getData()
1
0..n
view
EditorWidget
- attr..: Gtk...
- view_model_: shared_ptr<DataSharedVM>

+ EditorWidget(shared_ptr<DataSharedVM> vm)
DisplayWidget
- attr..: Gtk...
- view_model_: shared_ptr<DataSharedVM>

+ DisplayWidget(const string& title, const string& color, shared_ptr<SharedDataVM> vm)
 EditorWidget/DisplayWidget:

  view_model_=vm
  view_model_->addObserver(this);

 regis:

  button_.signal_clicked().connect(
      [this]() { view_model->submitText(entry_.get_text()); });
1
1
1
0..n
1
0..n
 main

shared_ptr<SharedData> m = make_shared<SharedData>();
shared_ptr<SharedDataVM> vm = make_shared<SharedDataVM>(m)
unique_ptr<EditorWidget> iv = make_unique<EditorWidget>(vm); unique_ptr<DisplayWidget> ov1 = make_unique<DisplayWidget>(vm);
unique_ptr<DisplayWidget> ov2 = make_unique<DisplayWidget>(vm);

// Flow
input -> iv -> press iv's button -> vm.submitText
-> m.setData -> m.notifyObserver -> vm.notifyObserver -> views update 
\ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d9f8b3..191aecb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,9 +9,6 @@ add_subdirectory(dp) add_subdirectory(socket) add_subdirectory(ap) -# main application executable does NOT link to this library. -add_subdirectory(leetcode) - # Header files directory set(APP_HEADERS ${PROJECT_SOURCE_DIR}/include diff --git a/src/ap/README.md b/src/ap/README.md index f757537..88afdb9 100644 --- a/src/ap/README.md +++ b/src/ap/README.md @@ -1,5 +1,6 @@ ## Architecture Patterns ### 1. MVVM +![Diagram](../../docs/uml/ap/ap_mvvm_example.drawio.svg) - **MVVM (Model - View - ViewModel)** is an architecture pattern that separates the user interface (`View`) from the business logic and data (`Model`) through an intermediary component called the `ViewModel` - **Components:** - **Model**: responsible for managing and abstracting data sources (databases, APIs, ..). @@ -17,10 +18,13 @@ 6. The `ViewModel` updates the observable data, which automatically updates the `View` through `data binding or observers`. ```bash User - ↓ -View ↔ ViewModel ↔ Model # view automatically update + | + v +View <-> ViewModel <-> Model # view automatically update (data binding) ``` + +--- ### 2. MVC ![Diagram](../../docs/uml/ap/ap_mvc_example.drawio.svg) - **MVC (Model - View - Controller)** is an architectural pattern that separates the user interface (`View`) from the application logic and data (`Model`) using an intermediary component called the `Controller`. @@ -37,14 +41,19 @@ View ↔ ViewModel ↔ Model # view automatically update 5. The `Controller` then updates the `View` based on the new `Model` data. ```bash User - ↓ -View → Controller → Model - ↓ + | + v +View -> Controller -> Model + | + v View # view update manually ``` + +--- ### 3. GTK4 - [Refer](https://docs.gtk.org/gtk4/getting_started.html) +--- ### 4. Trade-offs: MVC vs MVVM | Aspect | MVC | MVVM | diff --git a/src/core/datetime/REAME.md b/src/core/datetime/README.md similarity index 100% rename from src/core/datetime/REAME.md rename to src/core/datetime/README.md diff --git a/src/leetcode/CMakeLists.txt b/src/leetcode/CMakeLists.txt deleted file mode 100644 index f9e8b2f..0000000 --- a/src/leetcode/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -add_library(leetcode) - -target_include_directories(leetcode - PUBLIC - ${PROJECT_SOURCE_DIR}/include # for shared public headers -) - -target_sources(leetcode - PRIVATE - arrays/two_sum/TwoSum.cpp - arrays/median_two_arrays/MedianTwoSortedArrays.cpp - arrays/container_with_most_water/ContainerWithMostWater.cpp - arrays/longest_common_prefix/Solution.cpp - arrays/3sum/Solution.cpp - arrays/4sum/Solution.cpp - PUBLIC - FILE_SET HEADERS - BASE_DIRS arrays - FILES - arrays/3sum/Solution.h - arrays/4sum/Solution.h - arrays/container_with_most_water/ContainerWithMostWater.h - arrays/longest_common_prefix/Solution.h - arrays/median_two_arrays/MedianTwoSortedArrays.h - arrays/two_sum/TwoSum.h -) \ No newline at end of file diff --git a/src/leetcode/arrays/3sum/Solution.cpp b/src/leetcode/arrays/3sum/Solution.cpp deleted file mode 100644 index 184fa4b..0000000 --- a/src/leetcode/arrays/3sum/Solution.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "Solution.h" -#include -/** - * @brief Complexity - * - Time: O(nlog(n) + n(n-1)) ~ O(n2) - * - Space: O(logn) // sort - */ -std::vector> Solution::threeSum(std::vector& nums) { - std::vector> trips{}; - const size_t size = nums.size(); - if (size < 3) { - return trips; - } - - std::sort(nums.begin(), nums.end()); - - // after sorted, if the smallest number is greater than 0, - // no triplet can sum to zero - if (nums[0] > 0) { - return {}; - } - - for (size_t i = 0; i < size - 2; ++i) { - if (i > 0 && nums[i] == nums[i - 1]) { - // we should not use num[i] == num[i+1] expression because we - // may fall thorough out - continue; // skip duplicates for the 1st - } - - int first = nums[i]; - - // use two pointers to find the 2 remain numbers - size_t j = i + 1; - size_t k = size - 1; - while (j < k) { - int second = nums[j]; - int third = nums[k]; - int sum = first + second + third; - - if (sum == 0) { - trips.push_back({first, second, third}); - - ++j; - --k; - - // move next - while (j < k && nums[j] == nums[j - 1]) { - ++j; // skip duplicates for the 2nd - } - - while (j < k && nums[k] == nums[k + 1]) { - --k; // skip duplicates for the 3rd - } - } else if (sum < 0) { - // require a large sum by increasing the 2nd - ++j; - } else { - // require a smaller sum by decreasing the 3rd - --k; - } - } - } - - return trips; -} diff --git a/src/leetcode/arrays/3sum/Solution.h b/src/leetcode/arrays/3sum/Solution.h deleted file mode 100644 index aa3d3ec..0000000 --- a/src/leetcode/arrays/3sum/Solution.h +++ /dev/null @@ -1,41 +0,0 @@ -//cppcheck-suppress-file [functionStatic,ctuOneDefinitionRuleViolation] - -// 15 - M -// Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] -// such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. - -// Notice that the solution set must not contain duplicate triplets. - -// Example 1: -// Input: nums = [-1,0,1,2,-1,-4] -// Output: [[-1,-1,2],[-1,0,1]] -// Explanation: -// nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0. -// nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0. -// nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0. -// The distinct triplets are [-1,0,1] and [-1,-1,2]. -// Notice that the order of the output and the order of the triplets does not matter. - -// Example 2: -// Input: nums = [0,1,1] -// Output: [] -// Explanation: The only possible triplet does not sum up to 0. - -// Example 3: -// Input: nums = [0,0,0] -// Output: [[0,0,0]] -// Explanation: The only possible triplet sums up to 0. - -// Constraints: -// 3 <= nums.length <= 3000 -// -105 <= nums[i] <= 105 - -#pragma once - -#include -#include - -class Solution { - public: - std::vector> threeSum(std::vector& nums); -}; diff --git a/src/leetcode/arrays/4sum/Solution.cpp b/src/leetcode/arrays/4sum/Solution.cpp deleted file mode 100644 index 78f5f30..0000000 --- a/src/leetcode/arrays/4sum/Solution.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "Solution.h" -#include -#include - -/** - * @brief Complexity - * - Time: O(n3) - * - Space: O(logn) // belong to sort - */ -std::vector> Solution::fourSum(std::vector& nums, - int target) { - size_t size = nums.size(); - if (size < 4) { - return {}; - } - - std::sort(nums.begin(), nums.end()); - - std::vector> result; - for (size_t fI = 0; fI < size - 3; ++fI) { - if (fI > 0 && nums[fI] == nums[fI - 1]) { - continue; - } - - for (size_t sI = fI + 1; sI < size - 2; ++sI) { - if (sI > fI + 1 && nums[sI] == nums[sI - 1]) { - continue; - } - - size_t tI = sI + 1; - size_t frI = size - 1; - while (tI < frI) { - int f = nums[fI]; - int s = nums[sI]; - int t = nums[tI]; - int fr = nums[frI]; - long diff = static_cast(f) + s + t + fr - target; - if (diff == 0) { - result.push_back({f, s, t, fr}); - // Next - ++tI; - --frI; - - while (tI < frI && nums[tI] == nums[tI - 1]) { - ++tI; - } - - while (tI < frI && nums[frI] == nums[frI + 1]) { - --frI; - } - } else if (diff < 0) { - ++tI; - } else { - --frI; - } - } - } - } - - return result; -} diff --git a/src/leetcode/arrays/4sum/Solution.h b/src/leetcode/arrays/4sum/Solution.h deleted file mode 100644 index 5555781..0000000 --- a/src/leetcode/arrays/4sum/Solution.h +++ /dev/null @@ -1,41 +0,0 @@ -//cppcheck-suppress-file [functionStatic,ctuOneDefinitionRuleViolation] - -// 18. 4Sum -// Medium -// Topics -// premium lock icon -// Companies -// Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that: - -// 0 <= a, b, c, d < n -// a, b, c, and d are distinct. -// nums[a] + nums[b] + nums[c] + nums[d] == target -// You may return the answer in any order. - - - -// Example 1: - -// Input: nums = [1,0,-1,0,-2,2], target = 0 -// Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]] -// Example 2: - -// Input: nums = [2,2,2,2,2], target = 8 -// Output: [[2,2,2,2]] - - -// Constraints: - -// 1 <= nums.length <= 200 -// -109 <= nums[i] <= 109 -// -109 <= target <= 109 - -#pragma once - -#include -#include - -class Solution { - public: - std::vector> fourSum(std::vector& nums, int target); -}; diff --git a/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.cpp b/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.cpp deleted file mode 100644 index 9986c05..0000000 --- a/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ContainerWithMostWater.h" - -// /** -// * @brief Complexity -// * Time: O(n^2) -// * Space: O(1) -// */ -// int ContainerWithMostWater::getMaxAmount(const std::vector& height) { -// std::size_t size = height.size(); -// int max{}; -// for (std::size_t i = 0; i < size - 1; ++i) { -// for (std::size_t j = i + 1; j < size; ++j) { -// int w = j - i; -// int h = std::min(height.at(i), height.at(j)); -// max = std::max(max, w * h); -// } -// } - -// return max; -// } - -/** - * @brief Two pointers solution - * Complexity - * Time: O(n) - * Space: O(1) - */ -#include -int ContainerWithMostWater::getMaxAmount(const std::vector& height) { - std::size_t size = height.size(); - if (size < 2) { - return -1; - } - - // size_t index = it - v.begin(); - auto lpos = height.begin(); - auto rpos = height.end() - 1; // end point to the last one e - int result{0}; - while (lpos < rpos) { - int h = std::min(*lpos, *rpos); - int w = static_cast(rpos - lpos); - int t = h * w; - result = std::max(result, t); - - // the height of the container is determined by the shorter position - // so it means we do not need to change the taller one. - if (*lpos < *rpos) { - lpos += 1; - } else { - rpos -= 1; - } - } - - return result; -} \ No newline at end of file diff --git a/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.h b/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.h deleted file mode 100644 index 753591d..0000000 --- a/src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.h +++ /dev/null @@ -1,49 +0,0 @@ -//cppcheck-suppress-file [functionStatic] - -/* 11. Container With Most Water -Medium - -Hint: -You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). -Find two lines that together with the x-axis form a container, such that the container contains the most water. -Return the maximum amount of water a container can store. -Notice that you may not slant the container. - -Example 1: -Input: height = [1,8,6,2,5,4,8,3,7] -Output: 49 -Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. - -Example 2: -Input: height = [1,1] -Output: 1 - -Constraints: -n == height.length -2 <= n <= 105 -0 <= height[i] <= 104 - -==== - ...--................................................................................. - .----........----.......................................---........................... - .-----.......-+#----------------------------------------##------------------.......... - .----........-+#+---------------------------------------##+-------------+#--.......... - .----........-+#+-------##------------------------------##+-------------+#--.......... - ..---........-+#+-------##--------------##+-------------##+-------------+#--.......... - .----........-+#+-------##--------------##+-----##------##+-------------+#--.......... - .----........-+#+-------##--------------##+-----##------##+-----##------+#--.......... - ..---........-+#+-------##------##------##+-----##------##+-----##------+#--.......... - .-------##----+#+-------##------##------##+-----##------##+-----##------+#-------..... - ........0......1.........................................................8............ - -h[1] & h[8] -*/ - -#pragma once - -#include - -class ContainerWithMostWater { - public: - int getMaxAmount(const std::vector& height); -}; \ No newline at end of file diff --git a/src/leetcode/arrays/longest_common_prefix/Solution.cpp b/src/leetcode/arrays/longest_common_prefix/Solution.cpp deleted file mode 100644 index 1e57e16..0000000 --- a/src/leetcode/arrays/longest_common_prefix/Solution.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "Solution.h" -/** - * @brief Complexity - * - Time: O(n*m) - * - Space: O(1) - */ -std::string Solution::longestCommonPrefix( - const std::vector& strs) { - const std::string& str_benchmark = - strs.at(0); // use 1st string as a benchmark - - // Iterator charactor-by-charator over the first string - // to compare it against all other strings - for (size_t i = 0; i < str_benchmark.size(); ++i) { - char c = str_benchmark.at(i); - for (size_t j = 1; j < strs.size(); ++j) { - const std::string& str = strs.at(j); - if (i >= str.size() || c != str.at(i)) { - return str_benchmark.substr(0, i); - } - } - } - - return str_benchmark; -} diff --git a/src/leetcode/arrays/longest_common_prefix/Solution.h b/src/leetcode/arrays/longest_common_prefix/Solution.h deleted file mode 100644 index 3c66e1c..0000000 --- a/src/leetcode/arrays/longest_common_prefix/Solution.h +++ /dev/null @@ -1,32 +0,0 @@ -//cppcheck-suppress-file [functionStatic,ctuOneDefinitionRuleViolation] - -// 14 - E -// Write a function to find the longest common prefix string amongst an array of strings. -// If there is no common prefix, return an empty string "". -// Example 1: - -// Input: strs = ["flower","flow","flight"] -// Output: "fl" -// Example 2: - -// Input: strs = ["dog","racecar","car"] -// Output: "" -// Explanation: There is no common prefix among the input strings. - -// Constraints: - -// 1 <= strs.length <= 200 -// 0 <= strs[i].length <= 200 -// strs[i] consists of only lowercase English letters if it is non-empty. - -// Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity ? - -#pragma once - -#include -#include - -class Solution { - public: - std::string longestCommonPrefix(const std::vector& strs); -}; diff --git a/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.cpp b/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.cpp deleted file mode 100644 index ffbe271..0000000 --- a/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "MedianTwoSortedArrays.h" -#include - -/** - * Time Complexity: O((m+n) + (m+n)log(m+n)) ~ O((m+n)log(m+n)) - * Space Complexity: O(n+m) - */ -double MedianTwoSortedArrays::findMedianSortedArrays( - const std::vector& nums1, const std::vector& nums2) { - std::vector nums{}; - nums.reserve( - nums1.size() + - nums2.size()); // should use reserve to pre-allocate the required mem - - nums.insert(nums.end(), nums1.begin(), - nums1.end()); // insert: copy n + m => O(m+n) - nums.insert(nums.end(), nums2.begin(), nums2.end()); - - std::sort(nums.begin(), nums.end()); // sort: NLogN => (m+n)Log(m+n) - - size_t size = nums.size(); - if (size == 0) { - return -1; - } - - if (size % 2 != 0) { - int index = - size / - 2; // integer division truncates toward zero, so size / 2 gives the lower middle index - return nums.at(index); - } else { - int index1 = size / 2; - int index2 = size / 2 - 1; - int sum = nums.at(index1) + nums.at(index2); - return sum / 2.0; - } -} \ No newline at end of file diff --git a/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.h b/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.h deleted file mode 100644 index d532e48..0000000 --- a/src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.h +++ /dev/null @@ -1,32 +0,0 @@ - -//cppcheck-suppress-file [functionStatic] -#pragma once -// Hard - -// Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. -// The overall run time complexity should be O(log (m+n)). - -// Example 1: -// Input: nums1 = [1,3], nums2 = [2] -// Output: 2.00000 -// Explanation: merged array = [1,2,3] and median is 2. - -// Example 2: -// Input: nums1 = [1,2], nums2 = [3,4] -// Output: 2.50000 -// Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. - -// Constraints: -// nums1.length == m -// nums2.length == n -// 0 <= m <= 1000 -// 0 <= n <= 1000 -// 1 <= m + n <= 2000 -// -106 <= nums1[i], nums2[i] <= 106 - -#include -class MedianTwoSortedArrays { - public: - double findMedianSortedArrays(const std::vector& nums1, - const std::vector& nums2); -}; \ No newline at end of file diff --git a/src/leetcode/arrays/two_sum/TwoSum.cpp b/src/leetcode/arrays/two_sum/TwoSum.cpp deleted file mode 100644 index b6c73c3..0000000 --- a/src/leetcode/arrays/two_sum/TwoSum.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "TwoSum.h" - -/** - * S1: Using for-loop-index - * Time complexity: O(n2) - * Space complexity: O(1) - */ -std::vector Solution::twoSum(const std::vector& nums, int target) { - for (int i = 0; i < nums.size(); ++i) { - int diff = target - nums.at(i); - for (int j = i + 1; j < nums.size(); ++j) { - if (diff == nums.at(j)) { - return std::vector{i, j}; - } - } - } - - // no solution - return std::vector{-1, -1}; -} - -// #include -// /** -// * 3 1 4 -// * ===== -// * 3 1 4 -// * ----- -// * 0 1 2 -// * ===== -// * Time complexity: O(n) -// * Space complexity: O(n) -// */ -// std::vector Solution::twoSum(const std::vector& nums, int target) { -// std::unordered_map numMap{}; -// for (int i = 0; i < nums.size(); ++i) { -// int xkey = nums[i]; -// int ykey = target - nums[i]; -// if (numMap.find(ykey) != nullptr) { -// return std::vector{numMap.at(ykey), i}; -// } - -// // save vector to map -// numMap.insert(std::pair(xkey, i)); -// } - -// // no solution -// return std::vector{-1, -1}; -// } diff --git a/src/leetcode/arrays/two_sum/TwoSum.h b/src/leetcode/arrays/two_sum/TwoSum.h deleted file mode 100644 index 78fba08..0000000 --- a/src/leetcode/arrays/two_sum/TwoSum.h +++ /dev/null @@ -1,34 +0,0 @@ -//cppcheck-suppress-file [functionStatic] - -// Given an array of integers nums and an integer target, return indices[ˈɪn.də.siːz] of the two numbers such that they add up to target. - -// You may assume that each input would have exactly one solution, and you may not use the same element twice. -// You can return the answer in any order. - -// Example 1: -// Input: nums = [2,7,11,15], target = 9 -// Output: [0,1] -// Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]. - -// Example 2: -// Input: nums = [3,2,4], target = 6 -// Output: [1,2] - -// Example 3: -// Input: nums = [3,3], target = 6 -// Output: [0,1] - -// Constraints: -// 2 <= nums.length <= 104 -// -109 <= nums[i] <= 109 -// -109 <= target <= 109 -// Only one valid answer exists. - -// Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity ? - -#pragma once -#include -class Solution { - public: - std::vector twoSum(const std::vector& nums, int target); -}; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0d76665..2b07b48 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,12 +12,6 @@ set(SOURCES set(TEST_SOURCES DeleteMeTest.cpp - two_sum_ut.cpp - median_two_sorted_arrays_ut.cpp - container_with_most_water_ut.cpp - longest_common_prefix_ut.cpp - three_sum_ut.cpp - four_sum_ut.cpp ) # Build the test executable @@ -39,7 +33,6 @@ target_include_directories(${PROJECT_NAME_TEST} # Link GoogleTest and GoogleMock target_link_libraries(${PROJECT_NAME_TEST} - leetcode GTest::gtest_main GTest::gmock_main ) diff --git a/tests/container_with_most_water_ut.cpp b/tests/container_with_most_water_ut.cpp deleted file mode 100644 index 296e6f8..0000000 --- a/tests/container_with_most_water_ut.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "../src/leetcode/arrays/container_with_most_water/ContainerWithMostWater.h" - -TEST(ContainerWithMostWater, TC1) { - std::vector height{1, 8, 6, 2, 5, 4, 8, 3, 7}; - int expected = 49; - ContainerWithMostWater solution{}; - EXPECT_EQ(expected, solution.getMaxAmount(height)); -} - -TEST(ContainerWithMostWater, TC2) { - std::vector height{1, 1}; - int expected = 1; - ContainerWithMostWater solution{}; - EXPECT_EQ(expected, solution.getMaxAmount(height)); -} \ No newline at end of file diff --git a/tests/four_sum_ut.cpp b/tests/four_sum_ut.cpp deleted file mode 100644 index 8b9bbeb..0000000 --- a/tests/four_sum_ut.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "../src/leetcode/arrays/4sum/Solution.h" - -// Create a struct for our tcs -struct FourSumCase { - int target; - std::vector numsInput; - std::vector> expected; -}; - -// Param Test Fixture -class FourSumTest : public ::testing::TestWithParam {}; - -// Test Data -INSTANTIATE_TEST_SUITE_P( - BasicTestCases, FourSumTest, - ::testing::Values( - FourSumCase{0, - {1, 0, -1, 0, -2, 2}, - {{-2, -1, 1, 2}, {-2, 0, 0, 2}, {-1, 0, 0, 1}}}, - FourSumCase{0, - {-2, -1, -1, 1, 1, 2, 2}, - {{-2, -1, 1, 2}, {-1, -1, 1, 1}}}, - FourSumCase{3, {-3, -4, -5, 0, -5, -2, 5, 2, -3}, {{-4, 0, 2, 5}}}, - FourSumCase{-294967296, - {1000000000, 1000000000, 1000000000, 1000000000}, - {}}, - FourSumCase{8, {2, 2, 2, 2, 2}, {{2, 2, 2, 2}}})); - -TEST_P(FourSumTest, ReturnCorrectValues) { - const auto& tc = GetParam(); // get the test case from test suit - Solution s{}; - auto nums = tc.numsInput; - auto target = tc.target; - EXPECT_EQ(s.fourSum(nums, target), tc.expected); -} diff --git a/tests/longest_common_prefix_ut.cpp b/tests/longest_common_prefix_ut.cpp deleted file mode 100644 index 6af8255..0000000 --- a/tests/longest_common_prefix_ut.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "../src/leetcode/arrays/longest_common_prefix/Solution.h" - -TEST(LongestCommonPrefix, TC1) { - std::vector strs{"flower", "flow", "flight"}; - std::string expected{"fl"}; - Solution s{}; - EXPECT_EQ(expected, s.longestCommonPrefix(strs)); -} - -TEST(LongestCommonPrefix, TC2) { - std::vector strs{"dog","racecar","car"}; - std::string expected{""}; - Solution s{}; - EXPECT_EQ(expected, s.longestCommonPrefix(strs)); -} - - -TEST(LongestCommonPrefix, TC3) { - std::vector strs{"a"}; - std::string expected{"a"}; - Solution s{}; - EXPECT_EQ(expected, s.longestCommonPrefix(strs)); -} - -TEST(LongestCommonPrefix, TC4) { - std::vector strs{"ab","a"}; - std::string expected{"a"}; - Solution s{}; - EXPECT_EQ(expected, s.longestCommonPrefix(strs)); -} \ No newline at end of file diff --git a/tests/median_two_sorted_arrays_ut.cpp b/tests/median_two_sorted_arrays_ut.cpp deleted file mode 100644 index f95d7ec..0000000 --- a/tests/median_two_sorted_arrays_ut.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include "../src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.h" - -TEST(MedianTwoSortedArrays, TC1) { - std::vector nums1{1, 2}; - std::vector nums2{3}; - double expected{2.0}; - - MedianTwoSortedArrays s{}; - - EXPECT_EQ(expected, s.findMedianSortedArrays(nums1, nums2)); -} - -TEST(MedianTwoSortedArrays, TC2) { - std::vector nums1{1, 2}; - std::vector nums2{3, 3}; - double expected{2.5}; - - MedianTwoSortedArrays s{}; - - EXPECT_EQ(expected, s.findMedianSortedArrays(nums1, nums2)); -} \ No newline at end of file diff --git a/tests/three_sum_ut.cpp b/tests/three_sum_ut.cpp deleted file mode 100644 index 11c9ebf..0000000 --- a/tests/three_sum_ut.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include "../src/leetcode/arrays/3sum/Solution.h" - -using ::testing::ElementsAre; -using ::testing::UnorderedElementsAre; - -/** - * Test case definition - */ -struct ThreeSumCase { - std::vector input; - std::vector> expected; -}; - -/** - * Parameterized test fixture - */ -class ThreeSumTest : public ::testing::TestWithParam {}; - -/** - * Main test - * - * Note: - * - Order of triplets does NOT matter - * - Order inside each triplet DOES matter (sorted by implementation) - */ -TEST_P(ThreeSumTest, ReturnsCorrectTriplets) { - const auto& tc = GetParam(); - Solution s{}; - - auto nums = tc.input; - auto result = s.threeSum(nums); - - std::vector<::testing::Matcher>> matchers; - for (const auto& triplet : tc.expected) { - matchers.push_back(ElementsAre(triplet[0], triplet[1], triplet[2])); - } - - EXPECT_THAT(result, UnorderedElementsAreArray(matchers)); -} - -/** - * Test data - */ -INSTANTIATE_TEST_SUITE_P( - BasicAndEdgeCases, ThreeSumTest, - ::testing::Values(ThreeSumCase{{}, {}}, ThreeSumCase{{1}, {}}, - ThreeSumCase{{1, 2}, {}}, ThreeSumCase{{1, 2, 3}, {}}, - ThreeSumCase{{2, 1, 3}, {}}, ThreeSumCase{{0, 1, 1}, {}}, - ThreeSumCase{{-5, -4, -3, -2}, {}}, - ThreeSumCase{{1, 2, 3, 4}, {}}, - - ThreeSumCase{{-1, 0, 1, 2, -1, -4}, - {{-1, -1, 2}, {-1, 0, 1}}}, - - ThreeSumCase{{0, 0, 0}, {{0, 0, 0}}}, - - ThreeSumCase{{0, 0, 0, 0}, {{0, 0, 0}}}, - - ThreeSumCase{{1, 2, 0, 1, 0, 0, 0, 0}, {{0, 0, 0}}}, - - ThreeSumCase{{-2, 0, 0, 2, 2}, {{-2, 0, 2}}})); - -/** - * Extra safety test: - * ensure no duplicate triplets are returned - */ -TEST(ThreeSumExtra, NoDuplicateTriplets) { - std::vector nums{-2, 0, 0, 2, 2}; - Solution s{}; - - auto result = s.threeSum(nums); - - ASSERT_EQ(result.size(), 1); - EXPECT_EQ(result[0], std::vector({-2, 0, 2})); -} diff --git a/tests/two_sum_ut.cpp b/tests/two_sum_ut.cpp deleted file mode 100644 index aee0d17..0000000 --- a/tests/two_sum_ut.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "../src/leetcode/arrays/two_sum/TwoSum.h" - -struct TestCase { - std::vector nums; - int target; - std::vector expected; -}; - -TEST(TwoSum, TC1) { - TestCase tc = {.nums{2, 7, 11, 15}, .target{9}, .expected{0, 1}}; - Solution s{}; - - EXPECT_EQ(tc.expected, s.twoSum(tc.nums, tc.target)); -} - -TEST(TwoSum, TC2) { - TestCase tc = {.nums{3, 2, 4}, .target{6}, .expected{1, 2}}; - Solution s{}; - - EXPECT_EQ(tc.expected, s.twoSum(tc.nums, tc.target)); -} - -TEST(TwoSum, TC3) { - TestCase tc = {.nums{3, 3}, .target{6}, .expected{0, 1}}; - Solution s{}; - - EXPECT_EQ(tc.expected, s.twoSum(tc.nums, tc.target)); -} - -TEST(TwoSum, TC4) { - TestCase tc = {.nums{3, 3}, .target{0}, .expected{-1, -1}}; - Solution s{}; - - EXPECT_EQ(tc.expected, s.twoSum(tc.nums, tc.target)); -} \ No newline at end of file