Skip to content

Commit e45d60e

Browse files
Merge pull request #15 from DoctorLai/ranges-find-in-vector-string
Different ways to find an element in a vector string
2 parents 3e82a2b + e155813 commit e45d60e

File tree

5 files changed

+203
-1
lines changed

5 files changed

+203
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Examples include (and will expand to):
2626
* Parallelism
2727
* [parallel-transform](./parallel-transform/)
2828
* Performance‑oriented C++ idioms
29+
* STL and ranges:
30+
* [ranges-find-in-vector-string](./ranges-find-in-vector-string/)
2931
* Algorithms
3032
* [integer-factorization](./integer-factorization/)
3133
* Encoding

map-with-unknown-key/main.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,48 @@ What happens if you access an unknown key in the std::map, std::unordered_map?
33
*/
44
#include <iostream>
55
#include <map>
6+
#include <unordered_map>
67
#include <string>
7-
#include <format>
88
#include <print>
9+
#include <cassert>
910

1011
int
1112
main()
1213
{
14+
// Example with std::map value type int
1315
std::map<std::string, int> my_map;
1416
std::print("Accessing unknown key 'unknown_key' in std::map:\n");
1517
int value = my_map["unknown_key"];
1618
std::print("Value: {}\n", value); // Should print 0, as default-constructed int is 0
1719
std::print("Map size after access: {}\n", my_map.size()); // Should print 1
20+
assert(value == 0); // Default-constructed int is 0
21+
assert(my_map.size() == 1); // The map now contains one entry for 'unknown_key'
22+
23+
// Example with std::unordered_map value type int
24+
std::unordered_map<std::string, int> my_unordered_map;
25+
std::print("Accessing unknown key 'unknown_key' in std::unordered_map:\n");
26+
int unordered_value = my_unordered_map["unknown_key"];
27+
std::print("Value: {}\n", unordered_value); // Should print 0
28+
std::print("Unordered map size after access: {}\n", my_unordered_map.size()); // Should print 1
29+
assert(unordered_value == 0); // Default-constructed int is 0
30+
assert(my_unordered_map.size() == 1); // The unordered_map now contains one entry for 'unknown_key'
31+
32+
// Example with std::map value type std::string
33+
std::map<std::string, std::string> my_string_map;
34+
std::print("Accessing unknown key 'unknown_key' in std::map with string values:\n");
35+
std::string str_value = my_string_map["unknown_key"];
36+
std::print("Value: '{}'\n", str_value); // Should print empty string
37+
std::print("Map size after access: {}\n", my_string_map.size()); // Should print 1
38+
assert(str_value.empty()); // Default-constructed string is empty
39+
assert(my_string_map.size() == 1); // The map now contains one entry for
40+
41+
// Example with std::unordered_map value type std::string
42+
std::unordered_map<std::string, std::string> my_string_unordered_map;
43+
std::print("Accessing unknown key 'unknown_key' in std::unordered_map with string values:\n");
44+
std::string str_unordered_value = my_string_unordered_map["unknown_key"];
45+
std::print("Value: '{}'\n", str_unordered_value); // Should print empty string
46+
std::print("Unordered map size after access: {}\n", my_string_unordered_map.size()); // Should print 1
47+
assert(str_unordered_value.empty()); // Default-constructed string is empty
48+
assert(my_string_unordered_map.size() == 1); // The unordered_map now contains one entry for 'unknown_key'
1849
return 0;
1950
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# pull in shared compiler settings
2+
include ../common.mk
3+
4+
# per-example flags
5+
# CXXFLAGS += -pthread
6+
7+
## get it from the folder name
8+
TARGET := $(notdir $(CURDIR))
9+
## all *.cpp files in this folder
10+
SRCS := $(wildcard *.cpp)
11+
OBJS := $(SRCS:.cpp=.o)
12+
13+
all: $(TARGET)
14+
15+
$(TARGET): $(OBJS)
16+
$(CXX) $(CXXFLAGS) -o $@ $^
17+
18+
%.o: %.cpp
19+
$(CXX) $(CXXFLAGS) -c $< -o $@
20+
21+
run: $(TARGET)
22+
./$(TARGET) $(ARGS)
23+
24+
clean:
25+
rm -f $(OBJS) $(TARGET)
26+
27+
# Delegates to top-level Makefile
28+
check-format:
29+
$(MAKE) -f ../Makefile check-format DIR=$(CURDIR)
30+
31+
.PHONY: all clean run check-format
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/**
2+
This demonstrates different ways to find an element in a vector of strings
3+
*/
4+
#include <iostream>
5+
#include <vector>
6+
#include <string>
7+
#include <print>
8+
#include <cassert>
9+
#include <ranges>
10+
#include <algorithm>
11+
12+
int
13+
main()
14+
{
15+
std::vector<std::string> vec = {"apple", "banana", "cherry", "date", "elderberry"};
16+
std::string target = "cherry";
17+
18+
// Method 1: Using a loop
19+
bool found = false;
20+
for (size_t i = 0; i < vec.size(); ++i) {
21+
if (vec[i] == target) {
22+
std::print("loop: Found '{}' using loop at index {}\n", target, i);
23+
found = true;
24+
break;
25+
}
26+
}
27+
if (!found) {
28+
std::print("loop: '{}' not found using loop\n", target);
29+
}
30+
31+
// Method 2: Using std::find_if with a lambda
32+
auto it_if = std::find_if(vec.begin(), vec.end(), [&target](const std::string& s) { return s == target; });
33+
if (it_if != vec.end()) {
34+
std::print(
35+
"std::find_if: Found '{}' using std::find_if at index {}\n", target, std::distance(vec.begin(), it_if));
36+
} else {
37+
std::print("std::find_if: '{}' not found using std::find_if\n", target);
38+
}
39+
40+
// Method 3: Using std::find
41+
auto it = std::find(vec.begin(), vec.end(), target);
42+
if (it != vec.end()) {
43+
std::print("std::find: Found '{}' using std::find at index {}\n", target, std::distance(vec.begin(), it));
44+
} else {
45+
std::print("std::find: '{}' not found using std::find\n", target);
46+
}
47+
48+
// Method 4: std::count (pre C++20)
49+
auto count_std = std::count(vec.begin(), vec.end(), target);
50+
std::print("std::count: Vector contains '{}' {} time(s) using std::count\n", target, count_std);
51+
52+
// Method 5: std::count_if (pre C++20)
53+
auto count_if_std = std::count_if(vec.begin(), vec.end(), [&target](const std::string& s) { return s == target; });
54+
std::print("std::count_if: Vector contains '{}' {} time(s) using std::count_if\n", target, count_if_std);
55+
56+
// Method 6: std::any_of
57+
bool any_of_std = std::any_of(vec.begin(), vec.end(), [&target](const std::string& s) { return s == target; });
58+
if (any_of_std) {
59+
std::print("std::any_of: Vector contains '{}' using std::any_of\n", target);
60+
} else {
61+
std::print("std::any_of: Vector does not contain '{}' using std::any_of\n", target);
62+
}
63+
64+
// Method 7: Using std::ranges::find (C++20)
65+
auto range_it = std::ranges::find(vec, target);
66+
if (range_it != vec.end()) {
67+
std::print(
68+
"std::ranges::find: Found '{}' using std::ranges::find at index {}\n",
69+
target,
70+
std::distance(vec.begin(), range_it));
71+
} else {
72+
std::print("std::ranges::find: '{}' not found using std::ranges::find\n", target);
73+
}
74+
75+
// Method 8: Using std::ranges::find_if with a lambda (C++20)
76+
auto range_it_if = std::ranges::find_if(vec, [&target](const std::string& s) { return s == target; });
77+
if (range_it_if != vec.end()) {
78+
std::print(
79+
"std::ranges::find_if: Found '{}' using std::ranges::find_if at index {}\n",
80+
target,
81+
std::distance(vec.begin(), range_it_if));
82+
} else {
83+
std::print("std::ranges::find_if: '{}' not found using std::ranges::find_if\n", target);
84+
}
85+
86+
// Method 9: std::ranges::contains (C++23)
87+
auto contains = std::ranges::contains(vec, target);
88+
if (contains) {
89+
std::print("std::ranges::contains: Vector contains '{}' using std::ranges::contains\n", target);
90+
} else {
91+
std::print("std::ranges::contains: Vector does not contain '{}' using std::ranges::contains\n", target);
92+
}
93+
94+
// Method 10: std::ranges::any_of (C++20)
95+
bool any_of = std::ranges::any_of(vec, [&target](const std::string& s) { return s == target; });
96+
if (any_of) {
97+
std::print("std::ranges::any_of: Vector contains '{}' using std::ranges::any_of\n", target);
98+
} else {
99+
std::print("std::ranges::any_of: Vector does not contain '{}' using std::ranges::any_of\n", target);
100+
}
101+
102+
// Method 11: std::ranges::count (C++20)
103+
auto count = std::ranges::count(vec, target);
104+
std::print("std::ranges::count: Vector contains '{}' {} time(s) using std::ranges::count\n", target, count);
105+
106+
// Method 12: std::ranges::count_if (C++20)
107+
auto count_if = std::ranges::count_if(vec, [&target](const std::string& s) { return s == target; });
108+
std::print(
109+
"std::ranges::count_if: Vector contains '{}' {} time(s) using std::ranges::count_if\n", target, count_if);
110+
111+
// Method 13: via std::ranges::views (C++20)
112+
auto view = vec | std::ranges::views::filter([&target](const std::string& s) { return s == target; });
113+
for (const auto& s : view) {
114+
std::print("std::ranges::views::filter: Found '{}' using std::ranges::views::filter\n", s);
115+
}
116+
117+
// Assertions to verify correctness
118+
assert(it != vec.end() && *it == target);
119+
assert(found);
120+
assert(range_it != vec.end() && *range_it == target);
121+
assert(it_if != vec.end() && *it_if == target);
122+
assert(range_it_if != vec.end() && *range_it_if == target);
123+
assert(contains);
124+
assert(any_of);
125+
assert(count == 1);
126+
assert(count_std == 1);
127+
assert(count_if == 1);
128+
assert(count_if_std == 1);
129+
assert(std::ranges::distance(view) == 1);
130+
assert(any_of_std);
131+
132+
return 0;
133+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
set -ex
4+
5+
./ranges-find-in-vector-string

0 commit comments

Comments
 (0)