diff --git a/README.md b/README.md index e4b1a8e..e9d3208 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,14 @@ This repository contains the LaTeX source and C++ code samples for the book "A Complete Guide to Standard C++ Algorithms". -[Latest PDF release (v0.3.0)](https://github.com/HappyCerberus/book-cpp-algorithms/releases/download/v0.3.0/book_with_cover_v0.3.0.pdf) +[Latest PDF release (v1.0.1)](https://github.com/HappyCerberus/book-cpp-algorithms/releases/download/v1.0.1/a_complete_guide_to_standard_cpp_algorithms_v1_0_1.pdf) -[![Book Cover](static/book_cover.png)](https://github.com/HappyCerberus/book-cpp-algorithms/releases/download/v0.3.0/book_with_cover_v0.3.0.pdf) +[![Book Cover](static/book_cover.png)](https://github.com/HappyCerberus/book-cpp-algorithms/releases/download/v1.0.1/a_complete_guide_to_standard_cpp_algorithms_v1_0_1.pdf) ## Changelog +- `1.0.1` Small (mostly) formatting fixes. +- `1.0.0` Content complete release with Compiler Explorer links. - `0.3.0` New chapter with ADL information and formatting cleanup. - `0.2.1` Fixed page numbering issue, small text changes. - `0.2.0` Added chapter covering C++20 ranges and views. @@ -29,3 +31,18 @@ The resulting PDF will be in the build folder. Most code files have wrapping main files that exercise both the build and also contain `assert` expressions that verify correctness of the code. The `verify.sh` shell script will build all (except for a few that don't compile with GCC 11) examples, and then run each of them to validate all asserts. + +## Alternative approach of building from sources + +This section was provided by [@wxinix](https://github.com/wxinix). Please direct any questions to him. + +[TeXstudio](https://www.texstudio.org/) offers an alternative solution for those who are building from sources in a virtual machine environment and are unable to use the VSCode and Docker approach. Follow the steps below (assuming the Guest OS of the virtual machine is Windows): + +- Install [Anaconda](https://www.anaconda.com/) and add `C:\Users\YourUserName\anaconda3\Scripts` to system path. Replace `YourUserName` with your actual user name. +- Install [TeXstudio](https://www.texstudio.org/). +- Go to TeXstudio menu "Options -> Configure TeXstudio -> Commands -> XeLaTex", and enter the following command: `xelatex.exe -synctex=1 -interaction=nonstopmode -shell-escape -aux-directory=build -output-directory=build %.tex`. This command sets both the aux and output directories to ".\build". +- Go to TeXstudio menu "Options -> Configure TeXstudio -> Build -> Meta Commands -> Default Compiler", and enter `txs:///xelatex`. This switches the default compiler from `pdflatex` to `xelatex`. Then, enable the checkbox "Show Advanced Options". +- For TeXstudio menu "Options -> Configure TeXstudio -> Build -> Build Options -> PDF File", enter `build`. This tells the pdf previewer to look for the generated pdf file in the ".\build" directory. +- Finally, go to "TeXstudio menu Options -> Configure TeXstudio -> Commands -> Makeindex", and enter the following command: `makeindex.exe build%.idx` + +These steps will enable you to build from sources inside a virtual machine using TeXstudio. Keep in mind that the VSCode and Docker approach might not work in a virtual machine environment, because it requires extra set-up for [nested virtulization](https://stackoverflow.com/questions/39720254/can-i-run-docker-in-a-virtual-machine). Ask @wxinix if you have any questions. diff --git a/chapters/01_preface.tex b/chapters/01_preface.tex index 52d5d3f..c3f4536 100644 --- a/chapters/01_preface.tex +++ b/chapters/01_preface.tex @@ -41,5 +41,6 @@ \section*{Book status} \subsection*{Changelog} \begin{enumerate} - \item[1.0] First complete release + \item[1.0.1] Small (mostly) formatting changes. + \item[1.0.0] First complete release. \end{enumerate} \ No newline at end of file diff --git a/chapters/02_introduction.tex b/chapters/02_introduction.tex index 50599c2..9a29019 100644 --- a/chapters/02_introduction.tex +++ b/chapters/02_introduction.tex @@ -82,7 +82,7 @@ \subsection{Iterator categories} \textit{arrays, e.g. std::vector}\index{\cpp{std::vector}} \end{description} -\begin{codebox}[]{\href{https://godbolt.org/z/dcaMEdnoM}{\ExternalLink}} +\begin{codebox}[]{\href{https://godbolt.org/z/aWT1Wajva}{\ExternalLink}} \footnotesize Example demonstrating the difference between a random access iterator provided by \cpp{std::vector} and a bidirectional iterator provided by \cpp{std::list}. \tcblower \cppfile{code_examples/introduction/categories_code.h} diff --git a/chapters/03_algorithms_01_foreach.tex b/chapters/03_algorithms_01_foreach.tex index 0c7e8b3..2ceed90 100644 --- a/chapters/03_algorithms_01_foreach.tex +++ b/chapters/03_algorithms_01_foreach.tex @@ -97,7 +97,7 @@ \subsection{\texorpdfstring{\cpp{std::for_each_n}}{\texttt{std::for\_each\_n}}} \raggedbottom -\begin{codebox}[]{\href{https://compiler-explorer.com/z/1hfje76Yq}{\ExternalLink}} +\begin{codebox}[]{\href{https://compiler-explorer.com/z/o8rEzc6q3}{\ExternalLink}} \footnotesize Example demonstrating multiple uses of \cpp{std::for_each_n}. \tcblower \cppfile{code_examples/algorithms/for_each_n_code.h} diff --git a/chapters/03_algorithms_03_sorting.tex b/chapters/03_algorithms_03_sorting.tex index 4351d54..fd25854 100644 --- a/chapters/03_algorithms_03_sorting.tex +++ b/chapters/03_algorithms_03_sorting.tex @@ -79,12 +79,12 @@ \subsection{\texorpdfstring{\cpp{std::lexicographical_compare_three_way}}{\textt \subsection{\texorpdfstring{\cpp{std::sort}}{\texttt{std::sort}}} \index{\cpp{std::sort}} -The \cpp{std::sort} algorithm is the canonical $O(n*logn)$ sort (typically implemented as intro-sort). +The \cpp{std::sort} algorithm is the canonical $O(n\log n)$ sort (typically implemented as intro-sort). \cppversions{\texttt{sort}}{\CC98}{\CC20}{\CC17}{\CC20} \constraints{\cpp{random_access_range}}{\cpp{random_access_range}}{\cpp{operator<}}{\cpp{strict_weak_ordering}} -Due to the $O(n*logn)$ complexity guarantee, \cpp{std::sort} only operates on \cpp{random_access} ranges. Notably, \cpp{std::list} offers a method with an approximate $n*logn$ complexity. +Due to the $O(n\log n)$ complexity guarantee, \cpp{std::sort} only operates on \cpp{random_access} ranges. Notably, \cpp{std::list} offers a method with an approximate $n\log n$ complexity. \begin{codebox}[]{\href{https://compiler-explorer.com/z/vef61TWj9}{\ExternalLink}} \footnotesize Basic example of using \cpp{std::sort} and \cpp{std::list::sort}. @@ -110,7 +110,7 @@ \subsection{\texorpdfstring{\cpp{std::stable_sort}}{\texttt{std::stable\_sort}}} \cppversions{\texttt{stable\_sort}}{\CC98}{N/A}{\CC17}{\CC20} \constraints{\cpp{random_access_range}}{}{\cpp{operator<}}{\cpp{strict_weak_ordering}} -If additional memory is available, stable\_sort remains $O(n*logn)$. However, if it fails to allocate, it will degrade to an $O(n*logn*logn)$ algorithm. +If additional memory is available, stable\_sort remains $O(n\log n)$. However, if it fails to allocate, it will degrade to an $O(n\log n\log n)$ algorithm. \begin{codebox}[]{\href{https://compiler-explorer.com/z/TKx8qP8bK}{\ExternalLink}} \footnotesize Example of re-sorting a range using \cpp{std::stable_sort}, resulting in a guaranteed order of elements. diff --git a/chapters/03_algorithms_05_divide.tex b/chapters/03_algorithms_05_divide.tex index 2fc9309..98e8c51 100644 --- a/chapters/03_algorithms_05_divide.tex +++ b/chapters/03_algorithms_05_divide.tex @@ -10,7 +10,7 @@ \subsection{\texorpdfstring{\cpp{std::lower_bound}, \cpp{std::upper_bound}}{\tex \index{\cpp{std::lower_bound}} \index{\cpp{std::upper_bound}} -The \cpp{std::lower_bound} and \cpp{std::upper_bound} algorithms offer boundary search with logarithmic complexity (for random access ranges. +The \cpp{std::lower_bound} and \cpp{std::upper_bound} algorithms offer boundary search with logarithmic complexity (for random access ranges). \cppversions{\texttt{lower\_bound}}{\CC98}{\CC20}{N/A}{\CC20} \cppversions{\texttt{upper\_bound}}{\CC98}{\CC20}{N/A}{\CC20} @@ -30,7 +30,7 @@ \subsection{\texorpdfstring{\cpp{std::lower_bound}, \cpp{std::upper_bound}}{\tex \cppfile{code_examples/algorithms/lower_bound_code.h} \end{codebox} -While the algorithms will operate on any \cpp{forward_range}, the logarithmic divide and conquer behaviour is only available for \cpp{random_access_range}. Data structures like \cpp{std::set}, \cpp{std::multiset}, \cpp{std::map} and \cpp{std::multimap} offer their $O(logn)$ implementations of lower and upper bound as methods. +While the algorithms will operate on any \cpp{forward_range}, the logarithmic divide and conquer behaviour is only available for \cpp{random_access_range}. Data structures like \cpp{std::set}, \cpp{std::multiset}, \cpp{std::map} and \cpp{std::multimap} offer their $O(\log n)$ implementations of lower and upper bound as methods. \begin{codebox}[]{\href{https://compiler-explorer.com/z/o9Wdvzno9}{\ExternalLink}} \footnotesize Example of using \cpp{lower_bound} and \cpp{upper_bound} methods on a \cpp{std::multiset}. diff --git a/chapters/03_algorithms_15_heap.tex b/chapters/03_algorithms_15_heap.tex index 89526b4..e2db31d 100644 --- a/chapters/03_algorithms_15_heap.tex +++ b/chapters/03_algorithms_15_heap.tex @@ -39,7 +39,7 @@ \subsection{\texorpdfstring{\cpp{std::make_heap}, \cpp{std::push_heap}, \cpp{std \subsection{\texorpdfstring{\cpp{std::sort_heap}}{\texttt{std::sort\_heap}}} \index{\cpp{std::sort_heap}} -The \cpp{std::sort_heap} will reorder the elements in a heap into a sorted order. Note that this is the same as repeatedly calling \cpp{std::pop_heap}; hence the algorithm has $O(n*logn)$ complexity. +The \cpp{std::sort_heap} will reorder the elements in a heap into a sorted order. Note that this is the same as repeatedly calling \cpp{std::pop_heap}; hence the algorithm has $O(n\log n)$ complexity. \cppversions{\texttt{sort\_heap}}{\CC98}{\CC20}{N/A}{\CC20} \constraints{\texttt{random\_access\_range}}{}{\texttt{operator<}}{\texttt{strict\_weak\_ordering}} diff --git a/code_examples/algorithms/for_each_n.cpp b/code_examples/algorithms/for_each_n.cpp index 7a6e8ad..eab3cce 100644 --- a/code_examples/algorithms/for_each_n.cpp +++ b/code_examples/algorithms/for_each_n.cpp @@ -5,7 +5,7 @@ #include inline constexpr const size_t MAIN_SEATS = 2; -inline constexpr const ssize_t PAGE_SIZE = 2; +inline constexpr const size_t PAGE_SIZE = 2; struct Player { std::string display_name; diff --git a/code_examples/algorithms/for_each_n_code.h b/code_examples/algorithms/for_each_n_code.h index b504025..14922b4 100644 --- a/code_examples/algorithms/for_each_n_code.h +++ b/code_examples/algorithms/for_each_n_code.h @@ -9,7 +9,7 @@ std::for_each_n(std::execution::par_unseq, auto it = final_ranking.begin(); uint32_t page = 0; while (it != final_ranking.end()) { - ssize_t cnt = std::min(PAGE_SIZE, final_ranking.end() - it); + size_t cnt = std::min(PAGE_SIZE, size_t(final_ranking.end() - it)); std::for_each_n(it, cnt, [page](const Player& p) { store_final_score(page, p.display_name, p.score); }); diff --git a/code_examples/introduction/categories_code.h b/code_examples/introduction/categories_code.h index f1cd3cc..33c59e1 100644 --- a/code_examples/introduction/categories_code.h +++ b/code_examples/introduction/categories_code.h @@ -3,7 +3,7 @@ auto it1 = arr.begin(); it1 += 5; // OK, std::vector provides random access iterator ++it1; // OK, all iterators provide advance operation -ssize_t dst1 = it1 - arr.begin(); // OK, random access iterator +ptrdiff_t dst1 = it1 - arr.begin(); // OK, random access iterator // dst1 == 6 std::list lst = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; @@ -13,5 +13,5 @@ std::advance(it2, 5); // OK, linear advance by 5 steps ++it2; // OK, all iterators provide advance operation // it2 - lst.begin(); Would not compile -ssize_t dst2 = std::distance(lst.begin(), it2); // OK, linear calc. +ptrdiff_t dst2 = std::distance(lst.begin(), it2); // OK, linear calc. // dst2 == 6 diff --git a/packages/custom_commands/version.tex b/packages/custom_commands/version.tex index 9089338..e0ac109 100644 --- a/packages/custom_commands/version.tex +++ b/packages/custom_commands/version.tex @@ -1 +1 @@ -\newcommand{\version}{1.0.0} \ No newline at end of file +\newcommand{\version}{1.0.1} \ No newline at end of file