Skip to content

Instantly share code, notes, and snippets.

@DragonOsman
Created January 18, 2022 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DragonOsman/1a83c244118266e4bcf85a2df730b078 to your computer and use it in GitHub Desktop.
Save DragonOsman/1a83c244118266e4bcf85a2df730b078 to your computer and use it in GitHub Desktop.
// Osman Zakir
// 1 / 18 / 2022
// Beginning C++20: From Novice to Professional by Ivor Horton and Peter Van Weert
// Chapter 11 Exercise 3
// Exercise Specs:
/**
* Split the insanely large words module of Exercise 11-2 into two aptly
* named submodules: one submodule containing all sorting functionality, and one
* containing any remaining utilities (or utils, in programmer’s speak). Also put your
* functions in nested namespaces whose names mirror those of the submodules.
*/
import <iostream>;
import <string>;
import words;
int main()
{
using namespace std::string_literals;
words::Words words;
std::string text;
const auto separators{ " ,.!?\"\n"s };
std::cout << "Enter a string terminated by *:\n";
std::getline(std::cin, text, '*');
words::utils::extract_words(words, text, separators);
if (words.empty())
{
std::cout << "No words in text." << std::endl;
return 0;
}
words::sorting::sort(words);
words::utils::show_words(words);
}
export module words;
import <iostream>;
import <memory>;
import <string>;
import <vector>;
namespace words
{
export using Words = std::vector<std::shared_ptr<std::string>>;
}
export import words.sorting;
export import words.utils;
module words.sorting;
import <iostream>;
import <memory>;
import <string>;
import <vector>;
void swap(words::Words& words, std::size_t first, std::size_t second)
{
auto temp{ words[first] };
words[first] = words[second];
words[second] = temp;
}
void sort(words::Words& words, std::size_t start, std::size_t end)
{
// start index must be less than end index for 2 or more elements
if (!(start < end))
{
return;
}
// Choose middle address to partition set
// And swap middle address with start
swap(words, start, (start + end) / 2);
std::size_t current{ start };
for (std::size_t i{ start + 1 }; i <= end; i++)
{
// Is word word less than chosen word?
if (*words[i] < *words[start])
{
// Yes, so swap to the left
swap(words, ++current, i);
}
}
// Swap chosen and last swapped words
swap(words, start, current);
// Sort left subset if exists
if (current > start)
{
sort(words, start, current - 1);
}
// Sort right subset if exists
if (end > current + 1)
{
sort(words, current + 1, end);
}
}
void words::sorting::sort(Words& words)
{
if (!words.empty())
{
::sort(words, 0, words.size() - 1);
}
}
export module words.sorting;
import <iostream>;
import <memory>;
import <string>;
import <vector>;
namespace words
{
export using Words = std::vector<std::shared_ptr<std::string>>;
namespace sorting
{
export void sort(Words& words);
}
}
module words.utils;
import <iostream>;
import <format>;
import <memory>;
import <string>;
import <vector>;
std::size_t max_word_length(const words::Words& words)
{
std::size_t max{};
for (auto& pword : words)
{
if (max < pword->length())
{
max = pword->length();
}
}
return max;
}
void words::utils::extract_words(Words& words, const std::string& text,
const std::string& separators)
{
std::size_t start{ text.find_first_not_of(separators) };
while (start != std::string::npos)
{
std::size_t end = text.find_first_of(separators, start + 1);
if (end == std::string::npos)
{
end = text.length();
}
words.push_back(std::make_shared<std::string>(text.substr(start, end - start)));
start = text.find_first_not_of(separators, end + 1);
}
}
void words::utils::show_words(const Words& words)
{
const std::size_t field_width{ max_word_length(words) + 1 };
const std::size_t words_per_line{ 8 };
std::cout << std::format("{:{}}", *words[0], field_width);
std::size_t words_in_line{};
for (std::size_t i{ 1 }; i < words.size(); ++i)
{ // Output newline when initial letter changes or after 8 per line
if ((*words[i])[0] != (*words[i - 1])[0] || ++words_in_line == words_per_line)
{
words_in_line = 0;
std::cout << std::endl;
}
std::cout << std::format("{:{}}", *words[i], field_width);
}
std::cout << std::endl;
}
export module words.utils;
import <iostream>;
import <memory>;
import <string>;
import <vector>;
namespace words
{
export using Words = std::vector<std::shared_ptr<std::string>>;
namespace utils
{
export void extract_words(Words& words, const std::string& text,
const std::string& separators);
export void show_words(const Words& words);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment