Skip to content

Commit 9938e3a

Browse files
committed
week 14
1 parent 31b9dab commit 9938e3a

File tree

14 files changed

+199
-1
lines changed

14 files changed

+199
-1
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ include_directories(shared)
6262

6363

6464
##### subdirectories #####
65-
set(DIRS week-W week-2 week-3 week-4 week-5 week-6 week-7 week-8 week-9 week-10 week-11)
65+
set(DIRS week-W week-2 week-3 week-4 week-5 week-6 week-7 week-8 week-9 week-10 week-11 week-14)
6666
foreach(DIR ${DIRS})
6767
add_subdirectory(${DIR})
6868
endforeach()

week-14/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
set(DIRS task-12-06 task-12-07 task-12-08)
2+
foreach(DIR ${DIRS})
3+
add_subdirectory(${DIR})
4+
endforeach()

week-14/task-12-06/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
3+
add_subdirectory(test)
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
#include <iterator>
4+
#include <ranges>
5+
#include <string>
6+
#include <algorithm>
7+
8+
namespace my_algorithms {
9+
10+
void title_case(std::string& str) {
11+
std::ranges::transform(
12+
std::views::zip(str, std::views::iota(0)), str.begin(), [&](auto&& pair) {
13+
auto [c, idx] = pair;
14+
return (idx == 0 || std::isspace(str[idx - 1])) ? std::toupper(c) : std::tolower(c);
15+
});
16+
}
17+
18+
} // namespace my_algorithms
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp_test(test-12-06.cpp)
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "gtest/gtest.h"
2+
#include "title_case.hpp"
3+
4+
using my_algorithms::title_case;
5+
6+
TEST(TitleCaseTest, HandlesEmptyString) {
7+
std::string str;
8+
title_case(str);
9+
EXPECT_EQ(str, "");
10+
}
11+
12+
TEST(TitleCaseTest, HandlesSingleWord) {
13+
std::string str = "hello";
14+
title_case(str);
15+
EXPECT_EQ(str, "Hello");
16+
}
17+
18+
TEST(TitleCaseTest, HandlesMultipleWords) {
19+
std::string str = "heLLo, woRLD";
20+
title_case(str);
21+
EXPECT_EQ(str, "Hello, World");
22+
}
23+
24+
TEST(TitleCaseTest, HandlesLeadingAndTrailingSpaces) {
25+
std::string str = " test CASE ";
26+
title_case(str);
27+
EXPECT_EQ(str, " Test Case ");
28+
}
29+
30+
TEST(TitleCaseTest, HandlesMixedCaseWithNumbers) {
31+
std::string str = "1st plaCE";
32+
title_case(str);
33+
EXPECT_EQ(str, "1st Place");
34+
}
35+
36+
TEST(TitleCaseTest, HandlesAllUppercase) {
37+
std::string str = "ALL UPPER";
38+
title_case(str);
39+
EXPECT_EQ(str, "All Upper");
40+
}

week-14/task-12-07/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
3+
add_subdirectory(test)

week-14/task-12-07/include/join.hpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
namespace my_algorithm {
4+
5+
template <std::ranges::forward_range Range>
6+
requires requires {
7+
requires std::convertible_to<std::ranges::range_value_t<Range>, std::string_view>;
8+
}
9+
std::string join(const Range& strings, const std::string& delimiter) {
10+
std::string res;
11+
for (auto it = std::begin(strings); it != std::end(strings); ++it) {
12+
if (it != std::begin(strings)) {
13+
res += delimiter;
14+
}
15+
res += *it;
16+
}
17+
return res;
18+
}
19+
20+
} // namespace my_algorithm
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp_test(test-12-07.cpp)
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <list>
2+
#include <vector>
3+
4+
#include "gtest/gtest.h"
5+
#include "join.hpp"
6+
7+
using my_algorithm::join;
8+
9+
TEST(JoinTest, HandlesEmptyRange) {
10+
const std::vector<std::string> empty_vec;
11+
EXPECT_EQ(join(empty_vec, ","), "");
12+
}
13+
14+
TEST(JoinTest, HandlesSingleString) {
15+
const std::list<std::string> single = {"hello"};
16+
EXPECT_EQ(join(single, " "), "hello");
17+
}
18+
19+
TEST(JoinTest, JoinsMultipleStrings) {
20+
const std::vector<std::string> strings = {"a", "b", "c"};
21+
EXPECT_EQ(join(strings, ","), "a,b,c");
22+
}
23+
24+
TEST(JoinTest, WorksWithStringView) {
25+
const std::vector<std::string_view> sv = {"x", "y", "z"};
26+
EXPECT_EQ(join(sv, "->"), "x->y->z");
27+
}
28+
29+
TEST(JoinTest, HandlesMultiCharDelimiter) {
30+
const std::vector<std::string> strings = {"1", "2", "3"};
31+
EXPECT_EQ(join(strings, "###"), "1###2###3");
32+
}
33+
34+
TEST(JoinTest, WorksWithNonOwningTypes) {
35+
const char* cstrings[] = {"quick", "brown", "fox"};
36+
EXPECT_EQ(join(cstrings, "..."), "quick...brown...fox");
37+
}

week-14/task-12-08/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
3+
add_subdirectory(test)
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <unordered_set>
4+
5+
namespace my_algorithm {
6+
7+
std::vector<std::string> tokenize(const std::string& str,
8+
const std::unordered_set<char>& delimiters) {
9+
std::vector<std::string> tokens;
10+
auto start = str.begin();
11+
auto end = str.end();
12+
while (start != end) {
13+
while (start != end && delimiters.contains(*start)) {
14+
++start;
15+
}
16+
auto token_end = start;
17+
while (token_end != end && !delimiters.contains(*token_end)) {
18+
++token_end;
19+
}
20+
if (start != token_end) {
21+
tokens.emplace_back(start, token_end);
22+
}
23+
start = token_end;
24+
}
25+
return tokens;
26+
}
27+
28+
} // namespace my_algorithm
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp_test(test-12-08.cpp)
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "gtest/gtest.h"
2+
#include "tokenize.hpp"
3+
4+
using my_algorithm::tokenize;
5+
6+
TEST(TokenizeTest, HandlesEmptyString) {
7+
EXPECT_EQ(tokenize("", {' ', ','}), std::vector<std::string>({}));
8+
}
9+
10+
TEST(TokenizeTest, HandlesNoDelimiters) {
11+
EXPECT_EQ(tokenize("hello", {}), std::vector<std::string>({"hello"}));
12+
}
13+
14+
TEST(TokenizeTest, SingleDelimiterBetweenTokens) {
15+
EXPECT_EQ(tokenize("a,b,c", {','}), std::vector<std::string>({"a", "b", "c"}));
16+
}
17+
18+
TEST(TokenizeTest, MultipleDelimitersBetweenTokens) {
19+
EXPECT_EQ(tokenize("hello, world!how?are.you", {' ', ',', '!', '?', '.'}),
20+
std::vector<std::string>({"hello", "world", "how", "are", "you"}));
21+
}
22+
23+
TEST(TokenizeTest, LeadingAndTrailingDelimiters) {
24+
EXPECT_EQ(tokenize(" ,,test,,case,, ", {' ', ','}),
25+
std::vector<std::string>({"test", "case"}));
26+
}
27+
28+
TEST(TokenizeTest, ConsecutiveDelimiters) {
29+
EXPECT_EQ(tokenize("a,, ,b", {',', ' '}), std::vector<std::string>({"a", "b"}));
30+
}
31+
32+
TEST(TokenizeTest, MixedDelimitersAndNoTokens) {
33+
EXPECT_EQ(tokenize(", , ,", {',', ' '}), std::vector<std::string>({}));
34+
}
35+
36+
TEST(TokenizeTest, ComplexRealWorldCase) {
37+
EXPECT_EQ(tokenize(" John;Doe,42;New York;USA ", {' ', ',', ';'}),
38+
std::vector<std::string>({"John", "Doe", "42", "New", "York", "USA"}));
39+
}

0 commit comments

Comments
 (0)