├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── algo_interview ├── readme.md └── yandex │ ├── reamde.md │ ├── task_001.cpp │ └── task_002.cpp ├── example.cpp ├── img ├── ASCII_Code_Chart.svg.png ├── img_1.png ├── img_100_1.png ├── img_114_1.png ├── img_121_1.png ├── img_121_2.png ├── img_128_1.png ├── img_130_1.png ├── img_130_2.png ├── img_130_3.png ├── img_142_1.png ├── img_142_2.png ├── img_143_1.png ├── img_144_1.png ├── img_144_2.png ├── img_144_3.png ├── img_146_1.png ├── img_147_1.png ├── img_147_2.png ├── img_147_3.png ├── img_151_1.png ├── img_151_2.png ├── img_151_3.png ├── img_156_1.png ├── img_164_1.png ├── img_164_2.png ├── img_168_1.png ├── img_168_2.png ├── img_170_1.png ├── img_2.png ├── img_37_2.png ├── img_39_1.png ├── img_46_1.png ├── img_46_2.png ├── img_46_3.png ├── img_46_4.png ├── img_46_5.png ├── img_46_6.png ├── img_55_1.png ├── img_82_1.png ├── img_90_1.png ├── img_94_1.png ├── junior │ └── UML_diagrams_overview.svg.png ├── middle │ ├── img_10_1.png │ ├── img_21_1.png │ ├── img_21_2.png │ ├── img_26_1.png │ ├── img_28_1.png │ ├── img_28_2.png │ ├── img_28_3.png │ └── img_31_1.png └── table_card.png ├── materials ├── OS.md ├── STL.md ├── base.md ├── books.md ├── computer_network.md ├── data_structures.md ├── effective_cpp_1.md ├── effective_cpp_2.md ├── memory.md ├── oop.md ├── problems.md └── virtual_functs.md ├── middle.md ├── problems.md ├── questions-400 ├── junior.md ├── middle.md ├── readme.md └── senior.md ├── readme.md ├── src ├── junior │ ├── code_4.cpp │ ├── code_9.cpp │ ├── jcode_10.cpp │ ├── jcode_101.cpp │ ├── jcode_11.cpp │ ├── jcode_14_1.cpp │ ├── jcode_14_2.cpp │ ├── jcode_15.cpp │ ├── jcode_187.cpp │ ├── jcode_22.cpp │ ├── jcode_23_1.cpp │ ├── jcode_23_2.cpp │ ├── jcode_33.cpp │ ├── jcode_37.cpp │ ├── jcode_41.cpp │ ├── jcode_63.cpp │ ├── jcode_65.cpp │ ├── jcode_66.cpp │ ├── jcode_67.cpp │ ├── jcode_68.cpp │ ├── jcode_69.cpp │ ├── jcode_83.cpp │ └── jcode_88.cpp └── problems │ ├── task_001.cpp │ ├── task_002.cpp │ ├── task_003.cpp │ ├── task_004.cpp │ ├── task_005.cpp │ ├── task_006.cpp │ ├── task_007.cpp │ ├── task_008.cpp │ ├── task_009.cpp │ ├── task_010.cpp │ ├── task_011.cpp │ ├── task_012.cpp │ ├── task_013.cpp │ ├── task_014.cpp │ ├── task_015.cpp │ ├── task_016.cpp │ ├── task_017.cpp │ ├── task_018.cpp │ ├── task_019.cpp │ ├── task_020.cpp │ ├── task_021.cpp │ ├── task_022.cpp │ ├── task_023.cpp │ ├── task_024.cpp │ ├── task_025.cpp │ ├── task_026.cpp │ ├── task_027.cpp │ ├── task_028.cpp │ ├── task_029.cpp │ ├── task_030.cpp │ ├── task_031.cpp │ ├── task_032.cpp │ └── task_033.cpp ├── start.md ├── stash └── merge_recursive_sort.md └── test.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .idea/ 35 | cmake-build-debug/ 36 | cmake-build-release/ 37 | 38 | 39 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(cppinterview) 3 | add_executable(junior_4 src/junior/code_4.cpp) 4 | set_target_properties(junior_4 PROPERTIES 5 | CXX_STANDARD 20 6 | CXX_STANDARD_REQUIRED ON 7 | ) 8 | add_executable(junior_9 src/junior/code_9.cpp) 9 | set_target_properties(junior_9 PROPERTIES 10 | CXX_STANDARD 20 11 | CXX_STANDARD_REQUIRED ON 12 | ) 13 | add_executable(junior_10 src/junior/jcode_10.cpp) 14 | set_target_properties(junior_10 PROPERTIES 15 | CXX_STANDARD 20 16 | CXX_STANDARD_REQUIRED ON 17 | ) 18 | add_executable(junior_11 src/junior/jcode_11.cpp) 19 | set_target_properties(junior_11 PROPERTIES 20 | CXX_STANDARD 20 21 | CXX_STANDARD_REQUIRED ON 22 | ) 23 | add_executable(junior_14_1 src/junior/jcode_14_1.cpp) 24 | set_target_properties(junior_14_1 PROPERTIES 25 | CXX_STANDARD 20 26 | CXX_STANDARD_REQUIRED ON 27 | ) 28 | add_executable(junior_14_2 src/junior/jcode_14_2.cpp) 29 | set_target_properties(junior_14_2 PROPERTIES 30 | CXX_STANDARD 20 31 | CXX_STANDARD_REQUIRED ON 32 | ) 33 | add_executable(junior_15 src/junior/jcode_15.cpp) 34 | set_target_properties(junior_15 PROPERTIES 35 | CXX_STANDARD 20 36 | CXX_STANDARD_REQUIRED ON 37 | ) 38 | add_executable(junior_22 src/junior/jcode_22.cpp) 39 | set_target_properties(junior_22 PROPERTIES 40 | CXX_STANDARD 20 41 | CXX_STANDARD_REQUIRED ON 42 | ) 43 | add_executable(junior_23_1 src/junior/jcode_23_1.cpp) 44 | set_target_properties(junior_23_1 PROPERTIES 45 | CXX_STANDARD 20 46 | CXX_STANDARD_REQUIRED ON 47 | ) 48 | add_executable(junior_23_2 src/junior/jcode_23_2.cpp) 49 | set_target_properties(junior_23_2 PROPERTIES 50 | CXX_STANDARD 20 51 | CXX_STANDARD_REQUIRED ON 52 | ) 53 | add_executable(junior_33 src/junior/jcode_33.cpp) 54 | set_target_properties(junior_33 PROPERTIES 55 | CXX_STANDARD 20 56 | CXX_STANDARD_REQUIRED ON 57 | ) 58 | add_executable(junior_37 src/junior/jcode_37.cpp) 59 | set_target_properties(junior_37 PROPERTIES 60 | CXX_STANDARD 20 61 | CXX_STANDARD_REQUIRED ON 62 | ) 63 | add_executable(junior_63 src/junior/jcode_63.cpp) 64 | set_target_properties(junior_63 PROPERTIES 65 | CXX_STANDARD 20 66 | CXX_STANDARD_REQUIRED ON 67 | ) 68 | add_executable(junior_65 src/junior/jcode_65.cpp) 69 | set_target_properties(junior_65 PROPERTIES 70 | CXX_STANDARD 20 71 | CXX_STANDARD_REQUIRED ON 72 | ) 73 | add_executable(junior_66 src/junior/jcode_66.cpp) 74 | set_target_properties(junior_66 PROPERTIES 75 | CXX_STANDARD 20 76 | CXX_STANDARD_REQUIRED ON 77 | ) 78 | add_executable(junior_67 src/junior/jcode_67.cpp) 79 | set_target_properties(junior_67 PROPERTIES 80 | CXX_STANDARD 20 81 | CXX_STANDARD_REQUIRED ON 82 | ) 83 | add_executable(junior_68 src/junior/jcode_68.cpp) 84 | set_target_properties(junior_68 PROPERTIES 85 | CXX_STANDARD 20 86 | CXX_STANDARD_REQUIRED ON 87 | ) 88 | add_executable(junior_69 src/junior/jcode_69.cpp) 89 | set_target_properties(junior_69 PROPERTIES 90 | CXX_STANDARD 20 91 | CXX_STANDARD_REQUIRED ON) 92 | 93 | add_executable(junior_83 src/junior/jcode_83.cpp) 94 | set_target_properties(junior_83 PROPERTIES 95 | CXX_STANDARD 20 96 | CXX_STANDARD_REQUIRED ON) 97 | 98 | add_executable(junior_88 src/junior/jcode_88.cpp) 99 | set_target_properties(junior_88 PROPERTIES 100 | CXX_STANDARD 20 101 | CXX_STANDARD_REQUIRED ON) 102 | 103 | add_executable(junior_187 src/junior/jcode_187.cpp) 104 | set_target_properties(junior_187 PROPERTIES 105 | CXX_STANDARD 20 106 | CXX_STANDARD_REQUIRED ON) 107 | add_executable(test test.cpp) 108 | set_target_properties(test PROPERTIES 109 | CXX_STANDARD 20 110 | CXX_STANDARD_REQUIRED ON) 111 | 112 | 113 | add_executable(example example.cpp) 114 | set_target_properties(example PROPERTIES 115 | CXX_STANDARD 20 116 | CXX_STANDARD_REQUIRED ON) 117 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jollu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /algo_interview/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/algo_interview/readme.md -------------------------------------------------------------------------------- /algo_interview/yandex/reamde.md: -------------------------------------------------------------------------------- 1 | 2 | ### No2 [Yandex] 3 | - Написать функцию, которая делает RLE сжатие строки, например "abbccc"→ "ab2c3" -------------------------------------------------------------------------------- /algo_interview/yandex/task_001.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Jollu Emil on 5/20/24. 3 | // 4 | -------------------------------------------------------------------------------- /algo_interview/yandex/task_002.cpp: -------------------------------------------------------------------------------- 1 | //// No2 [Yandex] 2 | //// Написать функцию, которая делает RLE сжатие строки, например "abbccc"→ "ab2c3" 3 | 4 | //// @Solution 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | class Solution_2 { 14 | public: 15 | string LRE(string &s) { 16 | string ans; 17 | ans += s[0]; 18 | if (s.size() == 1) return ans; 19 | 20 | for (int cnt = 1, r = 1; r < s.size(); ++r) { 21 | if (s[r - 1] == s[r])++cnt; 22 | else if (cnt > 1) { 23 | ans += {(char) (cnt + '0'), s[r]}; 24 | cnt = 1; 25 | } else ans += s[r]; 26 | if (r + 1 == s.size())ans += (cnt > 1 ? string() + (char) (cnt + '0') : ""); 27 | } 28 | return ans; 29 | } 30 | }; 31 | 32 | class Solution { 33 | public: 34 | string LRE(string &s) { 35 | string ans; 36 | ans += s[0]; 37 | for (int cnt = 1, i = 1; i < s.size();) { 38 | while (i < s.size() && ans.back() == s[i]) { 39 | ++cnt; 40 | ++i; 41 | } 42 | if (cnt > 1) 43 | ans += to_string(cnt); 44 | if (i < s.size()) 45 | ans += s[i]; 46 | cnt = 1; 47 | ++i; 48 | } 49 | std::cout << ans << '\n'; 50 | return ans; 51 | } 52 | }; 53 | 54 | int main() { 55 | string str = "abbccc"; 56 | Solution s; 57 | assert(s.LRE(str) == "ab2c3"); 58 | } 59 | -------------------------------------------------------------------------------- /example.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/find-all-anagrams-in-a-string/description/ 3 | /// 4 | //// @Solution 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | //class Solution { 21 | //public: 22 | // string LRE(string &s) { 23 | // string ans; 24 | // ans += s[0]; 25 | // if (s.size() == 1) return ans; 26 | // 27 | // for (int cnt = 1, r = 1; r < s.size(); ++r) { 28 | // if (s[r - 1] == s[r])++cnt; 29 | // else if (cnt > 1) { 30 | // ans += {(char) (cnt + '0'), s[r]}; 31 | // cnt = 1; 32 | // } else ans += s[r]; 33 | // if (r + 1 == s.size())ans += (cnt > 1 ? string() + (char) (cnt + '0') : ""); 34 | // } 35 | // return ans; 36 | // } 37 | //}; 38 | 39 | 40 | class Solution { 41 | public: 42 | string LRE(string &s) { 43 | string ans; 44 | ans += s[0]; 45 | for (int cnt = 1, i = 1; i < s.size();) { 46 | while (i < s.size() && ans.back() == s[i]) { 47 | ++cnt; 48 | ++i; 49 | } 50 | if (cnt > 1) 51 | ans += to_string(cnt); 52 | if (i < s.size()) 53 | ans += s[i]; 54 | cnt = 1; 55 | ++i; 56 | } 57 | std::cout << ans << '\n'; 58 | return ans; 59 | } 60 | }; 61 | 62 | int main() { 63 | string str = "abbccc"; 64 | Solution s; 65 | assert(s.LRE(str) == "ab2c3"); 66 | } 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /img/ASCII_Code_Chart.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/ASCII_Code_Chart.svg.png -------------------------------------------------------------------------------- /img/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_1.png -------------------------------------------------------------------------------- /img/img_100_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_100_1.png -------------------------------------------------------------------------------- /img/img_114_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_114_1.png -------------------------------------------------------------------------------- /img/img_121_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_121_1.png -------------------------------------------------------------------------------- /img/img_121_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_121_2.png -------------------------------------------------------------------------------- /img/img_128_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_128_1.png -------------------------------------------------------------------------------- /img/img_130_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_130_1.png -------------------------------------------------------------------------------- /img/img_130_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_130_2.png -------------------------------------------------------------------------------- /img/img_130_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_130_3.png -------------------------------------------------------------------------------- /img/img_142_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_142_1.png -------------------------------------------------------------------------------- /img/img_142_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_142_2.png -------------------------------------------------------------------------------- /img/img_143_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_143_1.png -------------------------------------------------------------------------------- /img/img_144_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_144_1.png -------------------------------------------------------------------------------- /img/img_144_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_144_2.png -------------------------------------------------------------------------------- /img/img_144_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_144_3.png -------------------------------------------------------------------------------- /img/img_146_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_146_1.png -------------------------------------------------------------------------------- /img/img_147_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_147_1.png -------------------------------------------------------------------------------- /img/img_147_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_147_2.png -------------------------------------------------------------------------------- /img/img_147_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_147_3.png -------------------------------------------------------------------------------- /img/img_151_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_151_1.png -------------------------------------------------------------------------------- /img/img_151_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_151_2.png -------------------------------------------------------------------------------- /img/img_151_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_151_3.png -------------------------------------------------------------------------------- /img/img_156_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_156_1.png -------------------------------------------------------------------------------- /img/img_164_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_164_1.png -------------------------------------------------------------------------------- /img/img_164_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_164_2.png -------------------------------------------------------------------------------- /img/img_168_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_168_1.png -------------------------------------------------------------------------------- /img/img_168_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_168_2.png -------------------------------------------------------------------------------- /img/img_170_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_170_1.png -------------------------------------------------------------------------------- /img/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_2.png -------------------------------------------------------------------------------- /img/img_37_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_37_2.png -------------------------------------------------------------------------------- /img/img_39_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_39_1.png -------------------------------------------------------------------------------- /img/img_46_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_1.png -------------------------------------------------------------------------------- /img/img_46_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_2.png -------------------------------------------------------------------------------- /img/img_46_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_3.png -------------------------------------------------------------------------------- /img/img_46_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_4.png -------------------------------------------------------------------------------- /img/img_46_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_5.png -------------------------------------------------------------------------------- /img/img_46_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_46_6.png -------------------------------------------------------------------------------- /img/img_55_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_55_1.png -------------------------------------------------------------------------------- /img/img_82_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_82_1.png -------------------------------------------------------------------------------- /img/img_90_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_90_1.png -------------------------------------------------------------------------------- /img/img_94_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/img_94_1.png -------------------------------------------------------------------------------- /img/junior/UML_diagrams_overview.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/junior/UML_diagrams_overview.svg.png -------------------------------------------------------------------------------- /img/middle/img_10_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_10_1.png -------------------------------------------------------------------------------- /img/middle/img_21_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_21_1.png -------------------------------------------------------------------------------- /img/middle/img_21_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_21_2.png -------------------------------------------------------------------------------- /img/middle/img_26_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_26_1.png -------------------------------------------------------------------------------- /img/middle/img_28_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_28_1.png -------------------------------------------------------------------------------- /img/middle/img_28_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_28_2.png -------------------------------------------------------------------------------- /img/middle/img_28_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_28_3.png -------------------------------------------------------------------------------- /img/middle/img_31_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/middle/img_31_1.png -------------------------------------------------------------------------------- /img/table_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jollu8/C-INTERVIEW-QUESTIONS/b19bd5302a8cbfdedd96d4613c99f974c8ed0e48/img/table_card.png -------------------------------------------------------------------------------- /materials/OS.md: -------------------------------------------------------------------------------- 1 | ## 💻 Операционная система 2 | 3 | ### Процессы и потоки 4 | 5 | Для систем с потоками: 6 | 7 | * Процессы - это независимые единицы выделения ресурсов 8 | * Поток - это независимая единица планирования ресурсов 9 | 10 | Для систем без потоков: 11 | 12 | * Процесс - это независимая единица планирования и выделения ресурсов 13 | 14 | #### Коммуникация между процессами и преимущества и недостатки 15 | 16 | * Конвейер (PIPE) 17 | * Известный конвейер: полудуплексный метод связи, который позволяет общаться между несвязанными процессами 18 | * Преимущества: может достигать межпроцессного общения в любых отношениях 19 | * Недостатки: 20 | 1. Долгосрочное хранение в системе, неправильное использование склонно к ошибкам 21 | Ограниченный буфер 22 | * Безымянный конвейер: полудуплексный метод связи, который может быть использован только между процессами с 23 | родственными отношениями (родительские процессы) 24 | * Преимущества: простота и удобство 25 | * Недостатки: 26 | Ограничено односторонней связью 27 | 2. Может быть создан только между своими процессами и их связанными процессами 28 | 3. Ограниченный буфер 29 | * Семафор: счетчик, который может быть использован для контроля доступа к общим ресурсам несколькими потоками 30 | * Преимущества: может синхронизировать процессы 31 | * Недостаток: ограниченный семафор 32 | * Сигнал (Signal): более сложный метод связи, используемый для уведомления принимающего процесса о том, что произошло 33 | событие 34 | * Очередь сообщений: связный список сообщений, хранящийся в ядре и идентифицируемый идентификатором очереди сообщений 35 | * Преимущества: может достигать общения между любым процессом, и достигать синхронизации между отправкой и 36 | получением сообщений через функции системного вызова, не нужно учитывать вопросы синхронизации, удобно 37 | * Недостатки: Копирование информации требует дополнительного времени ЦП, что не подходит для ситуаций с большим 38 | объемом информации или частыми операциями 39 | * Общая память: отображает кусок памяти, который может быть доступен для других процессов. Эту общую память создает один 40 | процесс, но к ней могут обращаться несколько процессов. 41 | * Преимущества: не нужно копировать, быстро, большой объем информации 42 | * Недостатки: 43 | 1. Коммуникация достигается путем прямого присоединения буфера общего пространства к виртуальному адресному 44 | пространству процесса, поэтому синхронизация операций чтения и записи между процессами 45 | 2. Используйте буфер памяти для прямого обмена информацией. Сущность памяти существует в компьютере и может быть 46 | общей только для многих процессов в компьютерной системе, что неудобно для сетевой связи. 47 | * Сокет (Socket): может быть использован для общения процессов между разными компьютерами 48 | * Преимущества: 49 | 1. Передаваемые данные на уровне байт, передаваемые данные можно настроить, объем данных мал и эффективность 50 | высока 51 | 2. Короткое время передачи данных и высокая производительность 52 | 3. Подходит для обмена информацией в реальном времени между клиентом и сервером 53 | 4. Может быть зашифрован, сильная безопасность данных 54 | * Недостатки: Передаваемые данные нужно разобрать и преобразовать в данные уровня приложения. 55 | 56 | ## 💻 Операционная система 57 | 58 | ### Коммуникация между потоками 59 | 60 | * Механизм блокировки: включает в себя мьютекс, блокировку читателя-писателя, спин-блокировку и условие 61 | * Мьютекс (mutex): предоставляет исключительный способ предотвращения одновременного изменения структур данных. 62 | * Блокировка читателя-писателя: позволяет нескольким потокам одновременно читать общие данные и является 63 | взаимоисключающей для операций записи. 64 | * Спин-блокировки аналогичны мьютекс-блокировкам для защиты общих ресурсов. Мьютекс - это когда ресурс занят, и 65 | заявитель засыпает; спин-блокировка циклически проверяет, освободил ли владелец блокировку. 66 | * Переменная условия (condition): вы можете атомарно блокировать процесс, пока не станет истинным определенное 67 | условие. Тестирование условий выполняется под защитой мьютекса. Переменные условия всегда используются с 68 | мьютексом. 69 | * Механизм семафора 70 | * Неизвестный семафор потока 71 | * Именованный семафор потока 72 | * Механизм сигнала (Signal): аналогичен обработке сигналов между процессами 73 | * Барьер: барьер позволяет каждому потоку ждать, пока все сотрудничающие потоки не достигнут определенной точки, а затем 74 | продолжить выполнение с этой точки. 75 | 76 | Цель коммуникации между потоками в основном заключается в синхронизации потоков, поэтому у потоков нет механизма 77 | коммуникации для обмена данными, как в коммуникации процессов. 78 | 79 | > Методы коммуникации между процессами и их преимущества и недостатки взяты 80 | > 81 | из: [Сводка вопросов на собеседовании по потокам процессов](http://blog.csdn.net/wujiafei_njgcxy/article/details/77098977) 82 | 83 | #### Частные и общие ресурсы между процессами 84 | 85 | * Частные: адресное пространство, куча, глобальные переменные, стек, регистры 86 | * Общие: фрагмент кода, общедоступные данные, каталог процессов, идентификатор процесса 87 | 88 | #### Частные и общие ресурсы между потоками 89 | 90 | * Частные: стек потока, регистр, счетчик программ 91 | * Общие: куча, адресное пространство, глобальные переменные, статические переменные 92 | 93 | #### Сравнение, преимущества и недостатки многопроцессорности и многопоточности 94 | 95 | ##### Сравнение 96 | 97 | | Параметры сравнения | Многопроцессорность | Многопоточность | Итог | 98 | |-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|--------------------------------| 99 | | Обмен данными и синхронизация | Сложный обмен данными требует IPC; данные раздельные и легко синхронизируются | Поскольку данные процесса общие, обмен данными прост, но именно по этой причине синхронизация усложняется | Каждый имеет свои преимущества | 100 | | Память, ЦП | Занимает больше памяти, сложное переключение, низкая утилизация ЦП | Меньше памяти, простое переключение, высокая утилизация ЦП | Потоки доминируют | 101 | | Создание, уничтожение, переключение | создание, уничтожение, переключение сложные, медленная скорость | создание, уничтожение, переключение простые, быстрая скорость | потоки доминируют | 102 | | Программирование, отладка | простое программирование, простая отладка | сложное программирование, сложная отладка | процессы доминируют | 103 | | Надежность | Процессы не будут влиять друг на друга | Повисание потока приведет к повисанию всего процесса | Процессы доминируют | 104 | | Распределенность | Применимо к многопроцессорному, многомашинному распределению; если одной машины недостаточно, расширение до нескольких машин относительно просто | адаптировано к многопроцессорному распределению | процессы доминируют | 105 | 106 | ##### Преимущества и недостатки 107 | 108 | | Плюсы и минусы | многопроцессорность | многопоточность | 109 | |----------------|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| 110 | | Преимущества | Простое программирование и отладка, высокая надежность | Быстрое создание, уничтожение, переключение, маленькое занимаемое памятью и ресурсное пространство | 111 | | Недостатки | Создание, уничтожение, медленное переключение, большое занимаемое памятью и ресурсное пространство | Сложное программирование и отладка, плохая надежность | 112 | 113 | ##### Выбор 114 | 115 | * Необходимо часто создавать и уничтожать приоритетные потоки 116 | * Приоритетные потоки, которые требуют большого количества вычислений 117 | * Сильно связанные потоки обработки, слабо связанные процессы обработки 118 | * Может быть расширено до многомашинного распределенного процесса, многопроцессорных распределенных потоков 119 | * Когда все удовлетворяют потребностям, используйте метод, с которым вы наиболее знакомы 120 | 121 | > Сравнение, преимущества и недостатки многопроцессорности и многопоточности взяты 122 | > из: [выбор между многопоточностью или многопроцессорностью и разница](https://blog.csdn.net/lishenglong666/article/details/8557215) 123 | 124 | ### Синхронизация в ядре Linux 125 | 126 | #### Причина 127 | 128 | В современных операционных системах может быть несколько потоков выполнения ядра, выполняющихся одновременно, поэтому 129 | ядру на самом деле нужен некоторый механизм синхронизации для синхронизации доступа исполнительных единиц к общим 130 | данным, как в многопроцессорном и многопоточном программировании. Особенно на многопроцессорных системах требуются 131 | некоторые механизмы синхронизации для синхронизации доступа исполнительных единиц на разных процессорах к общим данным. 132 | 133 | #### Синхронизация 134 | 135 | * Атомарные операции 136 | * Семафор 137 | * Семафор чтения и записи (rw_semaphore) 138 | * Спин-блокировка 139 | * Большая блокировка ядра (BKL, Big Kernel Lock) 140 | * Блокировка чтения-записи (rwlock) 141 | * Brlock-Big Reader Lock 142 | * Обновление чтения-копирования (RCU, Read-Copy Update) 143 | * Блокировка последовательности (seqlock) 144 | 145 | > 146 | Из: [Механизм синхронизации ядра Linux, Часть 1](https://www.ibm.com/developerworks/cn/linux/l-synch/part1/), [Механизм синхронизации ядра Linux, Часть 2](https://www.ibm.com/developerworks/cn/linux/l-synch/part2/) 147 | 148 | ### Взаимная блокировка 149 | 150 | #### Причины 151 | 152 | * Недостаток системных ресурсов 153 | * Неправильное распределение ресурсов 154 | * Неподходящий порядок выполнения операций процесса 155 | 156 | #### Условия генерации 157 | 158 | * Взаимное исключение 159 | * Запрос и удержание 160 | * Не лишены 161 | * Цикл 162 | 163 | #### Профилактика 164 | 165 | * Разрушение условий взаимного исключения: преобразование исключительных ресурсов в виртуальные ресурсы, большинство из 166 | которых не могут быть преобразованы. 167 | * Разрушение условия непредвзятости: когда процесс занимает исключительный ресурс, а затем применяет исключительный 168 | ресурс, который не может быть выполнен, он откажется от исходного ресурса. 169 | * Разрушение условий владения и применения: принять стратегию предварительного распределения ресурсов, то есть применить 170 | все ресурсы перед выполнением процесса, выполнить, если он соответствует, или ждать, чтобы он не был занят и применен. 171 | * Разрушение условия ожидания цикла: реализовать упорядоченное распределение ресурсов, реализовать классификацию номеров 172 | для всех устройств, и все процессы могут применять ресурсы только в форме возрастающих чисел. 173 | * Упорядоченный метод распределения ресурсов 174 | * Алгоритм банкира 175 | 176 | ### Файловая система 177 | 178 | * Windows: таблица FCB + FAT + битовая карта 179 | * Unix: inode + смешанный индекс + групповая ссылка 180 | 181 | ### Порядок байтов хоста и порядок байтов сети 182 | 183 | #### Порядок байтов хоста (Порядок байтов CPU) 184 | 185 | ##### Понятие 186 | 187 | Порядок байтов хоста также называется порядком байтов CPU. Он не определяется операционной системой, а архитектурой 188 | набора инструкций CPU. Существуют два типа порядка байтов хоста: 189 | 190 | * Big Endian: старший байт хранится в адресе низкого порядка, а младший байт хранится в адресе высокого порядка 191 | * Little Endian: старший байт хранится в адресе высокого порядка, а младший байт хранится в адресе низкого порядка. 192 | 193 | ##### Метод хранения 194 | 195 | 32-битное целое число `0x12345678` хранится с адреса, начинающегося с `0x00`, тогда: 196 | 197 | | Адрес памяти | 0x00 | 0x01 | 0x02 | 0x03 | 198 | |---------------|------|------|------|------| 199 | | Big Endian | 12 | 34 | 56 | 78 | 200 | | Little Endian | 78 | 56 | 34 | 12 | 201 | 202 | Картинки большого и малого порядка байтов 203 | 204 | ![Big endian](https://raw.githubusercontent.com/huihut/interview/master/images/CPU-Big-Endian.svg.png) 205 | ![Little endian](https://raw.githubusercontent.com/huihut/interview/master/images/CPU-Little-Endian.svg.png) 206 | 207 | ##### Определение большого и малого порядка байтов 208 | 209 | Вы можете определить, является ли порядок байтов вашего процессора большим или малым: 210 | 211 | ```cpp 212 | #include 213 | using namespace std; 214 | 215 | int main() 216 | { 217 | int i = 0x12345678; 218 | 219 | if (*((char*)&i) == 0x12) 220 | cout << "Big endian" << endl; 221 | else 222 | cout << "Little endian" << endl; 223 | 224 | return 0; 225 | } 226 | ``` 227 | 228 | ##### Порядок байтов каждого процессора архитектуры 229 | 230 | * x86 (Intel, AMD), MOS Technology 6502, Z80, VAX, PDP-11 и другие процессоры - малый порядок байтов; 231 | * Motorola 6800, Motorola 68000, PowerPC 970, System/370, SPARC (кроме V9) процессоры - большой порядок байтов; 232 | * Порядок байтов ARM (по умолчанию малый порядок байтов), PowerPC (кроме PowerPC 970), DEC Alpha, SPARC V9, MIPS, PA-RISC и IA64 можно настроить. 233 | 234 | #### Порядок байтов сети 235 | 236 | Порядок байтов сети - это формат представления данных, указанный в TCP/IP. Он не имеет ничего общего с конкретным типом процессора, операционной системой и т.д., чтобы он мог гарантировать, что данные будут правильно интерпретироваться при передаче между разными хостами. 237 | 238 | Порядок байтов сети использует: расположение Big Endian. 239 | 240 | ### Алгоритм замены страниц 241 | 242 | В процессе отображения адресов, если обнаружено, что страница, к которой нужно обратиться, не находится в памяти, генерируется прерывание отсутствия страницы. Когда происходит отсутствие страницы, если в памяти операционной системы нет свободной страницы, операционная система должна выбрать страницу в памяти, чтобы переместить ее из памяти, чтобы освободить место для страницы, которая собирается подкачать. Правила, используемые для выбора того, какие страницы устранить, называются алгоритмами замены страниц. 243 | 244 | #### Категории 245 | 246 | * Глобальная замена: замена во всем пространстве памяти 247 | * Частичная замена: Заменить в этом процессе 248 | 249 | #### Алгоритм 250 | 251 | Глобальный: 252 | * Алгоритм рабочего набора 253 | * Алгоритм замены страниц 254 | 255 | Частично: 256 | * Оптимальный алгоритм замены (OPT) 257 | * Алгоритм замены "первым пришел, первым обслужен" (FIFO) 258 | * Алгоритм наименее недавно использованных (LRU) 259 | * Алгоритм замены часов 260 | 261 | 262 | -------------------------------------------------------------------------------- /materials/STL.md: -------------------------------------------------------------------------------- 1 | ## *📦 STL* 2 | 3 | ### STL index 4 | 5 | [STL Method Meaning Index](https://github.com/huihut/interview/tree/master/STL) 6 | 7 | ### STL container 8 | 9 | | Container | Underlying data structure | Time complexity | Unordered | Can not be repeated | Other | 10 | |--------------------------------------------------------------------------------------|---------------------------|----------------------------------------------------------------------------------------|-----------|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| 11 | | [array](https://ru.cppreference.com/w/cpp/container/array) | array | random read and change O(1) | unordered | repeatable | support random access | 12 | | [vector](https://ru.cppreference.com/w/cpp/container/vector) | Array | Random read, tail insertion, tail deletion O(1)
head insertion, head Delete O(n) | Unordered | Repeatable | Support random access | 13 | | [deque](https://ru.cppreference.com/w/cpp/container/deque) | Dual-end queue | End-to-end insertion, end-to-end deletion O(1) | Unordered | Repeatable | One central control + Multiple buffers, support rapid addition and deletion at the beginning and end, support random access | 14 | | [forward_list](https://ru.cppreference.com/w/cpp/container/froward_list) | One-way linked list | Insert and delete O(1) | Unordered | Repeatable | Random access is not supported | 15 | | [list](https://ru.cppreference.com/w/cpp/container/list) | Doubly linked list | Insert / delete O(1) | Unordered | Repeatable | Does not support random access | 16 | | [stack](https://ru.cppreference.com/w/cpp/container/stack) | deque / list | top insert, top delete O(1) | unordered | repeatable | deque or list closed head The end is open. The reason why the vector is not used should be that the capacity is limited, and the expansion takes time. | 17 | | [queue](https://ru.cppreference.com/w/cpp/container/queue) | deque / list | tail insertion, head deletion O(1) | unordered | repeatable | deque or list closure The head end is open. The reason why the vector is not used should be that the capacity is limited, and the expansion takes time. | 18 | | [priority_queue](https://ru.cppreference.com/w/cpp/container/priority_queue) | vector + max-heap | Insert, delete O(log2n) | Ordered | Repeatable | vector container + heap processing rules | 19 | | [set](https://ru.cppreference.com/w/cpp/container/set) | Red and Black Tree | Insert, delete, find O(log2n) | Ordered | Not repeatable | | 20 | | [multiset](https://ru.cppreference.com/w/cpp/container/multiset) | Red and Black Tree | Insert, delete, find O(log2n) | Ordered | Repeatable | | 21 | | [map](https://ru.cppreference.com/w/cpp/container/map) | Red and Black Tree | Insert, delete, find O(log2n) | Ordered | Not repeatable | | 22 | | [multimap](https://ru.cppreference.com/w/cpp/container/multimap) | Red and Black Tree | Insert, delete, find O(log2n) | Ordered | Repeatable | | 23 | | [unordered_set](https://ru.cppreference.com/w/cpp/container/unordered_set) | Hash Table | Insert, Delete, Find O(1) Worst O(n) | Unordered | Not Repeatable | | 24 | | [unordered_multiset](https://ru.cppreference.com/w/cpp/container/unordered_multiset) | Hash Table | Insert, Delete, Find O(1) Worst O(n) | Unordered | Repeatable | | 25 | | [unordered_map](https://ru.cppreference.com/w/cpp/container/unordered_map) | Hash Table | Insert, Delete, Find O(1) Worst O(n) | Unordered | Not Repeatable | | 26 | | [unordered_multimap](https://ru.cppreference.com/w/cpp/container/unordered_multimap) | Hash Table | Insert, Delete, Find O(1) Worst O(n) | Unordered | Repeatable | | 27 | 28 | ### STL Algorithm 29 | 30 | | Algorithm | Low-level algorithm | Time complexity | Can not be repeated | 31 | |--------------------------------------------------------------------------------------------------|------------------------------------------------------------------|-----------------------|---------------------| 32 | | [find](http://www.cplusplus.com/reference/algorithm/find/) | Sequence search | O(n) | Repeatable | 33 | | [sort](https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/include/bits/stl_algo.h#L4808) | [Introspection sorting](https://en.wikipedia.org/wiki/Introsort) | O(n*log2n) | Repeatable | 34 | 35 | 36 | -------------------------------------------------------------------------------- /materials/books.md: -------------------------------------------------------------------------------- 1 | ## *Книги на всю жизнь* 2 | 3 | ## 1.[C++](#cpp) 4 | 5 | ## 2.[Networks](#network) 6 | 7 | ## 3.POSIX 8 | 9 | ## 4.Дядя Боб 10 | 11 | ## C++ 12 | 13 | 1. ### Джош Лоспинозо "C++ для профи" 14 | Эта книга идеальна, если вы собираетесь в совершенстве овладеть языком C++. В ней все описано подробно. Я жалею, что 15 | мне не рекомендовали эту книгу в начале моего изучения языка. (Однако книга не подходит для абсолютных новичков). 16 | 17 | 2. ### Райнер Гримм "C++20 в деталях" 18 | Эта книга должна быть наиболее полезной после книги Джоша Лоспинозо, поскольку в ней подробно описаны все 19 | нововведения языка C++. В перспективе без них не обойтись. 20 | 21 | 3. ### Курт Гантерот "Оптимизация программ на C++" 22 | Эта книга уже посвящена оптимизации. 23 | 24 | 4. ### Виталий Ткаченко "Обратные вызовы в C++" 25 | Книга "Обратные вызовы в C++" обязательно должна быть прочитана, поскольку я видел, что большинство бизнес-проектов 26 | злоупотребляют обратными вызовами. 27 | 28 | 5. ### Pro TBB 29 | C++ Parallel Programming with Threading Building Blocks наконец, книга про TBB. 30 | 31 | ## Networks 32 | 33 | - К сожалению, по этой теме я не знаю, что рекомендовать. 34 | Но я лично читаю или практикую по этой [ссылке](https://github.com/clowwindy/Awesome-Networking). -------------------------------------------------------------------------------- /materials/computer_network.md: -------------------------------------------------------------------------------- 1 | ## ☁️ Компьютерная сеть 2 | 3 | > Некоторые знания в этом разделе взяты из Компьютерных сетей (7-е издание) 4 | 5 | Архитектура компьютерной сети: 6 | > К сожалению пока картинка не готова 7 | 8 | [//]: # (todo) 9 | 10 | ### Роли и протоколы каждого слоя 11 | 12 | | Слои | роль | протокол | 13 | |--------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------| 14 | | Физический слой | Передача битов через среду, определение механических и электрических спецификаций (биты) | RJ45, CLOCK, IEEE802.3 (ретрансляторы, концентраторы) | 15 | | Слой канала данных | Сборка битов в кадры и доставка от точки к точке (Кадр) | PPP, FR, HDLC, VLAN, MAC (мост, коммутатор) | 16 | | Сетевой слой | Ответственность за передачу пакетов данных от источника к стоку и межсетевое взаимодействие (пакеты) | IP, ICMP, ARP, RARP, OSPF, IPX, RIP, IGRP (маршрутизатор) | 17 | | Транспортный слой | Обеспечение надежной доставки сообщений от конца к концу и восстановление ошибок (Сегмент) | TCP, UDP, SPX | 18 | | Сеансовый слой | Установление, управление и завершение сеансов (сеансовая протокольная единица данных SPDU) | NFS, SQL, NETBIOS, RPC | 19 | | Слой представления | Перевод, шифрование и сжатие данных (Единица данных протокола представления PPDU) | JPEG, MPEG, ASII | 20 | | Прикладной слой | Средство для доступа к среде OSI (Единица данных прикладного протокола APDU) | FTP, DNS, Telnet, SMTP, HTTP, WWW, NFS | 21 | 22 | ### Физический уровень 23 | 24 | * Единица передаваемых данных: бит 25 | * Система передачи данных: исходная система (источник, отправитель) -> система передачи -> система назначения (приемник, 26 | пункт назначения) 27 | 28 | Каналы: 29 | 30 | * Однонаправленный канал (simplex channel): только однонаправленная связь, нет обратной взаимодействия, например, 31 | вещание 32 | * Двунаправленная альтернативная связь (half-duplex communication): обе стороны связи могут отправлять сообщения, но не 33 | могут отправлять или получать одновременно 34 | * Двунаправленная одновременная связь (full-duplex communication): обе стороны связи могут отправлять и получать 35 | информацию одновременно 36 | 37 | Технология мультиплексирования каналов: 38 | 39 | * Частотное разделение мультиплексирование (FDM, Frequency Division Multiplexing): разные пользователи в разных 40 | частотных диапазонах, пользователи используют разные ресурсы пропускной способности одновременно 41 | * Временное разделение мультиплексирование (TDM): разные пользователи в разных временных интервалах в том же временном 42 | периоде, все пользователи занимают ту же пропускную способность в разное время 43 | * Мультиплексирование по длине волны (WDM): частотное разделение мультиплексирование света 44 | * Мультиплексирование по коду (CDM): Разные пользователи используют разные коды и могут использовать ту же частотную 45 | полосу для связи одновременно 46 | 47 | ### Уровень канала данных 48 | 49 | Основной канал: 50 | 51 | * Точечный канал 52 | * Широковещательный канал 53 | 54 | #### Точечный канал 55 | 56 | * Единица данных: кадр 57 | 58 | Три основных вопроса: 59 | 60 | * Инкапсуляция: инкапсуляция датаграмм IP на сетевом уровне в кадры, `SOH-часть данных-EOT` 61 | * Прозрачная передача: независимо от символов в части данных, она может быть передана; это может быть решено методом 62 | заполнения байтов (экранирование символов перед конфликтующими символами) 63 | * Обнаружение ошибок: уменьшение битовой частоты ошибок (BER), широко используется циклическая избыточная проверка (CRC, 64 | Cyclic Redundancy Check) 65 | 66 | Протокол точка-точка: 67 | 68 | * Протокол точка-точка: протокол, используемый компьютером пользователя для связи с провайдером интернет-услуг 69 | 70 | #### Широковещательный канал 71 | 72 | Широковещательная связь: 73 | 74 | * Аппаратный адрес (физический адрес, MAC-адрес) 75 | * Одноадресный кадр (один-к-одному): MAC-адрес полученного кадра совпадает с аппаратным адресом этой станции 76 | * Широковещательный кадр (один-к-паре): кадр, отправленный на все станции в локальной сети 77 | * Многоадресный кадр (один-к-многим): кадр, отправленный на некоторые сайты в локальной сети 78 | 79 | ### Сетевой уровень 80 | 81 | * IP (Internet Protocol, Internet Protocol) - это протокол, разработанный для общения компьютерных сетей друг с другом. 82 | * ARP (Address Resolution Protocol, Address Resolution Protocol) 83 | * ICMP (Internet Control Message Protocol, Internet Control Message Protocol) 84 | * IGMP (Internet Group Management Protocol, Internet Group Management Protocol) 85 | 86 | #### IP Интернет-протокол 87 | 88 | Классификация IP-адресов: 89 | 90 | * `IP-адрес ::= (<номер сети>, <номер хоста>)` 91 | 92 | | Категория IP-адреса | номер сети | диапазон сети | номер хоста | диапазон IP-адресов | 93 | |---------------------|---------------------------------------------------------------------------------------------|------------------------|-------------|------------------------------| 94 | | Класс A | 8 бит, первый бит фиксирован на 0 | 0 —— 127 | 24 бита | 1.0.0.0 —— 127.255.255.255 | 95 | | Класс B | 16 бит, первые два бита фиксированы на 10 | 128.0 —— 191.255 | 16 бит | 128.0.0.0 —— 191.255.255.255 | 96 | | Класс C | 24 бита, первые три бита фиксированы на 110 | 192.0.0 —— 223.255.255 | 8 бит | 192.0.0.0 —— 223.255.255.255 | 97 | | Класс D | Первые четыре бита фиксированы на 1110, за которыми следует многоадресный адрес | | | | 98 | | Класс E | Первые пять цифр фиксированы на 11110, последние зарезервированы для будущего использования | | | | 99 | 100 | Формат датаграммы IP: 101 | 102 | ![Формат датаграммы IP](https://media.geeksforgeeks.org/wp-content/uploads/20230512140024/Screenshot-(359).png) 103 | 104 | #### ICMP Интернет-протокол управления сообщениями 105 | 106 | Формат сообщения ICMP: 107 | 108 | ![Формат сообщения ICMP](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/ICMP_header_-_General-en.svg/2560px-ICMP_header_-_General-en.svg.png) 109 | 110 | * PING (Packet InterNet Groper) для проверки связности между двумя хостами 111 | * TTL (Time To Live, время жизни) Это поле указывает максимальное количество сегментов сети, которые пакеты IP могут 112 | проходить, прежде чем они будут отброшены маршрутизатором. 113 | 114 | #### Внутренний протокол шлюза 115 | 116 | * RIP (Протокол информации о маршрутизации, Routing Information Protocol) 117 | * OSPF (Протокол с наименьшим путем, Open Shortest Path First) 118 | 119 | #### Внешний протокол шлюза 120 | 121 | * BGP (Протокол граничного шлюза, Border Gateway Protocol) 122 | 123 | #### IP многоадресная рассылка 124 | 125 | * IGMP (Протокол управления группами в Интернете, Internet Group Management Protocol) 126 | * Протокол многоадресной маршрутизации 127 | 128 | #### VPN и NAT 129 | 130 | * VPN (Виртуальная частная сеть) 131 | * NAT (Трансляция сетевых адресов, Network Address Translation) 132 | 133 | #### Что содержит таблица маршрутизации? 134 | 135 | 1. ID сети (Network ID): Это ID сети адреса назначения. 136 | 2. Маска подсети: используется для определения сети, к которой принадлежит IP 137 | 3. Адрес / интерфейс следующего перехода: Это адрес следующей остановки данных на пути, отправленном на адрес 138 | назначения. Где интерфейс указывает на следующий переход (то есть следующий маршрут). Маршрут в автономной системе ( 139 | AS) должен содержать все подсети в области, а шлюз по умолчанию (ID сети: `0.0.0.0`, Маска сети:` 0.0.0.0`) указывает 140 | на выход из автономной системы. 141 | 142 | В зависимости от приложения и реализации таблица маршрутизации может содержать следующую дополнительную информацию: 143 | 144 | 1. Стоимость: Это стоимость, необходимая для прохождения пути во время передачи данных. 145 | 2. Качество обслуживания для маршрутизации 146 | 3. Список входящих / исходящих соединений, которые должны быть отфильтрованы в маршруте 147 | 148 | ### Транспортный слой 149 | 150 | протокол: 151 | 152 | * TCP (Протокол управления передачей) 153 | * UDP (Протокол пользовательских датаграмм, User Datagram Protocol) 154 | 155 | порт: 156 | 157 | | Приложения | FTP | TELNET | SMTP | DNS | TFTP | HTTP | HTTPS | SNMP | 158 | |-------------|-----|--------|------|-----|------|------|-------|------| 159 | | Номер порта | 21 | 23 | 25 | 53 | 69 | 80 | 443 | 161 | 160 | 161 | #### TCP 162 | 163 | * TCP (Протокол управления передачей, Transmission Control Protocol) - это ориентированный на соединение, надежный, 164 | основанный на потоке байтов протокол коммуникации транспортного уровня, а его единицей передачи является сегмент 165 | сообщения. 166 | 167 | Особенность: 168 | 169 | * Ориентирован на соединение 170 | * Только точка-точка (один-на-один) связь 171 | * Надежное взаимодействие 172 | * Дуплексная связь 173 | * Ориентирован на поток байтов 174 | 175 | Как TCP гарантирует надежную передачу: 176 | 177 | * Подтверждение и повторная передача по таймауту 178 | * Разумное фрагментирование и упорядочивание данных 179 | * Управление потоком 180 | * Управление перегрузкой 181 | * Проверка данных 182 | 183 | Структура сообщения TCP 184 | 185 | ![TCP Message](https://raw.githubusercontent.com/huihut/interview/master/images/TCP报文.png) 186 | 187 | Заголовок TCP 188 | 189 | ![TCP header](https://raw.githubusercontent.com/huihut/interview/master/images/TCP首部.png) 190 | 191 | TCP: Код управления состоянием (Code, Control Flag), который занимает 6 бит и имеет следующее значение: 192 | 193 | * URG: Срочно. Когда `URG = 1`, это указывает, что поле срочного указателя действительно, что означает, что пакет 194 | является срочным пакетом. Он сообщает системе, что в этом сегменте есть срочные данные, и их следует передать как 195 | можно скорее (эквивалентно данным с высоким приоритетом), и поле Urgent Pointer на рисунке выше также будет включено. 196 | * ACK: Подтверждение. Поле номера подтверждения действительно только при `ACK = 1`, что означает, что этот пакет 197 | является пакетом подтверждения. Когда `ACK = 0`, номер подтверждения недействителен. 198 | * PSH: (Функция Push) Если он равен 1, представитель требует, чтобы другая сторона немедленно передала другие 199 | соответствующие пакеты в буфере, не дожидаясь, пока буфер не заполнится перед отправкой. 200 | * RST: Бит сброса (Reset). Когда `RST = 1`, это указывает, что в TCP-соединении произошла серьезная ошибка (например, 201 | из-за сбоя хоста или по другим причинам). Вы должны освобод -------------------------------------------------------------------------------- /materials/data_structures.md: -------------------------------------------------------------------------------- 1 | ## *〽️ Дата Структуры* 2 | > Раздел "Структуры данных" (DS) требует визуализации для наглядного представления. Нужна ваша помощь. :) 3 | 4 | ### Структура последовательности 5 | 6 | #### Последовательный стек (Sequence Stack) 7 | 8 | [//]: # (todo) 9 | [SqStack.cpp](DataStructure/SqStack.cpp) 10 | 11 | [//]: # (Структуры данных и изображения последовательного стека) 12 | 13 | ```c++ 14 | typedef struct { 15 | ElemType *elem; 16 | int top; 17 | int size; 18 | int increment; 19 | } SqStack; 20 | ``` 21 | 22 | #### Очередь (Sequence Queue) 23 | 24 | Структура данных очереди 25 | 26 | ```c++ 27 | typedef struct { 28 | ElemType * elem; 29 | int front; 30 | int rear; 31 | int maxSize; 32 | }SqQueue; 33 | ``` 34 | 35 | ##### Ациклическая очередь 36 | 37 | [//]: # (Изображение ациклической очереди) 38 | 39 | `SqQueue.rear++` 40 | 41 | ##### Циклическая очередь 42 | 43 | [//]: # (Изображение циклической очереди) 44 | 45 | `SqQueue.rear = (SqQueue.rear + 1) % SqQueue.maxSize` 46 | 47 | #### Последовательная таблица (Sequence List) 48 | 49 | [//]: # (todo) 50 | [SqList.cpp](DataStructure/SqList.cpp) 51 | 52 | [//]: # (Структура данных и изображения последовательной таблицы) 53 | 54 | ```c++ 55 | typedef struct { 56 | ElemType *elem; 57 | int length; 58 | int size; 59 | int increment; 60 | } SqList; 61 | ``` 62 | ### Структура цепочки 63 | 64 | [LinkList.cpp](DataStructure/LinkList.cpp) 65 | 66 | [LinkList_with_head.cpp](DataStructure/LinkList_with_head.cpp) 67 | 68 | Структура данных цепочки 69 | 70 | ```c++ 71 | typedef struct LNode { 72 | ElemType data; 73 | struct LNode *next; 74 | } LNode, *LinkList; 75 | ``` 76 | 77 | #### Цепочная очередь (Link Queue) 78 | 79 | [//]: # (Изображение цепочной очереди) 80 | 81 | #### Цепочное представление линейного списка 82 | 83 | ##### Односвязный список (Link List) 84 | 85 | [//]: # (Изображение односвязного списка) 86 | 87 | ##### Двусвязный список (Du-Link-List) 88 | 89 | [//]: # (Изображение двусвязного списка) 90 | 91 | ##### Циклический связанный список (Cir-Link-List) 92 | 93 | [//]: # (Изображение циклического связанного списка) 94 | 95 | ### Хеш-таблица 96 | 97 | [HashTable.cpp](DataStructure/HashTable.cpp) 98 | 99 | #### Понятие 100 | 101 | Хеш-функция: `H(key): K -> D , key ∈ K` 102 | 103 | #### Метод построения 104 | 105 | * Прямое адресование 106 | * Метод деления с остатком 107 | * Метод цифрового анализа 108 | * Метод свертки 109 | * Метод квадратов 110 | 111 | #### Метод разрешения коллизий 112 | 113 | * Метод цепочных адресов: односвязный список, связанный с одинаковым ключом 114 | * Открытое адресование 115 | * Линейный метод обнаружения: одинаковый ключ -> поместить в следующую позицию ключа, `Hi = (H(key) + i) % m` 116 | * Вторичный метод обнаружения: одинаковый ключ -> поместить в `Di = 1^2, -1^2, ..., ±(k)^2,(k<=m/2)` 117 | * Случайное обнаружение: `H = (H(key) + псевдослучайное число) % m` 118 | 119 | #### Структура данных хеш-таблицы для линейного пробирования 120 | 121 | [//]: # (Структура данных хеш-таблицы и изображения для линейного обнаружения) 122 | 123 | ```c++ 124 | typedef char KeyType; 125 | 126 | typedef struct { 127 | KeyType key; 128 | }RcdType; 129 | 130 | typedef struct { 131 | RcdType *rcd; 132 | int size; 133 | int count; 134 | bool *tag; 135 | }HashTable; 136 | ``` 137 | 138 | ### Рекурсия 139 | 140 | #### Понятие 141 | 142 | Функция вызывает сама себя напрямую или косвенно 143 | 144 | #### Рекурсия и разделение 145 | 146 | * Разделение и завоевание 147 | * Разбиение проблемы 148 | * Размер декомпозиции проблемы 149 | * Половинный поиск (рекурсивный) 150 | * Сортировка слиянием (рекурсивная) 151 | * Быстрая сортировка (рекурсивная) 152 | 153 | #### Рекурсия и итерация 154 | 155 | * Итерация: использование старого значения переменной для выведения нового значения 156 | * Половинный поиск (итеративный) 157 | * Сортировка слиянием (итеративная) 158 | 159 | #### Обобщенная таблица 160 | 161 | ##### Представление хранения в виде списка с головой и хвостом 162 | 163 | Представления хранения в виде списка с головой и хвостом и изображения для обобщенных таблиц 164 | 165 | ```c++ 166 | // Представление хранения в виде списка с головой и хвостом обобщенного списка 167 | typedef enum {ATOM, LIST} ElemTag; 168 | // ATOM == 0: атом, LIST == 1: дочерняя таблица 169 | typedef struct GLNode { 170 | ElemTag tag; 171 | // общая часть, используемая для различения атомарных узлов от узлов таблицы 172 | union { 173 | // общая часть атомарного узла и узла таблицы 174 | AtomType atom; 175 | // атом - это диапазон атомарных узлов, AtomType определяется пользователем 176 | struct { 177 | struct GLNode *hp, *tp; 178 | } ptr; 179 | /// ptr - это поле указателя узла таблицы, prt.hp и ptr.tp указывают на заголовок таблицы и хвост таблицы соответственно 180 | } a; 181 | } *GList, GLNode; 182 | ``` 183 | 184 | ##### Расширенное линейное связное представление списка 185 | 186 | [//]: # (Расширенные линейные связные представления и изображения списков todo) 187 | 188 | ```c++ 189 | // Расширенное линейное связное представление обобщенных таблиц 190 | typedef enum {ATOM, LIST} ElemTag; 191 | // ATOM == 0: атом, LIST == 1: дочерняя таблица 192 | typedef struct GLNode1 { 193 | ElemTag tag; 194 | // общая часть, используется для различия атомарных узлов от узлов таблицы 195 | union { 196 | // совместная часть атомарного узла и узла таблицы 197 | AtomType atom; // диапазон атомарных узлов 198 | struct GLNode1 *hp; // указатель указателя таблицы 199 | } a; 200 | struct GLNode1 *tp; 201 | // Эквивалент next линейного связного списка, указывающий на следующий 202 | } *GList1, GLNode1; 203 | ``` 204 | 205 | ### Бинарное дерево 206 | 207 | [//]: # (todo) 208 | [BinaryTree.cpp](DataStructure/BinaryTree.cpp) 209 | 210 | #### Свойства 211 | 212 | 1. До 2(i-1) узлов на i-м уровне непустого бинарного дерева (i> = 1) 213 | 2. Бинарное дерево с глубиной k до 2k-1 узла (k >= 1) 214 | 3. Количество узлов с степенью 0 равно n0, и количество узлов со степенью 2 равно n2, тогда n0 = n2 + 1 215 | 4. Глубина полного бинарного дерева с n узлами k = ⌊ log 2 (n) ⌋ + 1 216 | 5. Для узла с номером i (1 <= i <= n) в полном бинарном дереве с n узлами 217 | 1. Если i = 1, это корень, иначе родители равны ⌊ i / 2 ⌋ 218 | 2. Если 2i > n, у узла i нет левого ребенка, иначе номер ребенка равен 2i 219 | 3. Если 2i + 1> n, у узла i нет правого ребенка, иначе номер ребенка равен 2i + 1 220 | 221 | #### Структура хранения 222 | 223 | Структура данных бинарного дерева 224 | 225 | ```cpp 226 | typedef struct BiTNode 227 | { 228 | TElemType data; 229 | struct BiTNode *lchild, *rchild; 230 | }BiTNode, *BiTree; 231 | ``` 232 | 233 | ##### Последовательное хранение 234 | 235 | [//]: # (Изображения последовательного хранения бинарного дерева todo) 236 | 237 | ##### Цепное хранение 238 | 239 | [//]: # (Изображения цепного хранения бинарного дерева todo) 240 | 241 | #### Обход 242 | 243 | * Последовательный обход 244 | * Обход в порядке 245 | * Последующие обходы 246 | * Иерархический обход 247 | 248 | #### Категории 249 | 250 | * Полное бинарное дерево 251 | * Полное бинарное дерево (куча) 252 | * Большая вершина кучи: корень> = левый && корень> = правый 253 | * Маленькая вершина кучи: корень <= левый && корень <= правый 254 | * Бинарное дерево поиска (бинарное дерево сортировки): левый <корень <правый 255 | * Сбалансированное бинарное дерево (дерево AVL): | Высота левого поддерева-Высота правого поддерева | <= 1 256 | * Наименее несбалансированное дерево: Вставка новых узлов в сбалансированное бинарное дерево вызывает несбалансированное поддерево: Регулировка: 257 | * Тип LL: левый ребенок корня 258 | * Тип RR: правый ребенок корня 259 | * Тип LR: Левый ребенок корня, левый 260 | * Тип RL: Левый ребенок правого ребенка, сначала повернуть вправо, затем влево 261 | 262 | ### Другие деревья и леса 263 | 264 | #### Структура хранения дерева 265 | 266 | * Родительская нотация 267 | * Родительская нотация 268 | * Нотация ребенка-брата 269 | 270 | #### И проверка 271 | 272 | Набор непересекающихся подмножеств S = {S1, S2, ..., Sn} 273 | 274 | #### Сбалансированное бинарное дерево (дерево AVL) 275 | 276 | ##### Природа 277 | 278 | * | Высота левого поддерева дерева-Высота правого поддерева дерева | <= 1 279 | * Сбалансированное бинарное дерево должно быть бинарным деревом поиска, иначе это не обязательно 280 | * Формула узлов минимального бинарного сбалансированного дерева: `F(n) = F(n-1) + F(n-2) + 1` (1 - это корневой узел, F (n-1) - это количество узлов левого поддерева, F (n-2) - это количество узлов в правом поддереве) 281 | 282 | [//]: # (Изображения сбалансированного бинарного дерева todo) 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /materials/effective_cpp_1.md: -------------------------------------------------------------------------------- 1 | - ### *Эффективный C++* 2 | 3 | > Вторая часть [ здесь ](./effective_cpp_2.md) 4 | 5 | 1. Рассматривайте C++ как федерацию языков (C, Object-Oriented C++, Template C++, STL). 6 | 2. Позвольте компилятору заменить препроцессор (по возможности замените #define на const, enum, inline). 7 | 3. Используйте const как можно чаще. 8 | 9 | 4. Убедитесь, что объекты инициализированы перед использованием (инициализация при конструировании (конструктор 10 | копирования) эффективнее, чем инициализация после конструирования по умолчанию (оператор присваивания копирования)). 11 | 12 | 5. Знайте, какие функции C++ автоматически создает и вызывает компилятор (компилятор автоматически создает конструктор 13 | по умолчанию, конструктор копирования, оператор присваивания копирования и деструктор для класса). 14 | 15 | 6. Если вы не хотите использовать функции, автоматически созданные компилятором, явно откажитесь от них (объявите 16 | нежелательные функции-члены как private и не реализуйте их). 17 | 18 | 7. Объявляйте виртуальный деструктор для полиморфных базовых классов (если класс имеет хотя бы одну виртуальную функцию, 19 | он должен иметь виртуальный деструктор). 20 | 21 | 8. Не позволяйте исключениям покидать деструктор (деструктор должен поглощать исключения и не распространять их или 22 | завершать программу, а не выбрасывать исключения; если нужно обработать исключения, это должно делаться в обычных 23 | функциях, а не в деструкторе). 24 | 25 | 9. Никогда не вызывайте виртуальные функции в конструкторе или деструкторе (такие вызовы никогда не опускаются до 26 | производного класса). 27 | 28 | 10. Оператор = должен возвращать ссылку на *this (для цепочечного присваивания). 29 | 30 | 11. Обрабатывайте “самоприсваивание” в операторе =. 31 | 32 | 12. Управляйте ресурсами с помощью объектов (ресурсы получаются в конструкторе и освобождаются в деструкторе. 33 | Рекомендуется использовать интеллектуальные указатели. Момент получения ресурса — это момент инициализации (Resource 34 | Acquisition Is Initialization, RAII)). 35 | 13. Будьте осторожны с поведением копирования в классах управления ресурсами (обычное поведение копирования класса RAII: 36 | подавление копирования, подсчет ссылок, глубокое копирование, передача прав собственности на нижний ресурс ( 37 | аналогично auto_ptr)). 38 | 39 | 14. Предоставлять доступ к необработанным ресурсам в классе управления ресурсами (доступ к необработанным ресурсам может 40 | быть явно преобразован или неявно преобразован, вообще говоря, явное преобразование безопаснее, а неявное 41 | преобразование удобнее для клиентов). 42 | 43 | 15. Используйте ту же форму при использовании новых и удаленных в парах ( если new используется в [] середине delete [] 44 | и new если не используется в [] середине delete). 45 | 46 | 16. Сохраните (поместите) новый объект в интеллектуальный указатель в отдельном выражении (в противном случае это может 47 | привести к незаметным утечкам ресурсов из-за оптимизации компилятора). 48 | 49 | 17. Сделайте интерфейс легким для правильного использования и непростым для неправильного использования (методы 50 | содействия нормальному использованию: согласованность интерфейсов, совместимое поведение встроенных типов; методы 51 | предотвращения неправильного использования: создавать новые типы, ограничивать операции над типами, ограничивать 52 | значения объектов , устранить обязанности Заказчика по управлению ресурсами). 53 | 54 | 18. Разработка класса аналогична разработке типа: необходимо учитывать создание, уничтожение, инициализацию, 55 | присваивание, передачу значения, юридическое значение, отношение наследования, преобразование, обобщение и т. д. 56 | 57 | 19. Скорее замените передачу по значению на передачу по ссылке на константу (первая обычно более эффективна и позволяет 58 | избежать проблем с нарезкой, но не работает со встроенными типами, итераторами STL, функциональными объектами). 59 | 60 | 20. Когда вы должны вернуть объект, не пытайтесь вернуть его ссылку (никогда не возвращайте указатель или ссылку, 61 | указывающую на локальный объект стека, или возвращайте ссылку на объект, размещенный в куче, или возвращайте 62 | указатель, или ссылку на локальный объект). статический объект и может потребоваться несколько таких объектов.) 63 | 64 | 21. Объявить переменные-члены как частные (для инкапсуляции, согласованности, точного контроля над их чтением и записью 65 | и т. д.) 66 | 67 | 22. Скорее замените функции-члены функциями, не являющимися членами и не являющимися друзьями (улучшая инкапсуляцию, 68 | гибкость упаковки и функциональную масштабируемость). 69 | 70 | 23. Если все параметры (включая метафорический параметр, на который указывает указатель this) требуют преобразования 71 | типов, используйте для этого функции, не являющиеся членами. 72 | 73 | 24. Рассмотрите возможность написания функции подкачки, которая не генерирует исключений. 74 | 75 | 25. максимально задержать появление определений переменных (увеличивает ясность программы и повышает ее эффективность) 76 | 77 | 26. Старайтесь делать как можно меньше действий преобразования (старый стиль: (T)expression, T(expression); новый стиль: 78 | const_cast(expression), dynamic_cast(expression), , reinterpret_cast(expression), static_cast( 79 | expression),; старайтесь избегать преобразования, сосредоточьтесь на эффективности и избегайте dynamic_casts, 80 | старайтесь проектировать без преобразования, вы можете инкапсулировать преобразование в функцию, скорее используйте 81 | новое преобразование) 82 | 83 | 27. Избегайте использования дескрипторов (включая ссылки, указатели и итераторы) для указания внутри объектов (чтобы 84 | усилить инкапсуляцию, заставить константные функции-члены вести себя как константные и уменьшить вероятность 85 | «висячих дескрипторов» (таких как висячие указатели и т. д.)) 86 | 28. Тщательно изучите все тонкости встраивания (встраивание — это поведение во время компиляции в большинстве программ 87 | на C++; действительно ли встроенная функция является встроенной, зависит от компилятора; большинство компиляторов 88 | отклоняют слишком сложные функции (например, с циклами или рекурсией) для встраивания, а все вызовы виртуальных 89 | функций (кроме самых простых) также не будут встроены; увеличение кода, вызванное встраиванием, может привести к 90 | потере эффективности; встроенные функции нельзя обновить с помощью обновлений библиотеки). 91 | 29. Минимизируйте зависимости компиляции между файлами (если вы можете использовать ссылки на объекты или указатели на 92 | объекты для выполнения задачи, не используйте объекты; если можете, попробуйте заменить определение класса 93 | объявлением класса; предоставьте разницу между объявлением и заголовочным файлом определения). 94 | 30. Убедитесь, что ваше общедоступное наследование формирует отношение is-a (является) (все, что относится к базовым 95 | классам, должно применяться к производным классам, потому что каждый объект производного класса также является 96 | объектом базового класса). 97 | 31. Избегайте затенения унаследованных имен (вы можете использовать объявления using или функции пересылки (forwarding 98 | functions), чтобы затененные имена снова увидели свет). 99 | 32. Различайте наследование интерфейса и наследование реализации (при общедоступном наследовании производные классы 100 | всегда наследуют интерфейс базового класса; чистые виртуальные функции определяют только наследование интерфейса; 101 | нечистые виртуальные функции определяют наследование интерфейса и наследование реализации по умолчанию; 102 | невиртуальные функции определяют наследование интерфейса и обязательное наследование реализации). 103 | 104 | 33. Рассмотрите альтернативы виртуальным функциям (например, метод невиртуального интерфейса (NVI) шаблона 105 | проектирования Template Method, замените виртуальные функции «переменными-членами указателя на функцию», замените 106 | виртуальные функции переменными-членами и замените виртуальные функции в системе наследования tr1::function. 107 | является виртуальной функцией в другой иерархии наследования). 108 | 109 | 34. Никогда не переопределяйте унаследованные невиртуальные функции. 110 | 111 | 35. Никогда не переопределяйте унаследованные значения параметров по умолчанию, потому что значения параметров по 112 | умолчанию связаны статически (statically bound), а виртуальные функции связаны динамически (динамически связаны). 113 | 114 | 36. С помощью составления формируйте отношения has-a (имеет) или «реализуется согласно чему-то» (в прикладной области 115 | составное средство имеет-a (имеет одно); в области реализации составное средство -реализовано-с точки зрения-из ( 116 | реализовано в терминах)). 117 | 118 | 37. Разумно и осторожно используйте частное наследование (частное наследование означает "реализовано-в-терминах-из" ( 119 | реализовано в соответствии с чем-то), используйте композицию, когда это возможно, когда производному классу 120 | требуется доступ к членам защищенного базового класса или необходимо переопределить наследование. приходит 121 | виртуальная функция, или когда требуется пустая базовая оптимизация, используется приватное наследование). 122 | 123 | 38. Разумно и осторожно используйте множественное наследование (множественное наследование сложнее, чем одиночное 124 | наследование, может привести к новым неоднозначностям и необходимости виртуального наследования, но имеет законное 125 | использование, например, «общедоступный наследует класс интерфейса» и «частный наследует класс». для помощи в 126 | реализации»; виртуальное наследование может решить проблему неоднозначности алмазного наследования при множественном 127 | наследовании, но это увеличит стоимость размера, скорости, инициализации и сложности присваивания и т. д.). 128 | 129 | 39. Понимайте неявные интерфейсы и полиморфизм времени компиляции (классы и шаблоны поддерживают интерфейсы (interfaces) 130 | и полиморфизм (polymorphism); интерфейсы класса являются явными (explicit) и основаны на подписи, а полиморфизм 131 | происходит через виртуальные функции во время выполнения; интерфейсы шаблона являются неявными (implicit) и основаны 132 | на действительных выражениях, а полиморфизм происходит через конкретизацию шаблона и разрешение перегрузки функций ( 133 | function overloading resolution) во время компиляции). 134 | 135 | 40. Понимайте двойное значение typename (при объявлении параметра типа шаблона ключевые слова class и typename имеют 136 | абсолютно одинаковое значение; используйте ключевое слово typename для обозначения вложенных зависимых типовых имён, 137 | но не используйте его как модификатор базового класса в списках базовых классов или списках инициализации членов). 138 | 139 | 41. Изучите обработку имён в шаблонизированных базовых классах (в шаблонах производных классах можно ссылаться на члены 140 | шаблонных базовых классов через this-> или с помощью явного «квалификатора квалификации базового класса»). 141 | 142 | 42. Выделите код, не зависящий от параметров, из шаблонов (раздутие кода из-за параметров типа (non-type template 143 | parameters) часто можно устранить путем замены параметров шаблона параметрами функций или переменными-членами 144 | класса; раздутие кода из-за параметров типа (type parameters) часто можно устранить путем общего использования кода 145 | реализации типами реализации (instantiation types) с одинаковым бинарным представлением). 146 | 43. Используйте шаблоны функций-членов для принятия всех совместимых типов (используйте шаблоны функций-членов для 147 | создания функций, которые «принимают все совместимые типы»; объявляйте шаблоны функций-членов для «обобщенного 148 | копирования конструктора» или «обобщенной операции присваивания», когда вам также нужно объявить обычный конструктор 149 | копирования и оператор присваивания копирования). 150 | 151 | 44. Определите нечленские функции, когда требуется преобразование типов (когда вы пишете шаблон класса, и он 152 | предоставляет функции, связанные с этим шаблоном, которые поддерживают «неявное преобразование типов всех 153 | параметров», определите эти функции как «дружественные функции внутри шаблона класса»). 154 | 155 | 45. Используйте классы свойств для отображения информации о типах (классы свойств с помощью шаблонов и «специализации 156 | шаблонов» делают информацию о типах доступной во время компиляции, используя технику перегрузки (overloading) для 157 | выполнения тестов if…else для типов во время компиляции). 158 | 159 | 46. Познакомьтесь с метапрограммированием на шаблонах (метапрограммирование на шаблонах (TMP, template metaprogramming) 160 | позволяет переместить работу из времени выполнения во время компиляции, что позволяет обнаруживать ошибки раньше и 161 | повышать эффективность выполнения; TMP может использоваться для генерации пользовательского кода на основе 162 | комбинаций выбора политик, а также для предотвращения генерации кода, который не подходит для некоторых специальных 163 | типов). 164 | 165 | 47. Познакомьтесь с поведением new-handler (set_new_handler позволяет клиентам указать функцию, которая будет 166 | вызываться, если не удается удовлетворить запрос на выделение памяти; nothrow new является довольно ограниченным 167 | инструментом, поскольку он применим только к выделению памяти (operator new), а вызываемый затем конструктор все 168 | равно может выбросить исключение). 169 | 170 | 48. Познакомьтесь с правильным временем замены new и delete (чтобы обнаружить ошибки использования, собрать 171 | статистическую информацию об использовании динамически выделенной памяти, увеличить скорость выделения и 172 | освобождения, уменьшить дополнительные расходы на пространство, вызываемые менеджером памяти по умолчанию, исправить 173 | неоптимальное выравнивание в менеджере памяти по умолчанию, сгруппировать связанные объекты вместе, получить 174 | нетрадиционное поведение). 175 | 176 | 49. При написании new и delete следуйте общепринятым правилам (operator new должен содержать бесконечный цикл и в нем 177 | пытаться выделить память; если он не может удовлетворить запрос на память, он должен вызвать new-handler; он также 178 | должен иметь возможность обрабатывать запросы на 0 байт; версии класса также должны обрабатывать «неправильные ( 179 | ошибочные) запросы большего размера»; operator delete должен ничего не делать, если получает нулевой указатель; 180 | версии класса также должны обрабатывать «неправильные (ошибочные) запросы большего размера»). 181 | 182 | 50. Если вы написали placement new, напишите и placement delete (когда вы пишете placement operator new, убедитесь, что 183 | вы также написали соответствующий placement operator delete, иначе может произойти скрытая и периодическая утечка 184 | памяти; когда вы объявляете placement new и placement delete, убедитесь, что вы не закрываете их обычные версии). 185 | 186 | 51. Не игнорируйте предупреждения компилятора. 187 | 188 | 52. Ознакомьтесь со стандартной библиотекой, включая TR1 (TR1, C++ Technical Report 1, черновик стандарта C++11). 189 | 190 | 53. Ознакомьтесь с Boost (почти стандартная библиотека). 191 | 192 | > Часть вторая [Еще более эффективный C++](effective_cpp_2.md) -------------------------------------------------------------------------------- /materials/effective_cpp_2.md: -------------------------------------------------------------------------------- 1 | ### Более эффективный C++ 2 | 3 | 1. Тщательно различайте указатели и ссылки (когда вы знаете, что вам нужно указать на что-то и никогда не менять 4 | указание на другие вещи, или когда вы реализуете оператор, требования к синтаксису которого не могут быть выполнены 5 | указателями, вы должны выбирать ссылки; В любое другое время используйте указатели) 6 | 2. Лучше всего использовать операторы приведения типов 7 | C++ (`static_cast`, `const_cast`, `dynamic_cast`, `reinterpret_cast`) 8 | 3. Никогда не обрабатывайте массивы полиморфно (полиморфизм и арифметика указателей не могут быть смешаны; объекты 9 | массива почти всегда включают арифметику указателей, поэтому массивы и полиморфизм не должны смешиваться) 10 | 4. Не предоставляйте конструктор по умолчанию, если это необходимо (чтобы избежать бессмысленной инициализации полей в 11 | объекте) 12 | 5. Будьте настороже с пользовательскими "функциями преобразования типов" (конструкторы с одним аргументом можно избежать 13 | простыми методами (ключевые слова explicit) или прокси-классами); неявные операторы преобразования типов можно 14 | изменить на явные член-функции, чтобы избежать неожиданного поведения) 15 | 6. Различайте префиксные и постфиксные формы оператора инкремента/декремента (предварительно накапливайте и выдавайте 16 | ссылку; после подготовки принимайте, и накапливайте, и возвращайте const объект; при обработке пользовательских типов 17 | следует использовать предварительный инкремент как можно больше; пост-реализация должна основываться на его 18 | пред-брате) 19 | 7. Никогда не перегружайте операторы `&&`, `||` и `,` (перегрузка `&&` и `||` заменит "внезапно-семантическую семантику" 20 | на "семантику вызова функции"; перегрузка `,` не гарантирует, что левое выражение должно быть оценено раньше, чем 21 | правое выражение) 22 | 8. Понимайте различные значения new и 23 | delete (`new operator`, `operator new`, `placement new`, `operator new[]`; `delete operator`, `operator delete`, `destructor`, `operator delete[]`) 24 | 9. Используйте деструкторы, чтобы избежать утечки ресурсов (освобождение ресурсов при деструкторах может предотвратить 25 | утечки ресурсов во время исключений) 26 | 10. Предотвращайте утечки ресурсов в конструкторах (поскольку C++ будет деструктурировать только уже сконструированные 27 | объекты, конструктор может использовать try...catch или auto_ptr (и подобные классы) для обработки утечек ресурсов 28 | при возникновении исключений) 29 | 11. Запрещайте исключениям вытекать из деструкторов (причина: во-первых, избегайте вызова функции terminate в механизме 30 | размотки стека при распространении исключений; во-вторых, помогите обеспечить, чтобы деструкторы завершили все, что 31 | они должны сделать) 32 | 12. Понимайте разницу между "бросанием исключения" и "передачей параметра" или "вызовом виртуальной функции" (во-первых, 33 | объекты исключений всегда копируются (кроме указателя), если вы ловите даже по значению, он копируется дважды, но 34 | объект, переданный в параметр функции, не обязательно должен быть скопирован. Во-вторых, у объекта, который " 35 | бросается как исключения", меньше разрешенных действий преобразования типа, чем у объекта, "переданного в функцию"; 36 | в-третьих, catch-клаузу проверяет компилятор на ее "порядок, в котором она появляется в исходном коде". Первое 37 | совпадение удается и выполняется, и вызывается виртуальная функция. Функция") 38 | 13. Захватывайте исключения по ссылке (чтобы избежать проблемы удаления объекта и обрезания объектов исключений, 39 | сохраните возможность ловить стандартные исключения и ограничьте количество раз, когда объект исключения должен быть 40 | скопирован) 41 | 14. Мудро используйте спецификации исключений (спецификации исключений предоставляют отличное описание того, какие 42 | исключения функция ожидает бросить; есть также некоторые недостатки, включая то, что компилятор проверяет их только 43 | локально и легко непреднамеренно нарушает их. Предотвращайте обработку неожиданных исключений обработчиками 44 | исключений более высокого уровня) 45 | 15. Понимайте стоимость обработки исключений (грубо оценивая, если используется блок try, общий код расширится примерно на 5% -10%, и скорость выполнения также уменьшится на это число; поэтому, пожалуйста, ограничьте использование блока try и спецификации исключений до мест, где они обязательно должны использоваться, и бросайте исключения только в случае реальных исключений) 46 | 16. Имейте в виду правило 80-20 (общая производительность программного обеспечения почти всегда определяется небольшой частью его составных элементов (кодов), и код, который потребляет ресурсы, можно определить с помощью профилировщика программы) 47 | 17. Рассмотрите возможность использования ленивой оценки (можно применить к: подсчету ссылок для избежания ненужного копирования объектов, различиям между операциями чтения и записи оператора [] для выполнения разных действий, ленивой выборке (удаление) для избежания ненужного чтения базы данных, и ленивой оценке выражений (чтобы избежать ненужных числовых вычислений) 48 | 18. Распределите ожидаемую вычислительную стоимость (когда вы должны поддерживать определенные операции, структура которых почти всегда требуется, или когда результаты часто требуются несколько раз, чрезмерная оценка может улучшить эффективность программы) 49 | 50 | ### Руководство по стилю Google C++ 51 | 52 | * Английский: [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) 53 | 54 | ### Другое 55 | 56 | * [FAQ Бьярна Страуструпа](http://www.stroustrup.com/bs_faq.html) 57 | * [FAQ по стилю и трюкам C++ для Бьярна Страуструпа](http://www.stroustrup.com/bs_faq2.html) -------------------------------------------------------------------------------- /materials/memory.md: -------------------------------------------------------------------------------- 1 | ## *Выделение и управление памятью* 2 | 3 | #### malloc, calloc, realloc, alloca 4 | 5 | 1. malloc: запросить указанное количество байтов памяти. Начальное значение в запрошенной памяти неопределенно. 6 | 2. calloc: для объекта указанной длины выделить память, которая может содержать указанное количество объектов. Каждый 7 | бит запрошенной памяти инициализируется на 0. 8 | 3. realloc: изменить длину ранее выделенной памяти (увеличить или уменьшить). При увеличении длины может потребоваться 9 | перемещение содержимого ранее выделенной области в другую достаточно большую область, при этом начальное значение в 10 | новой добавленной области неопределенно. 11 | 4. alloca: запросить память на стеке. Когда программа выходит из стека, она автоматически освобождает память. Однако 12 | следует отметить, что alloca не является переносимой и сложной для реализации на машинах без традиционных стеков. 13 | alloca не следует использовать в программах, которые должны быть широко портированы. C99 поддерживает массивы 14 | переменной длины (VLAs) и может использоваться вместо alloca. 15 | 16 | #### malloc, free 17 | 18 | Используются для выделения и освобождения памяти 19 | 20 | Использование malloc, free 21 | 22 | Запросить память и подтвердить успешность заявки 23 | 24 | ```c++ 25 | char *str = (char*) malloc(100); 26 | assert(str != nullptr); 27 | ``` 28 | 29 | Указатель пуст после освобождения памяти 30 | 31 | ```c++ 32 | free(p); 33 | p = nullptr; 34 | ``` 35 | 36 | #### new、delete 37 | 38 | 1. new / new []: делают две вещи, сначала вызывают malloc на нижнем уровне для выделения памяти, а затем вызывают 39 | конструктор (создают объект). 40 | 2. delete / delete []: также выполняют две вещи, сначала вызывают деструктор (очищают ресурсы), а затем вызывают free на 41 | нижнем уровне для освобождения пространства. 42 | 3. new автоматически вычисляет количество требуемых байтов при запросе памяти, а malloc требует от нас ввода количества 43 | байтов запрошенного пространства памяти. 44 | 45 | Демонстрация new, delete 46 | 47 | Запросить память и подтвердить успешность заявки 48 | 49 | ```c++ 50 | int main() 51 | { 52 | T* t = new T(); // сначала выделение памяти, затем конструктор 53 | delete t; // сначала деструктор, затем освобождение памяти 54 | return 0; 55 | } 56 | ``` 57 | 58 | #### Позиционированный new 59 | 60 | Позиционированный new (placement new) позволяет нам передавать дополнительные адресные параметры в new для создания 61 | объектов в заранее указанной области памяти. 62 | 63 | ```c++ 64 | new (place_address) type 65 | new (place_address) type (initializers) 66 | new (place_address) type [size] 67 | new (place_address) type [size] { braced initializer list } 68 | ``` 69 | 70 | * `place_address` - это указатель 71 | * `initializers` предоставляет (возможно, пустой) список начальных значений, разделенных запятыми 72 | 73 | ### delete this - это законно? 74 | 75 | > [Законно ли (и морально) для функции-члена сказать delete this?](https://isocpp.org/wiki/faq/freestore-mgmt#delete-this) 76 | 77 | Законно, но: 78 | 79 | 1. Должно быть гарантировано, что этот объект выделен через `new` (не `new[]`, не позиционированный new, не на стеке, не 80 | глобальный, не член других объектов) 81 | 2. Вы должны гарантировать, что функция-член, которая вызывает delete this, является последней функцией-членом, которая 82 | вызывает this 83 | 3. Вы должны гарантировать, что функция-член не вызывает this после `delete this` 84 | 4. Убедитесь, что никто не использует его после delete this 85 | 86 | ### Как определить класс, который может генерировать объекты только на куче (на стеке)? 87 | 88 | > [Как определить класс, который может генерировать объекты только на куче (на стеке)?](https://www.nowcoder.com/questionTerminal/0a584aa13f804f3ea72b442a065a7618) 89 | 90 | #### Только на куче 91 | 92 | Метод: Сделать деструктор приватным 93 | 94 | Причина: C ++ - это язык со статической привязкой. Компилятор управляет жизненным циклом объектов на стеке. Когда 95 | компилятор выделяет стековое пространство для объектов класса, он сначала проверяет доступность деструктора класса. Если 96 | деструктор недоступен, объект не может быть создан на стеке. 97 | 98 | #### Только на стеке 99 | 100 | Метод: перегрузить new и delete как private 101 | 102 | Причина: Объект генерируется на куче с использованием операции new. Процесс делится на два этапа: на первом этапе 103 | используется new для поиска доступной памяти на куче и выделения ее объекту; на втором этапе вызывается конструктор для 104 | создания объекта. Установив операцию new в private, первый этап не может быть завершен, и объекты не могут быть 105 | сгенерированы на куче. 106 | 107 | ### Умный указатель 108 | 109 | #### В стандартной библиотеке C ++ (STL) 110 | 111 | файл заголовка:`#include ` 112 | 113 | #### C++ 98 114 | 115 | ```c++ 116 | std::auto_ptr ps (new std::string(str)); 117 | ``` 118 | 119 | #### C++ 11 120 | 121 | 1. shared_ptr 122 | 2. unique_ptr 123 | 3. weak_ptr 124 | 4. auto_ptr (Устарел в C ++ 11) 125 | 126 | * Класс shared_ptr реализует концепцию совместного владения. Несколько умных указателей указывают на один и тот же 127 | объект, и этот объект и его связанные ресурсы освобождаются, когда "последняя ссылка уничтожается". Для выполнения 128 | вышеуказанной работы в более сложных сценариях стандартная библиотека предоставляет вспомогательные классы, такие как 129 | weak_ptr, bad_weak_ptr и enable_shared_from_this. 130 | * Класс unique_ptr реализует концепцию исключительного владения или строгого владения, обеспечивая, чтобы только один 131 | умный указатель мог указывать на объект в одно и то же время. Вы можете передать владение. Это особенно полезно для 132 | избежания утечек ресурсов, таких как забывание удалить после new. 133 | 134 | ##### shared_ptr 135 | 136 | Несколько умных указателей могут делить один и тот же объект, и последний из объектов имеет обязанность уничтожить 137 | объект и очистить все ресурсы, связанные с объектом. 138 | 139 | * Поддержка пользовательского удалителя, которая может предотвратить проблемы Cross-DLL (объект создается с помощью new 140 | в динамической библиотеке ссылок (DLL), но удаляется другой DLL), и мьютекс автоматически освобождается 141 | 142 | ##### weak_ptr 143 | 144 | weak_ptr позволяет вам делиться, но не владеть объектом. Как только последний умный указатель, который владеет объектом, 145 | теряет владение, любой weak_ptr автоматически становится пустым. Поэтому, в дополнение к конструкторам по умолчанию и 146 | копированию, weak_ptr предоставляет только конструктор "принять shared_ptr". 147 | 148 | * Проблема циклов ссылок (два объекта, которые не использовались, фактически ссылаются друг на друга, заставляя их 149 | появляться в состоянии "использовано") 150 | 151 | ##### unique_ptr 152 | 153 | `unique_ptr` - это тип, который стал доступен только с `C ++ 11`, и это умный указатель, который может помочь избежать 154 | утечек ресурсов во время исключений. Используя исключительное владение, вы можете гарантировать, что объект и его 155 | соответствующий ресурс принадлежат только одному указателю в одно и то же время. Как только вы уничтожите владение или 156 | запрограммируете пустоту, или начнете владеть другим объектом, ранее владеемый объект будет уничтожен, и любые 157 | соответствующие ресурсы будут освобождены. 158 | 159 | * unique_ptr используется вместо auto_ptr 160 | 161 | ##### auto_ptr 162 | 163 | Устарел в c ++ 11 из-за отсутствия языковых функций, таких как семантика `std::move` "для конструирования и 164 | присваивания", и других недостатков. 165 | 166 | ##### Сравнение auto_ptr и unique_ptr 167 | 168 | * auto_ptr может быть присвоен копия, и владение передается после копирования; unqiue_ptr не имеет семантики 169 | присваивания копий, но реализует семантику `move`; 170 | * объекты auto_ptr не могут управлять массивами (разрушительный вызов `delete`), unique_ptr может управлять массивами ( 171 | разрушительный вызов` delete [] `); 172 | 173 | ### Оператор приведения типов 174 | 175 | > [MSDN. Оператор приведения типов](https://msdn.microsoft.com/zh-CN/library/5f6c9f8h.aspx) 176 | 177 | #### static_cast 178 | 179 | * Для неполиморфных преобразований 180 | * Не выполняет проверку типа во время выполнения (безопасность преобразования не так хороша, как у dynamic_cast) 181 | * Обычно используется для преобразования числовых типов данных (например, float-> int) 182 | * Вы можете перемещать указатель по всей иерархии классов. Это безопасно (восходящее преобразование) для преобразования 183 | дочернего класса в родительский класс, и это не безопасно для преобразования родительского класса в дочерний класс ( 184 | потому что в дочернем классе могут быть поля или методы, которых нет в родительском классе) 185 | 186 | > Восходящее приведение является неявным преобразованием. 187 | 188 | #### dynamic_cast 189 | 190 | * Для полиморфных преобразований типов 191 | * Выполняет проверку типа во время выполнения 192 | * Применим только к указателям или ссылкам 193 | * Преобразование неоднозначных указателей будет неудачным (вернет nullptr), но исключение не будет выброшено 194 | * Вы можете перемещать указатель по всей иерархии классов, включая восходящее преобразование, нисходящее преобразование 195 | 196 | #### const_cast 197 | 198 | * Используется для удаления const, volatile и __unaligned свойств (например, преобразование const int в int) 199 | 200 | #### reinterpret_cast 201 | 202 | * Простое переинтерпретация для битов 203 | * Неправильное использование оператора reinterpret_cast может быть очень рискованным. Если требуемое преобразование само 204 | по себе не является низкоуровневым, вы должны использовать один из других операторов приведения. 205 | * Позволяет преобразование любого указателя в любой другой тип указателя (например, `char *` в `int *` или `One_class *` 206 | в `Unrelated_class *`, но само по себе это не безопасно) 207 | * Также позволяет преобразование любого целочисленного типа в любой тип указателя и обратное преобразование. 208 | * Оператор reinterpret_cast не может потерять const, volatile или __unaligned атрибуты. 209 | * Практическое использование reinterpret_cast находится в хеш-функции, которая предназначена для отображения значений на 210 | индексы, делая два разных значения едва кончаются с тем же индексом. 211 | 212 | #### bad_cast 213 | 214 | * Оператор dynamic_cast выбрасывает исключение bad_cast, потому что приведение к ссылочному типу не удалось. 215 | 216 | Демонстрация bad_cast 217 | 218 | ```c++ 219 | try { 220 | Circle& ref_circle = dynamic_cast(ref_shape); 221 | } 222 | catch (bad_cast b) { 223 | cout << "Caught: " << b.what(); 224 | } 225 | ``` 226 | 227 | ### Информация о типе во время выполнения (RTTI) 228 | 229 | #### dynamic_cast 230 | 231 | * Для полиморфных преобразований типов 232 | 233 | #### typeid 234 | 235 | * Оператор typeid позволяет определить тип объекта во время выполнения 236 | * type \ _id возвращает ссылку на объект type \ _info 237 | * Если вы хотите получить тип данных производного класса через указатель базового класса, базовый класс должен иметь 238 | виртуальную функцию 239 | * Может получить только фактический тип объекта 240 | 241 | #### type_info 242 | 243 | * Класс type_info описывает информацию о типе, генерируемую компилятором в программе. Объекты этого класса могут 244 | эффективно хранить указатели на имена типов. Класс type_info также может хранить закодированные значения, подходящие 245 | для сравнения, равны ли два типа, или сравнения их порядка перестановки. Правила кодирования и порядок перестановки 246 | для типов не указаны и могут варьироваться от программы к программе. 247 | * Файл заголовка: `typeinfo` 248 | 249 | Демонстрация typeid, type_info 250 | 251 | ```c++ 252 | #include 253 | using namespace std; 254 | 255 | class Flyable // может летать 256 | { 257 | public: 258 | virtual void takeoff() = 0; // взлететь 259 | virtual void land() = 0; // приземлиться 260 | }; 261 | class Bird : public Flyable // птица 262 | { 263 | public: 264 | void foraging() {...} // добывать пищу 265 | virtual void takeoff() {...} 266 | virtual void land() {...} 267 | virtual ~Bird(){} 268 | }; 269 | class Plane : public Flyable // самолет 270 | { 271 | public: 272 | void carry() {...} // перевозить 273 | virtual void takeoff() {...} 274 | virtual void land() {...} 275 | }; 276 | 277 | class type_info 278 | { 279 | public: 280 | const char* name() const; 281 | bool operator == (const type_info & rhs) const; 282 | bool operator != (const type_info & rhs) const; 283 | int before(const type_info & rhs) const; 284 | virtual ~type_info(); 285 | private: 286 | ... 287 | }; 288 | 289 | void doSomething(Flyable *obj) // делать что-то 290 | { 291 | obj->takeoff(); 292 | 293 | cout << typeid(*obj).name() << endl; // вывод типа входящего объекта("class Bird" или "class Plane") 294 | 295 | if(typeid(*obj) == typeid(Bird)) // определение типа объекта 296 | { 297 | Bird *bird = dynamic_cast(obj); // преобразование объекта 298 | bird->foraging(); 299 | } 300 | 301 | obj->land(); 302 | } 303 | 304 | int main(){ 305 | Bird *b = new Bird(); 306 | doSomething(b); 307 | delete b; 308 | b = nullptr; 309 | return 0; 310 | } 311 | ``` 312 | -------------------------------------------------------------------------------- /materials/oop.md: -------------------------------------------------------------------------------- 1 | ## *ООП* 2 | 3 | Объектно-ориентированное программирование (ООП) - это модель программирования программ с объектными концепциями, а также 4 | абстрактный подход к разработке программ. 5 | 6 | ![Особенности объектно-ориентированного](../img/junior/UML_diagrams_overview.svg.png) 7 | 8 | Три особенности объектно-ориентированного - инкапсуляция, наследование и полиморфизм 9 | 10 | ### Инкапсуляция 11 | 12 | Инкапсулируйте объективные вещи в абстрактные классы, и классы могут использовать только свои собственные данные и 13 | методы для доверенных классов или объектов для работы, и скрывать недоверенную информацию. Ключевые слова: public, 14 | protected, private. Не пишите по умолчанию в private. 15 | 16 | * `public` члены: могут быть доступны любой сущности 17 | * `protected` члены: разрешено доступ только подклассам и функциям-членам этого класса 18 | * `private` члены: доступны только функциям-членам, классам-друзьям или функциям-друзьям этого класса 19 | 20 | ### Наследование 21 | 22 | * Базовый класс (родительский класс) ——> производный класс (подкласс) 23 | 24 | #### Полиморфизм 25 | 26 | * Полиморфизм, то есть множественные состояния (формы). Проще говоря, мы можем определить полиморфизм как способность 27 | сообщения отображаться в нескольких формах. 28 | * Полиморфизм основан на инкапсуляции и наследовании. 29 | * Классификация и реализация полиморфизма C: 30 | 1. Ad-hoc Полиморфизм (во время компиляции): перегрузка функций, перегрузка операторов 31 | 2. Подтип Полиморфизма (во время выполнения): виртуальная функция 32 | 3. Параметрический Полиморфизм (во время компиляции): шаблон класса, шаблон функции 33 | 4. Принудительный Полиморфизм (компиляция / выполнение): базовое преобразование типов, пользовательское 34 | преобразование типов 35 | 36 | > [Четыре Полиморфизма в C++](https://catonmat.net/cpp-polymorphism) 37 | 38 | #### Статический полиморфизм (во время компиляции / раннее связывание) 39 | 40 | Перегрузка функций 41 | 42 | ```c++ 43 | class A 44 | { 45 | public: 46 | void do(int a); 47 | void do(int a, int b); 48 | }; 49 | ``` 50 | 51 | #### Динамический полиморфизм (во время выполнения / позднее связывание) 52 | 53 | * Виртуальные функции: украшают функции-члены виртуальными, чтобы сделать их виртуальными 54 | * Динамическое связывание: динамическое связывание происходит, когда виртуальная функция вызывается с использованием 55 | ссылки или указателя на базовый класс 56 | 57 | **заметка:** 58 | 59 | * Вы можете присвоить объект производного класса указателю или ссылке базового класса, и наоборот 60 | * Обычные функции (не функции-члены класса) не могут быть виртуальными функциями 61 | * Статические функции (static) не могут быть виртуальными функциями 62 | * Конструктор не может быть виртуальной функцией (потому что когда вызывается конструктор, указатель виртуальной таблицы 63 | не находится в пространстве памяти объекта, указатель виртуальной таблицы должен быть сформирован после вызова 64 | конструктора) 65 | * Встроенная функция не может быть виртуальной функцией, когда она показывает полиморфизм. Для объяснения см.:Может ли 66 | виртуальная функция быть встроенной функцией? 67 | 68 | -
Ответ: 69 | Виртуальная функция может быть объявлена как встроенная с помощью ключевого слова inline, но компилятор может проигнорировать это объявление. Виртуальные функции обычно не являются встроенными, потому что они используют механизм динамического связывания, который требует определения адреса функции во время выполнения. Встроенные функции, с другой стороны, вставляются непосредственно в точку вызова во время компиляции 70 |
71 | 72 | Демо динамического полиморфизма 73 | 74 | ```c++ 75 | class Shape // класс формы 76 | { 77 | public: 78 | virtual double calcArea() 79 | { 80 | ... 81 | } 82 | virtual ~Shape(); 83 | }; 84 | class Circle : public Shape // класс круга 85 | { 86 | public: 87 | virtual double calcArea(); 88 | ... 89 | }; 90 | class Rect : public Shape // класс прямоугольника 91 | { 92 | public: 93 | virtual double calcArea(); 94 | ... 95 | }; 96 | int main() 97 | { 98 | Shape * shape1 = new Circle(4.0); 99 | Shape * shape2 = new Rect(5.0, 6.0); 100 | shape1->calcArea(); // вызов метода в классе круга 101 | shape2->calcArea(); // вызов метода в классе прямоугольника 102 | delete shape1; 103 | shape1 = nullptr; 104 | delete shape2; 105 | shape2 = nullptr; 106 | return 0; 107 | } 108 | ``` 109 | 110 | ### Виртуальный деструктор 111 | 112 | Виртуальный деструктор - это для разрешения указателя базового класса на объект производного класса и удаления объекта 113 | производного класса с помощью указателя базового класса. 114 | 115 | Демо виртуального деструктора 116 | 117 | ```c++ 118 | class Shape 119 | { 120 | public: 121 | Shape(); // Конструктор не может быть виртуальным 122 | virtual double calcArea(); 123 | virtual ~Shape(); // виртуальный деструктор 124 | }; 125 | class Circle : public Shape // класс круга 126 | { 127 | public: 128 | virtual double calcArea(); 129 | ... 130 | }; 131 | int main() 132 | { 133 | Shape * shape1 = new Circle(4.0); 134 | shape1->calcArea(); 135 | delete shape1; // Поскольку у Shape есть виртуальный деструктор, когда delete удаляет память, он сначала вызывает деструктор подкласса, а затем деструктор базового класса, чтобы предотвратить утечки памяти. 136 | shape1 = NULL; 137 | return 0; 138 | } 139 | ``` 140 | 141 | ### Чистые виртуальные функции 142 | 143 | Чистая виртуальная функция - это особый вид виртуальной функции. Вы не можете дать значимую реализацию виртуальной 144 | функции в базовом классе. Вместо этого вы объявляете его как чистую виртуальную функцию. Его реализация оставлена для 145 | производных классов базового класса. 146 | 147 | ```c++ 148 | virtual int A() = 0; 149 | ``` 150 | 151 | ### Виртуальные функции и чисто виртуальные функции 152 | 153 | * Если в классе объявлена виртуальная функция, она реализуется, даже если она пуста. Её роль заключается в том, чтобы 154 | позволить этой функции быть переопределенной в подклассах. Так компилятор может использовать позднее связывание для 155 | достижения полиморфизма. Чисто виртуальная функция — это всего лишь интерфейс. Это объявление функции. Её реализацию 156 | необходимо оставить в подклассе. 157 | * Виртуальные функции не могут быть переопределены в подклассах, но чисто виртуальные функции должны быть реализованы в 158 | подклассах для создания экземпляров подклассов. 159 | * Виртуальный класс используется для "наследования реализации". Наследование интерфейса также означает наследование 160 | реализации родительского класса. Чисто виртуальные функции сосредотачиваются на единообразии интерфейса, а реализация 161 | выполняется подклассами. 162 | * Класс с чисто виртуальной функцией называется абстрактным классом. Этот класс не может напрямую создавать объекты. Он 163 | может быть использован только после наследования и переопределения его виртуальной функции. После наследования 164 | абстрактного класса подклассы могут оставаться абстрактными или стать обычными классами. 165 | * Виртуальный базовый класс — это базовый класс в виртуальном наследовании, подробности см. ниже. 166 | 167 | > [C++ и связь виртуальных функций и pure виртуальных функций](virtual_functs.md) 168 | 169 | ### Указатель на виртуальную функцию, таблица виртуальных функций 170 | 171 | * Указатель на виртуальную функцию: В объекте, содержащем класс виртуальной функции, он указывает на таблицу виртуальных 172 | функций, которая определяется во время выполнения. 173 | * Таблица виртуальных функций: в программе в разделе только для чтения данных (`.rodata section`, 174 | см.: [структура хранения объектного файла](https://blog.twofei.com/496/)) хранятся указатели на виртуальные функции. 175 | Если производный класс реализует виртуальную функцию базового класса, указатель на виртуальную функцию исходного 176 | базового класса перезаписывается в виртуальной таблице и создается в соответствии с объявлением класса на этапе 177 | компиляции. 178 | 179 | > [Механизм реализации функции (таблицы) C++ и моделирование реализации на языке C](https://blog.twofei.com/496/) 180 | 181 | ### Виртуальное наследование 182 | 183 | Виртуальное наследование используется для решения проблемы ромбовидного наследования в условиях множественного 184 | наследования (тратится место хранения и возникает неоднозначность). 185 | 186 | Принцип реализации на нижнем уровне связан с компилятором. Обычно он реализуется с помощью **указателя на виртуальный 187 | базовый класс** и **таблицы виртуального базового класса**. Каждый подкласс, наследуемый виртуально, имеет указатель на 188 | виртуальный базовый класс (занимает место хранения указателя, 4 байта) и таблицу виртуального базового класса (не 189 | занимает место хранения объектов класса) (Следует подчеркнуть, что виртуальный базовый класс все равно будет иметь копию 190 | в подклассе, но будет не более одной копии, а не внутри подкласса); когда подкласс виртуального наследования наследуется 191 | в качестве родительского класса, указатель на виртуальный базовый класс также будет унаследован. 192 | 193 | На самом деле, `vbptr` относится к указателю на виртуальную базовую таблицу. Этот указатель указывает на виртуальную 194 | базовую таблицу. Виртуальная таблица записывает смещение адреса виртуального базового класса и этого класса. Смещение 195 | адреса, чтобы были найдены члены виртуального базового класса, и виртуальное наследование не нужно поддерживать две 196 | идентичные копии общего базового класса (виртуального базового класса), как это делается при обычном множественном 197 | наследовании, экономя место хранения. 198 | 199 | ### Виртуальное наследование, виртуальные функции 200 | 201 | * Сходства: Оба используют виртуальные указатели (оба занимают место в классе) и виртуальные таблицы (оба не занимают 202 | место в классе) 203 | * Разница: 204 | * Виртуальное наследование 205 | * Виртуальный базовый класс все еще существует в наследуемом классе и занимает только место в памяти 206 | * Таблица виртуального базового класса хранит смещение виртуального базового класса относительно прямого 207 | наследуемого класса 208 | * Виртуальная функция 209 | * Виртуальные функции не занимают место в памяти 210 | * Таблица виртуальных функций хранит адрес виртуальной функции 211 | 212 | ### Шаблонные классы, шаблоны членов, виртуальные функции 213 | 214 | * Виртуальные функции могут использоваться в шаблонных классах 215 | * Шаблон члена класса (будь то обычный класс или шаблон класса) (это функция-член шаблона) не может быть виртуальной 216 | функцией 217 | 218 | ### Абстрактный класс, интерфейсный класс, агрегатный класс 219 | 220 | * Абстрактный класс: класс, содержащий чистые виртуальные функции 221 | * Интерфейсный класс: Абстрактный класс, содержащий только чистые виртуальные функции 222 | * Агрегатные классы: Пользователи могут напрямую обращаться к их членам и имеют специальный синтаксис инициализации. 223 | Соответствуют следующим характеристикам: 224 | * Все члены являются общедоступными 225 | * Конструктор не определен 226 | * Нет инициализации в классе 227 | * Нет базового класса, нет виртуальной функции 228 | -------------------------------------------------------------------------------- /materials/problems.md: -------------------------------------------------------------------------------- 1 | # Задачи 2 | 3 | ### Leet-Code 4 | 5 | ### Code-Run 6 | 7 | ### Yandex Contest 8 | 9 | ### Как пройти собеседование по программированию. -------------------------------------------------------------------------------- /materials/virtual_functs.md: -------------------------------------------------------------------------------- 1 | ## *Разница и связь между виртуальными функциями и чисто виртуальными функциями в C++* 2 | В C++ виртуальные функции и чисто `(pure)` виртуальные функции отличаются следующим образом: 3 | 4 | 1. Если в классе объявлена виртуальная функция, эта функция реализована, даже если это пустая реализация. Её задача - 5 | позволить эту функцию быть переопределенной в его подклассах, таким образом, компилятор может использовать позднее 6 | связывание для достижения полиморфизма. Чисто виртуальная функция - это просто интерфейс, это только объявление 7 | функции, его реализация должна быть в подклассах. 8 | 9 | 2. Виртуальная функция в подклассе может не быть переопределена; но чисто виртуальная функция должна быть реализована в 10 | подклассе, это похоже на интерфейс в Java. Обычно добавление `virtual` к большому количеству функций считается 11 | хорошей практикой, хотя это и ухудшает производительность, но увеличивает полиморфность объектно-ориентированного 12 | программирования, потому что трудно предсказать, не будет ли функция в родительском классе изменена в подклассе. 13 | 14 | 3. Класс с виртуальной функцией используется для "реализации наследования", наследуя интерфейс и одновременно реализацию 15 | родительского класса. Конечно, вы также можете завершить свою собственную реализацию. Чисто виртуальная функция 16 | фокусируется на единообразии интерфейса, реализация выполняется подклассами. 17 | 18 | 4. Класс с чисто виртуальной функцией называется виртуальным базовым классом, такой базовый класс не может напрямую 19 | создавать объекты, он может быть использован только при наследовании и переопределении его виртуальных функций. Такой 20 | класс также называется абстрактным классом. Абстрактный класс и обычно упоминаемый виртуальный базовый класс 21 | отличаются, в C# для определения абстрактного класса используется `abstract`, а в C++ есть понятие абстрактного 22 | класса, но нет такого ключевого слова. После наследования абстрактного класса подкласс может продолжать быть 23 | абстрактным классом, или может быть обычным классом, а виртуальный базовый класс, который содержит чисто виртуальные 24 | функции, если он наследуется, то подкласс должен реализовать все чисто виртуальные функции в виртуальном базовом 25 | классе, его подкласс не может быть абстрактным классом. 26 | 27 | Чисто виртуальная функция 28 | Класс, объявивший чисто виртуальную функцию, является абстрактным классом. Поэтому пользователи не могут создавать 29 | экземпляры класса, они могут создавать только экземпляры его подклассов. Наиболее заметной особенностью чисто 30 | виртуальных функций является то, что они должны быть заново объявлены в классе наследнике (без `=0` в конце, иначе этот 31 | подкласс тоже не может быть инстанцирован), и они часто не имеют определения в абстрактном классе. Цель определения 32 | чисто виртуальной функции - заставить подклассы наследовать только интерфейс функции. Смысл чисто виртуальной функции 33 | заключается в том, что все объекты класса (в основном объекты подкласса) могут выполнять действия чисто виртуальной 34 | функции, но класс не может предоставить разумную реализацию по умолчанию для чисто виртуальной функции. Поэтому 35 | объявление чисто виртуальной функции класса говорит дизайнеру подкласса: "Вы должны предоставить реализацию чисто 36 | виртуальной функции, но я не знаю, как вы ее реализуете". Кстати, определение чисто виртуальной функции также возможно. 37 | То есть вы можете предоставить реализацию для чисто виртуальной функции, компилятор C++ не будет препятствовать этому ( 38 | компилятор DEV_CPP G++ (gcc 3.4.2) не поддерживает определение поведения по умолчанию для чисто виртуальной функции; в 39 | VC6.0 поддерживается определение поведения по умолчанию для чисто виртуальной функции, виртуальная функция подкласса 40 | переопределяет чисто виртуальную функцию базового класса), но единственный способ вызвать его - полностью указать имя 41 | класса, который вызывает его (например, `pb->Base:: pureVirtual()`). Иногда объявление класса, который не содержит 42 | ничего, кроме чисто виртуальной функции, бывает полезным. Такой класс называется классом протокола (Protocol class), он 43 | предоставляет подклассам только интерфейс функции, не имея вообще никакой реализации. 44 | 45 | Виртуальная функция (здесь подразумевается не чисто виртуальная функция) 46 | Ситуация с виртуальной функцией немного отличается от чисто виртуальной функции. Как правило, подкласс наследует 47 | интерфейс функции, но простая виртуальная функция обычно также предоставляет реализацию, подкласс может выбрать 48 | переопределение (override) или не переопределять их. Цель объявления виртуальной функции - заставить подкласс 49 | наследовать интерфейс функции и реализацию по умолчанию. Смысл виртуальной функции заключается в том, что каждый класс 50 | должен предоставить виртуальную функцию, которую можно вызвать, но каждый класс может обрабатывать ее любым способом, 51 | который они считают подходящим. Если некоторый класс не хочет делать что-то особенное, он может использовать функцию 52 | обработки по умолчанию, предоставленную в базовом классе. То есть объявление виртуальной функции говорит дизайнеру 53 | подкласса: "Вы должны поддерживать виртуальную функцию, но если вы не хотите писать свою версию, вы можете использовать 54 | версию по умолчанию в базовом классе". На самом деле, предоставление объявления функции и реализации по умолчанию для в -------------------------------------------------------------------------------- /problems.md: -------------------------------------------------------------------------------- 1 | # my list problems 2 | 3 | | N | Title | tags | Comments | 4 | |:---:|:-------------------------------------------------------------------------------------:|:----:|:--------:| 5 | | 1. | [Delete Smiles](./src/problems/task_001.cpp) | | | 6 | | 2. | [Simplify Path](./src/problems/task_002.cpp) | | | 7 | | 3. | [356. Line Reflection](./src/problems/task_003.cpp) | | | 8 | | 4. | [Meeting room 1 and 2](./src/problems/task_004.cpp) | | | 9 | | 5. | [151. Reverse Words in a String](./src/problems/task_005.cpp) | | | 10 | | 6. | [2657. Find the Prefix Common Array of Two Arrays](./src/problems/task_006.cpp) | | | 11 | | 7. | [287. Find the Duplicate Number](./src/problems/task_007.cpp); | | | 12 | | 8. | [Find sum eq to k](./src/problems/task_008.cpp) | | | 13 | | 9. | [99. Recover Binary Search Tree](./src/problems/task_009.cpp) | | | 14 | | 10. | [Revers list from L to R](./src/problems/task_010.cpp) | | | 15 | | 11. | [228. Summary Ranges](./src/problems/task_011.cpp) | | | 16 | | 12. | [234. Palindrome Linked List](./src/problems/task_012.cpp) | | | 17 | | 13. | [238. Product of Array Except Self](./src/problems/task_013.cpp) | | | 18 | | 14. | [28. Find the Index of the First Occurrence in a String](./src/problems/task_014.cpp) | | | 19 | | 15. | [279. Perfect Squares](./src/problems/task_015.cpp) | | | 20 | | 16. | [150. Evaluate Reverse Polish Notation](./src/problems/task_016.cpp) | | | 21 | | 17. | [Longest sub array](./src/problems/task_017.cpp) | | | 22 | | 18. | [Is one edit distance](./src/problems/task_018.cpp) | | | 23 | | 19. | [283. Move zeros](./src/problems/task_019.cpp) | | | 24 | | 20. | [22. Generate Parentheses](./src/problems/task_020.cpp) | | | 25 | | 21. | [206. Reverse Linked List](./src/problems/task_021.cpp) | | | 26 | | 22. | [49. Group Anagrams](./src/problems/task_021.cpp) | | | 27 | | 23. | [125. Valid Palindrome](./src/problems/task_023.cpp) | | | 28 | | 24. | [56. Merge Intervals](./src/problems/task_024.cpp) | | | 29 | | 25. | [98. Validate Binary Search Tree](./src/problems/task_025.cpp) | | | 30 | | 26. | [20. Valid Parentheses](./src/problems/task_026.cpp) | | | 31 | | 27. | [42. Trapping Rain Water](./src/problems/task_027.cpp) | | | 32 | | 28. | [LRE problem](./src/problems/task_028.cpp) | | | 33 | | 29. | [map with get random element](./src/problems/task_029.cpp) | | | 34 | | 30. | [Get second max](./src/problems/task_030.cpp) | | | 35 | | 31. | [560. Subarray Sum Equals K](./src/problems/task_031.cpp) | | | 36 | | 32. | [438. Find All Anagrams in a String](./src/problems/task_032.cpp) | | | 37 | | 33. | [415. Add Strings](./src/problems/task_033.cpp) | | | -------------------------------------------------------------------------------- /questions-400/readme.md: -------------------------------------------------------------------------------- 1 | # 400 ВОПРОСОВ НА СОБЕСЕДОВАНИИ ПО С++ 2 | 3 | - Дорогой мой читатель, я, как и вы, когда-то был начинающим или Буду как вы опытным программистом на C++. В интернете 4 | очень много информации, 5 | но тяжело найти именно то, что нужно. Случайно я увидел 400 вопросов для разработчика на C++ и у меня появилось 6 | желание создать небольшой гайд-шпаргалку на русском языке. На самом деле, я сделал этот гайд для себя, чтобы 7 | подготовиться к собеседованию. Когда я писал этот монолог, у меня уже были готовые вопросы и ответы для уровня junior. 8 | Дорогой мой читатель, если у вас есть хорошая идея или вы хотите внести свой вклад, пожалуйста, не стесняйтесь и 9 | пишите мне в телеграм @jollu8. Я постараюсь помочь. Кстати, у меня есть еще 10 | сборник [алгоритмов](https://github.com/Jollu8/Algorithms) на языке C++ и 11 | Яндекс контест алгоритмы на языке C++. Желаю вам удачи в поиске работы! С Уважением, Джолу 12 | 13 | - ## [1.Junior](./junior.md) 14 | 15 | 1. Общие вопросы 16 | 2. Мета программирование 17 | 3. Препроцессор и компиляция 18 | 4. Язык C 19 | 5. c++ OOP 20 | 6. STL / Algorithms 21 | 7. Multithreading 22 | 8. Networking 23 | 9. OS / Linux 24 | 10. SCM / CI / CD 25 | 11. Practise tasks 26 | 27 | --- 28 | 29 | - ## [2.Middle](./middle.md) 30 | 31 | 1. Общее 32 | 2. Препроцессор и компиляция 33 | 3. C 34 | 4. C++ 35 | 5. Паттерны проектирования 36 | 6. Метапрограммирование 37 | 7. OOP/OOD 38 | 8. STL/Algorithms 39 | 9. Многопоточность 40 | 10. Networking 41 | 11. SCM/CI/CD 42 | 12. Практические задачи 43 | -------------------------------------------------------------------------------- /questions-400/senior.md: -------------------------------------------------------------------------------- 1 | # Senior 2 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # СТАШИК ПО С++: 2 | 3 |
💡ВКЛ 4 | 📚 Этот репозиторий представляет собой сборник базовых знаний для соискателей и новичков в области технологий C / C ++. 5 | Он включает в себя информацию о языке, программных библиотеках, структурах данных, алгоритмах, системах, сетях, 6 | библиотеках для работы со ссылками и других знаниях и опыте, необходимых для собеседований, набора персонала, карьерного 7 | роста и т.д. 8 | 🙏 Если в содержании репозитория есть ошибки или есть предложения по улучшению, мы приветствуем ваши вопросы или 9 | предложения. Обсуждения можно начать в [вопросе № 3](https://github.com/Jollu8/C-INTERVIEW-QUESTIONS/issues/3). Из-за 10 | моего ограниченного уровня, знания в репозитории основаны на моих заметках, книгах, блогах и т.д. Все неоригинальные 11 | материалы были отмечены источником. Если есть какие-либо упущения, пожалуйста, задайте вопрос. Все источники материалов 12 | указаны внизу этой страницы.
13 | 14 | # 📑 Содержание 15 | 16 | - `Практический учебный план >>` [ссылке](./start.md) 17 | 18 | ### ➕ [Си/С++](./materials/base.md) 19 | ### 🎓 [400 Вопросов на собеседование по С++](questions-400/readme.md) 20 | ### ⭐️ [Эффективный](./materials/effective_cpp_1.md) 21 | ### 📦 [STL](./materials/STL.md) 22 | ### 〽️ [Структура данных](./materials/data_structures.md) 23 | ### ⚡️ [Алгоритм](http://www.github.com/Jollu8/Algorithms) 24 | ### ❓ [Задачи](materials/problems.md) 25 | ### 💻 [ОС](materials/OS.md) 26 | ### ☁️ Компьютерная сеть 27 | ### 🌩 Сетевое программирование 28 | ### 💾 [База данных теория и пркатика (ru) ](https://stepik.org/course/63054/syllabus) И [практика leetcode](https://leetcode.com/studyplan/top-sql-50/) 29 | ### 📏 [System design](https://github.com/madd86/awesome-system-design) 30 | ### ⚙️ Библиотека загрузки ссылок 31 | 32 | ### 📚 [Книги](./materials/books.md) 33 | ### 🔱 Направление разработки C/C++ 34 | ### 💯 [Еще плюшки от дяди Джолу](./problems.md) 35 | ### 📝 Опыт вопросов на собеседовании 36 | ### 📆 Поиск Работы 37 | ### 👍 Рекомендую 38 | ### 👬 Автор 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/junior/code_4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | std::stack myStack; 7 | std::queue myQueue; 8 | 9 | // Добавление элементов в стек 10 | myStack.push(1); 11 | myStack.push(2); 12 | myStack.push(3); 13 | 14 | // Извлечение элементов из стека 15 | while (!myStack.empty()) { 16 | std::cout << myStack.top() << ' '; 17 | myStack.pop(); 18 | } 19 | std::cout << std::endl; 20 | 21 | // Добавление элементов в очередь 22 | myQueue.push(1); 23 | myQueue.push(2); 24 | myQueue.push(3); 25 | 26 | // Извлечение элементов из очереди 27 | while (!myQueue.empty()) { 28 | std::cout << myQueue.front() << ' '; 29 | myQueue.pop(); 30 | } 31 | std::cout << std::endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/junior/code_9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class PizzaBuilder { 5 | public: 6 | virtual ~PizzaBuilder() {} 7 | virtual void buildDough() = 0; 8 | virtual void buildSauce() = 0; 9 | virtual void buildTopping() = 0; 10 | }; 11 | 12 | class HawaiianPizzaBuilder : public PizzaBuilder { 13 | public: 14 | void buildDough() { std::cout << "Hawaiian pizza dough\n"; } 15 | void buildSauce() { std::cout << "Hawaiian pizza sauce\n"; } 16 | void buildTopping() { std::cout << "Hawaiian pizza topping\n"; } 17 | }; 18 | 19 | class SpicyPizzaBuilder : public PizzaBuilder { 20 | public: 21 | void buildDough() { std::cout << "Spicy pizza dough\n"; } 22 | void buildSauce() { std::cout << "Spicy pizza sauce\n"; } 23 | void buildTopping() { std::cout << "Spicy pizza topping\n"; } 24 | }; 25 | 26 | class Cook { 27 | public: 28 | void setPizzaBuilder(PizzaBuilder* builder) { this->builder = builder; } 29 | void constructPizza() { 30 | builder->buildDough(); 31 | builder->buildSauce(); 32 | builder->buildTopping(); 33 | } 34 | private: 35 | PizzaBuilder* builder; 36 | }; 37 | 38 | int main() { 39 | Cook cook; 40 | HawaiianPizzaBuilder hawaiianPizzaBuilder; 41 | SpicyPizzaBuilder spicyPizzaBuilder; 42 | 43 | cook.setPizzaBuilder(&hawaiianPizzaBuilder); 44 | cook.constructPizza(); 45 | 46 | cook.setPizzaBuilder(&spicyPizzaBuilder); 47 | cook.constructPizza(); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/junior/jcode_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Singleton { 4 | public: 5 | static Singleton& getInstance() { 6 | static Singleton instance; 7 | return instance; 8 | } 9 | private: 10 | Singleton() {} 11 | Singleton(const Singleton&); 12 | Singleton& operator=(const Singleton&); 13 | }; 14 | 15 | int main() { 16 | Singleton& s1 = Singleton::getInstance(); 17 | Singleton& s2 = Singleton::getInstance(); 18 | 19 | if (&s1 == &s2) { 20 | std::cout << "s1 and s2 are the same instance\n"; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/junior/jcode_101.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Color; 3 | class Animal { 4 | public: 5 | virtual void eat(); 6 | // ... 7 | }; 8 | 9 | // Two classes virtually inheriting Animal: 10 | class Mammal : public virtual Animal { 11 | public: 12 | Color getHairColor(); 13 | // ... 14 | }; 15 | 16 | class WingedAnimal : public virtual Animal { 17 | public: 18 | void flap(); 19 | // ... 20 | }; 21 | 22 | // A bat is still a winged mammal 23 | class Bat : public Mammal, public WingedAnimal {}; 24 | -------------------------------------------------------------------------------- /src/junior/jcode_11.cpp: -------------------------------------------------------------------------------- 1 | //// 2 | 3 | //#include 4 | // 5 | //int add(int a, int b) { 6 | // return a + b; 7 | //} 8 | // 9 | //TEST(AddTest, PositiveNumbers) { 10 | //EXPECT_EQ(add(1, 2), 3); 11 | //EXPECT_EQ(add(10, 20), 30); 12 | //} 13 | // 14 | //TEST(AddTest, NegativeNumbers) { 15 | //EXPECT_EQ(add(-1, -2), -3); 16 | //EXPECT_EQ(add(-10, -20), -30); 17 | //} 18 | // 19 | //int main(int argc, char **argv) { 20 | // ::testing::InitGoogleTest(&argc, argv); 21 | // return RUN_ALL_TESTS(); 22 | //} 23 | -------------------------------------------------------------------------------- /src/junior/jcode_14_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | class MyPair { 5 | public: 6 | MyPair(T first, T second) : first(first), second(second) {} 7 | T getFirst() const { return first; } 8 | T getSecond() const { return second; } 9 | private: 10 | T first; 11 | T second; 12 | }; 13 | 14 | int main() { 15 | MyPair intPair(1, 2); 16 | std::cout << intPair.getFirst() << ' ' << intPair.getSecond() << '\n'; 17 | 18 | MyPair stringPair("hello", "world"); 19 | std::cout << stringPair.getFirst() << ' ' << stringPair.getSecond() << '\n'; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/junior/jcode_14_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | T getMax(T a, T b) { 5 | return (a > b) ? a : b; 6 | } 7 | 8 | int main() { 9 | std::cout << getMax(1, 2) << '\n'; 10 | std::cout << getMax(3.14, 2.71) << '\n'; 11 | std::cout << getMax("hello", "world") << '\n'; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /src/junior/jcode_15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class MyClass { 5 | public: 6 | // Конструктор по умолчанию 7 | MyClass() { 8 | std::cout << "Default constructor\n"; 9 | } 10 | 11 | // Конструктор с параметрами 12 | MyClass(int x) : x(x) { 13 | std::cout << "Parameterized constructor\n"; 14 | } 15 | 16 | // Конструктор копирования 17 | MyClass(const MyClass& other) : x(other.x) { 18 | std::cout << "Copy constructor\n"; 19 | } 20 | 21 | // Конструктор перемещения 22 | MyClass(MyClass&& other) : x(other.x) { 23 | std::cout << "Move constructor\n"; 24 | } 25 | 26 | private: 27 | int x; 28 | }; 29 | 30 | int main() { 31 | MyClass a; // вызов конструктора по умолчанию 32 | MyClass b(10); // вызов конструктора с параметрами 33 | MyClass c(b); // вызов конструктора копирования 34 | MyClass d(std::move(c)); // вызов конструктора перемещения 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/junior/jcode_187.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | template 6 | class MyVector { 7 | public: 8 | MyVector() : data(nullptr), sz(0), capacity(0) {} 9 | ~MyVector() { delete[] data; } 10 | void push_back(const T& value) { 11 | if (sz == capacity) { 12 | resize(); 13 | } 14 | data[sz++] = value; 15 | } 16 | void push_front(const T& value) { 17 | if (sz == capacity) { 18 | resize(); 19 | } 20 | for (int i = sz; i > 0; i--) { 21 | data[i] = data[i - 1]; 22 | } 23 | data[0] = value; 24 | sz++; 25 | } 26 | void pop_back() { 27 | if (sz > 0) { 28 | sz--; 29 | } 30 | } 31 | void pop_front() { 32 | if (sz > 0) { 33 | for (int i = 0; i < sz - 1; i++) { 34 | data[i] = data[i + 1]; 35 | } 36 | sz--; 37 | } 38 | } 39 | int size() const { return sz; } 40 | void clear() { sz = 0; } 41 | private: 42 | T* data; 43 | int sz; 44 | int capacity; 45 | void resize() { 46 | capacity = max(1, capacity * 2); 47 | T* newData = new T[capacity]; 48 | for (int i = 0; i < sz; i++) { 49 | newData[i] = data[i]; 50 | } 51 | delete[] data; 52 | data = newData; 53 | } 54 | }; 55 | 56 | int main() { 57 | MyVector v; 58 | v.push_back(1); 59 | v.push_back(2); 60 | v.push_back(3); 61 | cout << "Размер: " << v.size() << endl; 62 | v.pop_back(); 63 | cout << "Размер: " << v.size() << endl; 64 | v.push_front(4); 65 | cout << "Размер: " << v.size() << endl; 66 | v.pop_front(); 67 | cout << "Размер: " << v.size() << endl; 68 | v.clear(); 69 | cout << "Размер: " << v.size() << endl; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/junior/jcode_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DEBUG // Определение макроса DEBUG 4 | 5 | int main() { 6 | #ifdef DEBUG // Если макрос DEBUG определен... 7 | std::cout << "Debug mode is ON" << std::endl; // ...выводим сообщение о том, что режим отладки включен 8 | #else // В противном случае... 9 | std::cout << "Debug mode is OFF" << std::endl; // ...выводим сообщение о том, что режим отладки выключен 10 | #endif 11 | 12 | return 0; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/junior/jcode_23_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define PI 3.14 // Определение макроса PI со значением 3.14 4 | #define SQUARE(x) ((x)*(x)) // Определение макроса SQUARE, который возвращает квадрат своего аргумента 5 | 6 | int main() { 7 | std::cout << "The value of PI is: " << PI << std::endl; // Использование макроса PI 8 | std::cout << "The square of 5 is: " << SQUARE(5) << std::endl; // Использование макроса SQUARE 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /src/junior/jcode_23_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::cout << "The value of PI is: " << 3.14 << std::endl; 5 | std::cout << "The square of 5 is: " << ((5)*(5)) << std::endl; 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /src/junior/jcode_33.cpp: -------------------------------------------------------------------------------- 1 | #include // подключаем библиотеку для ввода/вывода 2 | 3 | int main() { // начало функции main 4 | int x = 5; // объявляем переменную x и присваиваем ей значение 5 5 | std::cout << "x = " << x << std::endl; // выводим значение x на экран 6 | x = 10; // изменяем значение x 7 | std::cout << "x = " << x << std::endl; // выводим новое значение x на экран 8 | return 0; // завершаем функцию main с кодом возврата 0 9 | } 10 | -------------------------------------------------------------------------------- /src/junior/jcode_37.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int x = 5; // 00000101 5 | int y = 3; // 00000011 6 | 7 | printf("x & y = %d\n", x & y); // 00000001 8 | printf("x | y = %d\n", x | y); // 00000111 9 | printf("x ^ y = %d\n", x ^ y); // 00000110 10 | printf("~x = %d\n", ~x); // 11111010 11 | printf("x << 1 = %d\n", x << 1); // 00001010 12 | printf("x >> 1 = %d\n", x >> 1); // 00000010 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/junior/jcode_41.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int SIZE = 100100; 4 | const int BASE = 2017; 5 | const int MOD = 1000000009; 6 | int64_t hash[SIZE]; 7 | void init_hash(const string &line, int64_t *h, int base, int mod) { 8 | h[0] = 0; 9 | int n = line.length(); 10 | for (int i = 1; i <= n; ++i) { 11 | h[i] = h[i - 1] * base % mod + (signed char)line[i - 1] % mod; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/junior/jcode_63.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class Animal { 3 | public: 4 | virtual void makeSound() = 0; // чисто виртуальная функция 5 | }; 6 | 7 | class Cat : public Animal { 8 | public: 9 | void makeSound() override { // переопределение чисто виртуальной функции 10 | std::cout << "Meow" << std::endl; 11 | } 12 | }; 13 | 14 | class Dog : public Animal { 15 | public: 16 | void makeSound() override { 17 | std::cout << "Woof" << std::endl; 18 | } 19 | }; 20 | 21 | class Bird : public Animal { 22 | public: 23 | void makeSound() override { 24 | std::cout << "Chirp" << std::endl; 25 | } 26 | }; 27 | 28 | int main() { 29 | Animal* animals[] = {new Cat(), new Dog(), new Bird()}; 30 | for (Animal* animal : animals) { 31 | animal->makeSound(); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/junior/jcode_65.cpp: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | public: 3 | static int x; // статическое поле-переменная 4 | int y; 5 | 6 | static void staticMethod() { // статический метод 7 | x = 10; // имеет доступ к статическому полю-переменной 8 | // y = 20; // ошибка: нет доступа к нестатическому полю-переменной 9 | } 10 | 11 | void nonStaticMethod() { 12 | x = 30; // имеет доступ к статическому полю-переменной 13 | y = 40; // имеет доступ к нестатическому полю-переменной 14 | } 15 | }; 16 | 17 | int MyClass::x = 0; // определение и инициализация статического поля-переменной 18 | 19 | int main() { 20 | MyClass::staticMethod(); // вызов статического метода без создания объекта 21 | MyClass obj; 22 | obj.nonStaticMethod(); // вызов нестатического метода через объект 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/junior/jcode_66.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class MyClass { 3 | public: 4 | static int x; // объявление статического поля-переменной 5 | int y; 6 | }; 7 | 8 | int MyClass::x = 0; // определение и инициализация статического поля-переменной 9 | 10 | int main() { 11 | MyClass obj1; 12 | MyClass obj2; 13 | obj1.x = 10; // изменение значения статического поля-переменной 14 | obj1.y = 20; // изменение значения нестатического поля-переменной 15 | std::cout << obj2.x << std::endl; // вывод значения статического поля-переменной (10) 16 | std::cout << obj2.y << std::endl; // вывод значения нестатического поля-переменной (неопределенное значение) 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/junior/jcode_67.cpp: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | public: 3 | int x; 4 | 5 | void nonConstMethod() { 6 | x = 10; // допустимо: изменение поля-переменной в неконстантном методе 7 | } 8 | 9 | void constMethod() const { 10 | // x = 20; // ошибка: изменение поля-переменной в константном методе недопустимо 11 | } 12 | }; 13 | 14 | int main() { 15 | MyClass obj; 16 | obj.nonConstMethod(); // допустимо: вызов неконстантного метода для неконстантного объекта 17 | obj.constMethod(); // допустимо: вызов константного метода для неконстантного объекта 18 | 19 | const MyClass constObj{}; 20 | // constObj.nonConstMethod(); // ошибка: вызов неконстантного метода для константного объекта недопустимо 21 | constObj.constMethod(); // допустимо: вызов константного метода для константного объекта 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/junior/jcode_68.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class MyClass { 3 | public: 4 | int x; 5 | mutable int y; 6 | 7 | void constMethod() const { 8 | // x = 10; // ошибка: изменение неизменяемого поля-переменной в константном методе недопустимо 9 | y = 20; // допустимо: изменение изменяемого поля-переменной в константном методе 10 | } 11 | }; 12 | 13 | int main() { 14 | const MyClass obj {}; 15 | obj.constMethod(); // допустимо: вызов константного метода для константного объекта 16 | std::cout << obj.y << std::endl; // вывод значения изменяемого поля-переменной (20) 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /src/junior/jcode_69.cpp: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | public: 3 | int x; 4 | 5 | void nonConstMethod() { 6 | x = 10; // допустимо: изменение поля-переменной в неконстантном методе 7 | } 8 | 9 | void constMethod() const { 10 | // x = 20; // ошибка: изменение поля-переменной в константном методе недопустимо 11 | } 12 | }; 13 | 14 | int main() { 15 | MyClass obj; 16 | obj.nonConstMethod(); // допустимо: вызов неконстантного метода для неконстантного объекта 17 | obj.constMethod(); // допустимо: вызов константного метода для неконстантного объекта 18 | 19 | const MyClass constObj{}; 20 | // constObj.nonConstMethod(); // ошибка: вызов неконстантного метода для константного объекта недопустимо 21 | constObj.constMethod(); // допустимо: вызов константного метода для константного объекта 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/junior/jcode_83.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | std::map data = {{"Alice", 5}, {"Bob", 3}}; 7 | 8 | if (auto it = data.find("Alice"); it != data.end()) { 9 | std::cout << "Found Alice with value " << it->second << std::endl; 10 | } else { 11 | std::cout << "Did not find Alice" << std::endl; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/junior/jcode_88.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int divide(int a, int b) { 5 | if (b == 0) { 6 | throw std::runtime_error("Division by zero"); 7 | } 8 | return a / b; 9 | } 10 | 11 | int main() { 12 | try { 13 | int result = divide(10, 0); 14 | std::cout << result << std::endl; 15 | } catch (const std::exception& e) { 16 | std::cerr << "Error: " << e.what() << std::endl; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/task_001.cpp: -------------------------------------------------------------------------------- 1 | // 2 | //// Created by Jollu8 on 5/15/24. 3 | // 4 | 5 | ////- Нерекурсивно удалить смайлики вида :-)) и :-(( из строки 6 | ////string EraseSmiles (const string& input); 7 | /// "eg:-))g)" --> "egg)" 8 | /// "e:-:-))))" --> "e:-))" 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace std::string_literals; 15 | 16 | string EraseSmiles(const string &s) { 17 | string ans; 18 | for (int i = 0; i < s.size(); ++i) { 19 | if (i + 3 < s.size() && s[i] == ':' && (s.substr(i + 1, 3) == "-))"s || s.substr(i + 1, 3) == "-(("s)) 20 | i += 3; 21 | else ans += s[i]; 22 | } 23 | return ans; 24 | } 25 | 26 | int main() { 27 | const std::string s = "e:-:-))))"s; 28 | std::cout << EraseSmiles(s); 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/problems/task_002.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu on 5/15/24. 2 | 3 | //// Description https://leetcode.com/problems/simplify-path/description 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | class Solution { 12 | public: 13 | string simplifyPath(string s, stack st = {}) { 14 | using namespace std::string_literals; 15 | stringstream ss(s); 16 | string ans, tok; 17 | 18 | while (getline(ss, tok, '/')) { 19 | if (tok.empty() || tok == "."s) continue; 20 | else if (tok == ".."s) { if (!st.empty()) st.pop(); } 21 | else st.push(tok); 22 | } 23 | 24 | for (; !st.empty(); st.pop()) ans = "/"s + st.top() + ans; 25 | return ans.empty() ? "/"s : ans; 26 | } 27 | }; -------------------------------------------------------------------------------- /src/problems/task_003.cpp: -------------------------------------------------------------------------------- 1 | // 2 | //// Created by @Jollu8 on 5/16/24. 3 | // 4 | 5 | //// https://leetcode.com/problems/line-reflection 6 | ////описание проблемы 7 | ////Задача касается набора точек на двумерной плоскости, 8 | ////и цель состоит в том, чтобы определить, существует ли линия, параллельная оси Y, 9 | ////которая может отражать все точки симметрично. По сути, нам нужно выяснить, 10 | ////можем ли мы нарисовать вертикальную линию так, чтобы каждая точка имела зеркальный 11 | ////аналог на другой стороне линии. Набор точек до и после отражения их через эту линию должен быть одинаковым, 12 | ////даже если некоторые точки повторяются. 13 | 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | using namespace std; 28 | 29 | class Solution_1 { 30 | public: 31 | bool isReflected(vector> &A, set> u = {}) { 32 | std::transform(A.begin(), A.end(), std::inserter(u, u.begin()), 33 | [](auto &v) -> pair { return {v[0], v[1]}; }); 34 | 35 | auto s = u.begin()->first + u.rbegin()->first; 36 | return std::all_of(A.begin(), A.end(), 37 | [&u, &s](const vector &v) { return u.contains({s - v.front(), v.back()}); }); 38 | } 39 | }; 40 | 41 | 42 | class Solution_2 { 43 | public: 44 | bool isReflected(vector> &A, set> u = {}) { 45 | for (auto &v: A) 46 | u.insert({v[0], v[1]}); 47 | 48 | auto s = u.begin()->first + u.rbegin()->first; 49 | for (auto &v: A) if (!u.contains({s - v.front(), v.back()})) return false; 50 | return true; 51 | } 52 | }; 53 | 54 | 55 | class Solution_3 { 56 | public: 57 | bool isReflected(vector> &A) { 58 | unordered_map> u; 59 | int a = -1e9, b = 1e9; 60 | 61 | for (auto &v: A) { 62 | u[v[0]].insert(v[1]); 63 | a = max(a, v[0]); 64 | b = min(b, v[0]); 65 | } 66 | int s = a + b; 67 | return all_of(A.begin(), A.end(), [&u, &s](const vector &v) { 68 | return u[s - v[0]].contains(v[1]); 69 | }); 70 | } 71 | }; 72 | 73 | void test(); 74 | 75 | int main() { 76 | test(); 77 | std::cout << "OK!\n"; 78 | } 79 | 80 | void test() { 81 | vector> v{{1, 1}, 82 | {3, 1}, 83 | {7, 1}, 84 | {9, 1}}; 85 | vector> v1{{1, 1}, 86 | {-1, 1}}; 87 | vector> v2{{1, 1}, 88 | {-1, -1}}; 89 | vector> v3{{0, 0}, 90 | {1, 0}, 91 | {2, 0}}; 92 | vector> v4{{0, 0}, 93 | {1, 1}, 94 | {2, 2}, 95 | {3, 3}, 96 | {4, 5}, 97 | {5, 5}}; 98 | Solution_1 s1; 99 | Solution_2 s2; 100 | Solution_3 s3; 101 | assert(s1.isReflected(v) == true); 102 | assert(s1.isReflected(v1) == true); 103 | assert(s1.isReflected(v2) == false); 104 | assert(s1.isReflected(v3) == true); 105 | assert(s1.isReflected(v4) == false); 106 | 107 | assert(s2.isReflected(v) == true); 108 | assert(s2.isReflected(v1) == true); 109 | assert(s2.isReflected(v2) == false); 110 | assert(s2.isReflected(v3) == true); 111 | assert(s2.isReflected(v4) == false); 112 | 113 | assert(s3.isReflected(v) == true); 114 | assert(s3.isReflected(v1) == true); 115 | assert(s3.isReflected(v2) == false); 116 | assert(s3.isReflected(v3) == true); 117 | assert(s3.isReflected(v4) == false); 118 | 119 | } 120 | 121 | -------------------------------------------------------------------------------- /src/problems/task_004.cpp: -------------------------------------------------------------------------------- 1 | // 2 | //// Created by @Jollu8 on 5/16/24. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | //// @Solution_meeting1 14 | //// Задача — определить, сможет ли человек присутствовать на всех запланированных встречах без каких-либо совпадений. Точнее, две встречи не могут происходить одновременно. Человек может присутствовать на всех собраниях только в том случае, если из любых двух собраний одно заканчивается раньше начала другого. 15 | //// intervals = [[0, 30], [5, 10], [15, 20]] -> @false 16 | 17 | /// @Solution_meeting2_1 @Solution_meeting2_2 18 | /// Дан массив интервалов встреч, нужно вернуть минимальное количество переговорок, необходимое для проведения всех встреч 19 | /// int minMeetingRooms(vector>& intervals) 20 | /// Примечание: если одна встреча заканчивается в 10 минут, а вторая в 10 начинается, то для этого нужно две переговорки, т.е интервалы заданы так, что начала и конец должны быть включены 21 | /// {{0,30},{5,10},{15,20}} --> 2 22 | 23 | 24 | //// @class 25 | class Solution_meeting1 { 26 | public: 27 | bool canAttendMeetings(std::vector> &A) { 28 | sort(A.begin(), A.end(), [](auto &a, auto &b) { return a[0] < b[0]; }); 29 | for (int i = 1; i < A.size(); ++i) 30 | if (A[i][0] < A[i - 1][1]) return false; 31 | return true; 32 | } 33 | }; 34 | 35 | //// @class 36 | class Solution_meeting2_1{ 37 | public: 38 | int minMeetingRooms(vector> &A) { 39 | map mp; 40 | for (auto &v: A) { 41 | ++mp[v[0]]; 42 | --mp[v[1]]; 43 | } 44 | int ans{}, cnt {}; 45 | for (auto &[a, b]: mp) ans = max(ans, cnt += b); 46 | return ans; 47 | } 48 | }; 49 | 50 | //// @class 51 | class Solution_meeting2_2 { 52 | public: 53 | int minMeetingRooms(vector>& A) { 54 | sort(A.begin(), A.end(), [](auto &a, auto &b) {return a[0] < b[0];}); 55 | priority_queue, greater<>> pq; 56 | pq.push(A[0][1]); 57 | for(auto i = 1; i < A.size(); ++i) { 58 | if(A[i][0] > pq.top()) pq.pop(); 59 | pq.push(A[i][0]); 60 | } 61 | return pq.size(); 62 | } 63 | }; 64 | 65 | void test_meeting2(); 66 | void test_meeting1(); 67 | 68 | int main() { 69 | test_meeting1(); 70 | std::cout << "Solution_meeting1 OK!\n"; 71 | test_meeting2(); 72 | std::cout << "Solution_meeting2 OK!\n"; 73 | } 74 | 75 | void test_meeting2() { 76 | Solution_meeting2_1 s_1; 77 | Solution_meeting2_2 s_2; 78 | vector> v1{{1, 4}, {2, 5}, {7, 9}}; 79 | vector> v2 {{0,30},{5,10},{15,20}}; 80 | vector> v3{{7,10},{2,4}}; 81 | assert(s_1.minMeetingRooms(v1) == 2); 82 | assert(s_1.minMeetingRooms(v2) == 2); 83 | assert(s_1.minMeetingRooms(v3) == 1); 84 | assert(s_2.minMeetingRooms(v3) == 1); 85 | assert(s_2.minMeetingRooms(v2) == 2); 86 | assert(s_2.minMeetingRooms(v1) == 2); 87 | 88 | 89 | } 90 | 91 | void test_meeting1() { 92 | Solution_meeting1 s_1; 93 | // Пример 1: Проверка встреч, которые не пересекаются 94 | vector> intervals1 = {{0, 1}, 95 | {2, 3}, 96 | {4, 5}}; 97 | // Ожидаемый вывод: true, так как все встречи могут проходить параллельно 98 | assert(s_1.canAttendMeetings(intervals1) == true); 99 | 100 | 101 | // Пример 2: Проверка встреч, которые пересекаются 102 | vector> intervals2 = {{0, 1}, 103 | {1, 2}, 104 | {2, 3}}; 105 | // Ожидаемый вывод: false, так как одна встреча начинается до окончания предыдущей 106 | assert(s_1.canAttendMeetings(intervals2) == true); 107 | 108 | 109 | // Пример 3: Проверка встреч, которые пересекаются 110 | vector> intervals3 = {{1, 2}, 111 | {2, 3}, 112 | {3, 4}}; 113 | // Ожидаемый вывод: true, так как одна встреча начинается до окончания предыдущей 114 | assert(s_1.canAttendMeetings(intervals3) == true); 115 | 116 | 117 | // Пример 4: Одинаковые временные интервалы 118 | vector> intervals4 = {{1, 5}, 119 | {1, 5}, 120 | {1, 5}}; 121 | // Ожидаемый вывод: false, так как встречи проходят в одно время 122 | assert(s_1.canAttendMeetings(intervals4) == false); 123 | 124 | // Пример 5: Проверка пустого массива 125 | vector> intervals5; 126 | // Ожидаемый вывод: true, так как нет встреч 127 | assert(s_1.canAttendMeetings(intervals5)); 128 | 129 | // Пример 6: Проверка непрерывных временных интервалов 130 | vector> intervals6 = {{0, 5}, 131 | {5, 10}, 132 | {10, 15}}; 133 | // Ожидаемый вывод: true, так как встречи проходят одна за другой 134 | assert(s_1.canAttendMeetings(intervals6) == true); 135 | 136 | // Пример 7: Проверка встреч, которые пересекаются 137 | vector> intervals7 = {{0, 5}, 138 | {3, 8}, 139 | {6, 10}}; 140 | // Ожидаемый вывод: false, так как одна встреча начинается до окончания предыдущей 141 | assert(s_1.canAttendMeetings(intervals7) == false); 142 | 143 | // Пример 8: Проверка случая, когда все встречи пересекаются 144 | vector> intervals8 = {{1, 3}, 145 | {2, 4}, 146 | {3, 5}, 147 | {4, 6}}; 148 | // Ожидаемый вывод: false, так как все встречи накладываются друг на друга 149 | assert(s_1.canAttendMeetings(intervals8) == false); 150 | 151 | // Пример 9: Проверка случая, когда все встречи проходят одновременно 152 | vector> intervals9 = {{0, 1}, 153 | {0, 1}, 154 | {0, 1}}; 155 | // Ожидаемый вывод: false, так как встречи проходят в одно время 156 | assert(s_1.canAttendMeetings(intervals9) == false); 157 | 158 | // Пример 10: Тестирование большого количества встреч 159 | vector> intervals10 = {{0, 1}, 160 | {2, 3}, 161 | {4, 5}, 162 | {6, 7}, 163 | {8, 9}, 164 | {10, 11}, 165 | {12, 13}, 166 | {14, 15}}; 167 | // Ожидаемый вывод: true, так как все встречи могут проходить параллельно 168 | assert(s_1.canAttendMeetings(intervals10) == true); 169 | } 170 | -------------------------------------------------------------------------------- /src/problems/task_005.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/16/24. 2 | 3 | /// нужно слова вернуть в обратном порядке, убрав пробелы с начала и конца предложения и между словами оставить только один пробел 4 | //// @Solution_1 , @Solution (не работает) 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | //// @class 16 | class Solution_1 { 17 | public: 18 | string reverseWords(string s) { 19 | string ans, tok; 20 | ans.reserve(s.size()); 21 | stringstream ss(s); 22 | while (ss >> tok) ans = tok + " " + ans; 23 | 24 | ans.pop_back(); 25 | return ans; 26 | } 27 | }; 28 | 29 | //// @class 30 | class Solution { // не умеет пробелы удалять 31 | public: 32 | string reverseWords(string s) { 33 | reverse(s.begin(), s.end()); 34 | for (int l{}, r{}; r < s.size(); ++r) { 35 | if (int cnt{}; s[r] == ' ') { 36 | while (r + 1 < s.size() && s[r + 1] == ' ')++r, ++cnt; 37 | reverse(s.begin() + l, s.begin() + r - cnt); 38 | l = r; 39 | } 40 | if (r + 1 == s.size() || r == s.size() - 1) 41 | reverse(s.begin() + l, s.end()); 42 | } 43 | return s; 44 | } 45 | }; 46 | 47 | void test(); 48 | 49 | int main() { 50 | test(); 51 | std::cout << "OK!\n"; 52 | } 53 | 54 | void test() { 55 | using namespace std::string_literals; 56 | Solution_1 s1; 57 | // Solution_2 s2; 58 | string str1 = "the sky is blue"s; 59 | string str2 = " hello world "s; 60 | string str3 = "a good example"s; 61 | assert(s1.reverseWords(str1) == "blue is sky the"s); 62 | assert(s1.reverseWords(str2) == "world hello"s); 63 | assert(s1.reverseWords(str3) == "example good a"s); 64 | // assert(s2.reverseWords(str1) == "blue is sky the"s); 65 | // assert(s2.reverseWords(str2) == "world hello"s); 66 | // assert(s2.reverseWords(str3) == "example good a"s); 67 | } 68 | -------------------------------------------------------------------------------- /src/problems/task_006.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/16/24. 2 | //// Description https://leetcode.com/problems/find-the-prefix-common-array-of-two-arrays/ 3 | //// @Solution_1, @Solution_2 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | 11 | /// @class 12 | class Solution_1 { 13 | public: 14 | vector findThePrefixCommonArray(vector &A, vector &B) { 15 | vector ans(A.size()); 16 | bitset<51> a, b; 17 | for (int i = 0; i < A.size(); i++) 18 | ans[i] = (a.set(A[i]) & b.set(B[i])).count(); 19 | 20 | return ans; 21 | } 22 | }; 23 | 24 | class Solution_2 { 25 | public: 26 | vector findThePrefixCommonArray(vector &A, vector &B) { 27 | int n = A.size(), cnt{}; 28 | vector ans(n), seen(n + 1); 29 | for (int i = 0; i < n; ++i) { 30 | if (++seen[A[i]] == 2)++cnt; 31 | if (++seen[B[i]] == 2)++cnt; 32 | ans[i] = cnt; 33 | } 34 | return ans; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /src/problems/task_007.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/16/24. 2 | //// Desciption https://leetcode.com/problems/find-the-duplicate-number/description/ 3 | //// @Solution_1 , @Solution_2 , @Solution_3 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | //// @class 11 | class Solution_1 { 12 | public: 13 | int findDuplicate(vector &n) { 14 | unordered_set s; 15 | s.reserve(n.size()); 16 | for (auto i: n) { 17 | if (!s.contains(i))s.insert(i); 18 | else return i; 19 | } 20 | return 42; 21 | } 22 | }; 23 | 24 | class Solution_2 { 25 | public: 26 | int findDuplicate(vector &A) { 27 | int slow = A[0], fast = A[0]; 28 | do { 29 | slow = A[slow]; 30 | fast = A[A[fast]]; 31 | } while (slow != fast); 32 | 33 | slow = A[0]; 34 | while (slow != fast) slow = A[slow], fast = A[fast]; 35 | return slow; 36 | } 37 | }; 38 | 39 | 40 | class Solution_3 { 41 | public: 42 | int findDuplicate(vector &A) { 43 | vector seen(A.size() + 1); 44 | for (auto i: A) if (++seen[i] > 1)return i; 45 | return 42; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/problems/task_008.cpp: -------------------------------------------------------------------------------- 1 | // Created by @Jollu8 on 5/17/24. 2 | 3 | //// @Solution 4 | /// Дано три массива, и число k, нужно определить есть ли такие три числа, что их сумма равна k и они лежат в разных массивах 5 | /// bool HasTreeSum(const vector& first, const vector& second, const vector& third, int k) 6 | /// k = 9 7 | /// [1 , 2 , 3 , 4 , 5] 8 | /// [2 , 3 , 6 , 1 , 2] 9 | /// [3 , 2 , 4 , 5 , 6] 10 | /// 1 + 2 + 6 = 9 --> true 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define N // D for debug 19 | 20 | using namespace std; 21 | 22 | //// @class 23 | class Solution { 24 | using CVI = const vector; 25 | public: 26 | bool HasThreeSum(CVI &a, CVI &b, CVI &c, int k) { 27 | unordered_set u(a.begin(), a.end()); 28 | int ans{}; 29 | for (auto i: b) 30 | for (auto j: c) 31 | if (u.contains(k - i - j)) { 32 | #ifdef D 33 | std::cout << i << " " << j << " " << k - i - j << '\n'; 34 | #endif 35 | return true; 36 | } 37 | return false; 38 | } 39 | }; 40 | 41 | 42 | void test() { 43 | Solution s; 44 | vector> v1{ 45 | {1, 2, 3, 4, 5}, 46 | {2, 3, 6, 1, 2}, 47 | {3, 2, 4, 5, 6}, 48 | }; 49 | vector> v2{ 50 | {1, 2, 3, 4, 5}, 51 | {2, 3, 6, 1, 2}, 52 | {3, 2, 4, 5, 6}, 53 | }; 54 | assert(s.HasThreeSum(v1[0], v1[1], v1[2], 9) == true); 55 | assert(s.HasThreeSum(v2[0], v1[1], v1[2], 0) == false); 56 | assert(s.HasThreeSum(v1[0], v1[1], v1[2], 99) == false); 57 | 58 | 59 | } 60 | 61 | int main() { 62 | test(); 63 | std::cout << "OK!\n"; 64 | } 65 | -------------------------------------------------------------------------------- /src/problems/task_009.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/17/24. 2 | 3 | 4 | 5 | //// @Solution_1, @Solution_2 https://leetcode.com/problems/recover-binary-search-tree/description/ 6 | /// Дано бинарное дерево поиска, в нём взяли два разных узла и поменяли значения местами. Нужно поменять значения обратно 7 | /// void recoverTree(TreeNode* root) 8 | /// 3 1 9 | /// / / 10 | /// 1 --> 3 11 | /// \ \ 12 | /// 2 2 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | using namespace std; 21 | 22 | 23 | struct TreeNode { 24 | int val; 25 | TreeNode *left; 26 | TreeNode *right; 27 | 28 | TreeNode() : val(0), left(nullptr), right(nullptr) {} 29 | 30 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 31 | 32 | TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 33 | }; 34 | 35 | //// @class 36 | class Solution_1 { 37 | vector p; 38 | 39 | void dfs(TreeNode *r) { 40 | if (!r) return; 41 | dfs(r->left); 42 | if (p[0] && p[0]->val > r->val) { 43 | if (!p[1]) p[1] = p[0]; 44 | p[2] = r; 45 | } 46 | p[0] = r; 47 | dfs(r->right); 48 | } 49 | 50 | public: 51 | Solution_1() : p(vector(3, nullptr)) {} 52 | 53 | void recoverTree(TreeNode *r) { 54 | dfs(r); 55 | if (p[1] && p[2]) 56 | swap(p[1]->val, p[2]->val); 57 | } 58 | }; 59 | 60 | class Solution_2 { 61 | 62 | public: 63 | void recoverTree(TreeNode *root) { 64 | vector p(3, nullptr); 65 | function inor = [&](TreeNode *r) { 66 | if (!r) return; 67 | inor(r->left); 68 | if (p[0] && p[0]->val > r->val) { 69 | if (!p[1])p[1] = p[0]; 70 | p[2] = r; 71 | } 72 | p[0] = r; 73 | inor(r->right); 74 | }; 75 | inor(root); 76 | if (p[1] && p[2]) 77 | swap(p[1]->val, p[2]->val); 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /src/problems/task_010.cpp: -------------------------------------------------------------------------------- 1 | 2 | //// Created by @author Jollu8 on 5/17/24. 3 | 4 | //// @Solution 5 | /// Дан односвязный список и числа l и r, l <= r. Нужно развернуть список с l по r включительно. В l и r используется отсчёт с 1. Гарантируется, что l и r не могут выйти за границы 6 | /// Количество узлов в списке >= 1 7 | /// 1 -> 2 -> 3 -> 4 -> 5 [2, 4] ---> 1 -> 4 -> 3 -> 2 -> 5 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | struct ListNode { 15 | int val; 16 | ListNode *next; 17 | 18 | ListNode() : val(0), next(nullptr) {} 19 | 20 | explicit ListNode(int x) : val(x), next(nullptr) {} 21 | 22 | ListNode(int x, ListNode *next) : val(x), next(next) {} 23 | }; 24 | 25 | /// @class 26 | class Solution { 27 | public: 28 | ListNode *reverseFromLtoR(ListNode *h, int l, int r) { 29 | if (!h)return h; 30 | auto dummy = new ListNode(0); 31 | dummy->next = h; 32 | auto pre = dummy; 33 | for (int i = 1; i < l; ++i) pre = pre->next; 34 | h = pre->next; 35 | 36 | for (int i = l; i < r; ++i) { 37 | auto next = h->next; 38 | h->next = next->next; 39 | next->next = pre->next; 40 | pre->next = next; 41 | } 42 | return dummy->next; 43 | } 44 | }; 45 | 46 | void printList(ListNode *head); 47 | 48 | int main() { 49 | Solution solution; 50 | 51 | // Тест 1 52 | std::cout << "Test 1\n"; 53 | auto *head1 = new ListNode(1); 54 | head1->next = new ListNode(2); 55 | head1->next->next = new ListNode(3); 56 | head1->next->next->next = new ListNode(4); 57 | head1->next->next->next->next = new ListNode(5); 58 | ListNode *result1 = solution.reverseFromLtoR(head1, 2, 4); 59 | printList(result1); // Ожидаемый вывод: 1 -> 4 -> 3 -> 2 -> 5 60 | 61 | // Тест 2 62 | std::cout << "Test 2\n"; 63 | auto *head2 = new ListNode(1); 64 | head2->next = new ListNode(2); 65 | head2->next->next = new ListNode(3); 66 | ListNode *result2 = solution.reverseFromLtoR(head2, 1, 2); 67 | printList(result2); // Ожидаемый вывод: 2 -> 1 -> 3 68 | 69 | // Тест 3 70 | std::cout << "Test 3\n"; 71 | auto *head3 = new ListNode(1); 72 | auto *result3 = solution.reverseFromLtoR(head3, 1, 1); 73 | printList(result3); // Ожидаемый вывод: 1 74 | 75 | // Тест 4 76 | std::cout << "Test 4\n"; 77 | auto *head4 = new ListNode(1); 78 | head4->next = new ListNode(2); 79 | head4->next->next = new ListNode(3); 80 | head4->next->next->next = new ListNode(4); 81 | head4->next->next->next->next = new ListNode(5); 82 | auto *result4 = solution.reverseFromLtoR(head4, 1, 5); 83 | printList(result4); // Ожидаемый вывод: 5 -> 4 -> 3 -> 2 -> 1 84 | 85 | // Тест 5 86 | std::cout << "Test 5\n"; 87 | auto *head5 = new ListNode(1); 88 | head5->next = new ListNode(2); 89 | head5->next->next = new ListNode(3); 90 | head5->next->next->next = new ListNode(4); 91 | head5->next->next->next->next = new ListNode(5); 92 | auto *result5 = solution.reverseFromLtoR(head5, 3, 3); 93 | printList(result5); // Ожидаемый вывод: 1 -> 2 -> 3 -> 4 -> 5 94 | 95 | // Добавьте больше тестов по мере необходимости... 96 | 97 | } 98 | 99 | 100 | void printList(ListNode *head) { 101 | ListNode *temp = head; 102 | while (temp != nullptr) { 103 | std::cout << temp->val; 104 | if (temp->next != nullptr) { 105 | std::cout << " -> "; 106 | } 107 | temp = temp->next; 108 | } 109 | std::cout << std::endl; 110 | } 111 | -------------------------------------------------------------------------------- /src/problems/task_011.cpp: -------------------------------------------------------------------------------- 1 | //// 228. Summary Ranges https://leetcode.com/problems/summary-ranges/description/ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Solution { 11 | public: 12 | vector summaryRanges(vector &A) { 13 | vector ans; 14 | for (int l = 0, r = 0; r < A.size(); ++r) { 15 | if (r + 1 == A.size() || A[r] + 1 != A[r + 1]) { 16 | ans.emplace_back(l != r ? to_string(A[l]) + "->" + to_string(A[r]) : to_string(A[r])); 17 | l = r + 1; 18 | } 19 | } 20 | return ans; 21 | } 22 | }; 23 | 24 | int main() { 25 | using namespace std::string_literals; 26 | Solution s; 27 | vector v1{0, 1, 2, 4, 5, 7}; 28 | vector v1a{"0->2"s, "4->5"s, "7"s}; 29 | assert(s.summaryRanges(v1) == v1a); 30 | std::cout << "OK!'\n"; 31 | 32 | } -------------------------------------------------------------------------------- /src/problems/task_012.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @author Jollu8 on 5/17/24. 2 | //// @Solution 3 | /// Description https://leetcode.com/problems/palindrome-linked-list/ 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | struct ListNode { 10 | int val; 11 | ListNode *next; 12 | 13 | ListNode() : val(0), next(nullptr) {} 14 | 15 | ListNode(int x) : val(x), next(nullptr) {} 16 | 17 | ListNode(int x, ListNode *next) : val(x), next(next) {} 18 | }; 19 | 20 | //// @class 21 | class Solution { 22 | public: 23 | bool isPalindrome(ListNode *h) { 24 | ListNode *prev = nullptr, *slow = h, *fast = h; 25 | 26 | for (; fast && fast->next; fast = fast->next->next, slow = slow->next); 27 | for (; slow; swap(prev, slow->next), swap(slow, prev)); 28 | for (; prev && h; prev = prev->next, h = h->next) 29 | if (h->val != prev->val) return false; 30 | 31 | return true; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /src/problems/task_013.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @author Jollu8 on 5/17/24. 2 | //// @Description https://leetcode.com/problems/product-of-array-except-self/description/ 3 | //// @Solution 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Solution { 11 | public: 12 | vector productExceptSelf(vector &A) { 13 | int n = A.size(), r = 1; 14 | vector ans(n); 15 | ans[0] = 1; 16 | 17 | for (int i = 1; i < n; ++i) ans[i] = ans[i - 1] * A[i - 1]; 18 | for (int i = n - 1; i >= 0; --i) { 19 | ans[i] = ans[i] * r; 20 | r *= A[i]; 21 | } 22 | return ans; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /src/problems/task_014.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @author Jollu8 on 5/17/24. 2 | //// @Desciption https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/ 3 | //// @Solution_1 (::npos) , @Solution_2 (kmp) 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | //// @class 10 | class Solution { 11 | public: 12 | int strStr(string h, string n) { 13 | if(auto f = h.find(n); f != string::npos) return f; 14 | return -1; 15 | } 16 | }; 17 | 18 | //// @class 19 | class Solution_2 { 20 | public: 21 | int strStr(string h, string n) { 22 | int ans = -1, ns = n.size(); 23 | 24 | for (int i{}, j = ns - 1; j < h.size(); ++i, ++j) { 25 | int l{}; 26 | for (int k = i; l < ns && (h[k] == n[l]); ++k, ++l); 27 | if (l == ns) { 28 | ans = i; 29 | break; 30 | } 31 | } 32 | return ans; 33 | } 34 | }; -------------------------------------------------------------------------------- /src/problems/task_015.cpp: -------------------------------------------------------------------------------- 1 | //// Created by Jollu8 on 5/17/24. 2 | //// Description https://leetcode.com/problems/perfect-squares/description/ 3 | //// @Solution_3, Solution_2 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | //// @class 12 | class Solution_3 { 13 | public: 14 | int numSquares(int n) { 15 | queue q({n}); 16 | int ans{}; 17 | 18 | while (!q.empty()) { 19 | int size = q.size(); 20 | ans++; 21 | while (size--) { 22 | int cur = q.front(); 23 | q.pop(); 24 | for (int i = 1; i * i <= cur; ++i) { 25 | int sub = cur - i * i; 26 | if (!sub) 27 | return ans; 28 | q.push(sub); 29 | } 30 | } 31 | } 32 | return 0; 33 | } 34 | }; 35 | 36 | 37 | //// @class 38 | class Solution_2 { 39 | public: 40 | int numSquares(int n, int m = 1) { 41 | vector dp(max(m, n+1), INT_MAX); 42 | // dp[0] = 0; 43 | for(int i{}, ii; (ii = i*i) <= n; ++i) 44 | for(int j = max(m, ii); j<=n; ++j) 45 | dp[j] = min(dp[j], dp[j-ii]+1); 46 | return dp[n]; 47 | } 48 | }; -------------------------------------------------------------------------------- /src/problems/task_016.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/17/24. 2 | //// Description https://leetcode.com/problems/evaluate-reverse-polish-notation/description/ 3 | //// @Solution_1 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | using namespace std::string_literals; 13 | 14 | class Solution { 15 | public: 16 | int evalRPN(vector &S) { 17 | unordered_map> func{ 18 | {'+', [](int a, int b) { return a + b; }}, 19 | {'-', [](int a, int b) { return a - b; }}, 20 | {'*', [](int a, int b) { return a * b; }}, 21 | {'/', [](int a, int b) { return a / b; }} 22 | }; 23 | stack st; 24 | 25 | for (auto &c: S) { 26 | if (!isdigit(c.back())) { 27 | auto b = st.top();st.pop(); 28 | auto a = st.top();st.pop(); 29 | st.push(func[c.back()](a, b)); 30 | } else st.push(stoi(c)); 31 | } 32 | return st.top(); 33 | } 34 | }; 35 | 36 | #define S size() 37 | #define PB push_back 38 | 39 | class Solution_1 { 40 | public: 41 | int evalRPN(vector &t) { 42 | vector st; 43 | unordered_map> ops{ 44 | {'+', [](int a, int b) { return a + b; }}, 45 | {'-', [](int a, int b) { return a - b; }}, 46 | {'*', [](int a, int b) { return a * b; }}, 47 | {'/', [](int a, int b) { return a / b; }} 48 | }; 49 | for (auto i: t) { 50 | if (ops.count(i.back())) { 51 | int a = st.back(); 52 | st.pop_back(); 53 | int b = st.back(); 54 | st.pop_back(); 55 | st.PB(ops[i.back()](b, a)); 56 | } else { 57 | st.PB(stoi(i)); 58 | } 59 | } 60 | return st.back(); 61 | } 62 | }; 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/problems/task_017.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/17/24. 2 | //// Description 3 | //// @Solution_1 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | class Solution_1 { 10 | public: 11 | int longestSubarray(vector &A, int l = 0, int r = 0) { 12 | for (int cnt = 1; r < A.size(); ++r) { 13 | cnt = !A[r] ? cnt - 1 : cnt; 14 | cnt = (cnt < 0 && !A[l++]) ? cnt + 1 : cnt; 15 | } 16 | return r - l - 1; 17 | } 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /src/problems/task_018.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/one-edit-distance 3 | //// @Solution 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | //// @class 10 | class Solution { 11 | public: 12 | bool isOneEditDistance(string s, string t) { 13 | int n = s.size(), m = t.size(); 14 | if(n < m) swap(s, t); 15 | 16 | for(int i = 0; i < n; ++i) { 17 | if(s[i] != t[i]) { 18 | if(n == m) return s.substr(i+1) == t.substr(i+1); 19 | return s.substr(i+1) == t.substr(i); 20 | } 21 | } 22 | return n == m+1; 23 | 24 | } 25 | }; 26 | 27 | 28 | #include 29 | 30 | int main() { 31 | Solution solution; 32 | assert(solution.isOneEditDistance("cat", "bat") == true); 33 | assert(solution.isOneEditDistance("cat", "cats") == true); 34 | assert(solution.isOneEditDistance("cat", "cut") == true); 35 | assert(solution.isOneEditDistance("cat", "cat") == false); 36 | assert(solution.isOneEditDistance("cat", "dog") == false); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /src/problems/task_019.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// DEscription https://leetcode.com/problems/move-zeroes/description/ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Solution { 11 | public: 12 | void moveZeroes(vector &A) { 13 | for(int s{}, f{}; f < A.size(); f = (A[f] ? swap(A[s++], A[f]), f+1 : f+1)); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/problems/task_020.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | //// @class 11 | class Solution { 12 | public: 13 | vector generateParenthesis(int n, vector ans = {}) } 14 | function func = [&](int l, int r, string s) { 15 | using namespace std::string_literals; 16 | if (s.size() == n * 2) ans.emplace_back(s); 17 | if (l < n) func(l + 1, r, s + "("s); 18 | if (r < l) func(l, r + 1, s + ")"s); 19 | }; 20 | func(0, 0, ""s); 21 | return ans; 22 | } 23 | }; -------------------------------------------------------------------------------- /src/problems/task_021.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/reverse-linked-list/ 3 | //// @Solution_3 , @Solution_1 , @Solution_2 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | 10 | struct ListNode { 11 | int val; 12 | ListNode *next; 13 | 14 | ListNode() : val(0), next(nullptr) {} 15 | 16 | ListNode(int x) : val(x), next(nullptr) {} 17 | 18 | ListNode(int x, ListNode *next) : val(x), next(next) {} 19 | }; 20 | 21 | //// @class 22 | class Solution_2 { 23 | public: 24 | ListNode *reverseList(ListNode *h, ListNode *p = nullptr) { 25 | for(; h; swap(p, h->next), swap(p, h)); 26 | return p; 27 | } 28 | }; 29 | 30 | //// @class 31 | class Solution_1 { 32 | public: 33 | ListNode *reverseList(ListNode *h) { 34 | if (!h) return h; 35 | ListNode *p = nullptr; 36 | while (h) { 37 | swap(p, h->next); 38 | swap(p, h); 39 | } 40 | return p; 41 | } 42 | }; 43 | 44 | //// @class 45 | class Solution_3 { 46 | public: 47 | ListNode *reverseList(ListNode *h) { 48 | if (!h) return h; 49 | ListNode *p = nullptr, *n; 50 | while (h) { 51 | n = h->next; 52 | h->next = p; 53 | p = h; 54 | h = n; 55 | } 56 | return p; 57 | } 58 | }; -------------------------------------------------------------------------------- /src/problems/task_022.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/group-anagrams/description/ 3 | //// @Solution 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | 14 | class Solution { 15 | public: 16 | vector> groupAnagrams(vector& s) { 17 | unordered_map mp; 18 | vector> ans(s.size()); 19 | int index{}; 20 | for (auto& w : s) { 21 | auto tmp = w; 22 | sort(w.begin(), w.end()); 23 | if (auto f = mp.find(w); f != mp.end()) 24 | ans[f->second].emplace_back(tmp); 25 | else 26 | ans[mp[w] = index++].emplace_back(tmp); 27 | } 28 | ans.resize(index); 29 | return ans; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /src/problems/task_023.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description 125. Valid Palindrome 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace std::string_literals; 9 | 10 | class Solution { 11 | public: 12 | bool isPalindrome(string s) { 13 | for(int l{}, r = s.size()-1; l <=r; ++l, --r) { 14 | if(!isalnum(s[r]))--l; 15 | else if(!isalnum(s[l]))++r; 16 | else if(tolower(s[l]) != tolower(s[r])) return false; 17 | } 18 | return true; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/problems/task_024.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/merge-intervals/description/ 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | vector> merge(vector> &A) { 12 | sort(A.begin(), A.end()); 13 | vector> ans{A[0]}; 14 | int n = A.size(); 15 | 16 | for (int i = 1; i < n; ++i) { 17 | if (ans.back()[1] >= A[i][0]) ans.back()[1] = max(ans.back()[1], A[i].back()); 18 | else ans.push_back(A[i]); 19 | } 20 | return ans; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/problems/task_025.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/validate-binary-search-tree/ 3 | 4 | struct TreeNode { 5 | int val; 6 | TreeNode *left; 7 | TreeNode *right; 8 | 9 | TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | 11 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | 13 | TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), 14 | right(right) {} 15 | }; 16 | 17 | class Solution { 18 | public: 19 | bool isValidBST(TreeNode *root, TreeNode *l = {}, TreeNode *r = {}) { 20 | if (!root) return true; 21 | if (l && l->val >= root->val || r && r->val <= root->val) return false; 22 | return isValidBST(root->left, l, root) && isValidBST(root->right, root, r); 23 | } 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /src/problems/task_026.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/valid-parentheses/ 3 | 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | bool isValid(string s) { 12 | stack st; 13 | 14 | for (auto c: s) { 15 | if (c == '(' || c == '{' || c == '[')st.push(c); 16 | else { 17 | if (st.empty()) return false; 18 | auto t = st.top(); 19 | st.pop(); 20 | if (t == '[' && c != ']' || 21 | t == '{' && c != '}' || 22 | t == '(' && c != ')') 23 | return false; 24 | } 25 | } 26 | return st.empty(); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/problems/task_027.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/trapping-rain-water 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | 11 | class Solution_1 { 12 | public: 13 | int trap(vector &h) { 14 | int l{}, r = h.size() - 1, lev{}, water{}; 15 | while (l < r) { 16 | int low = h[h[l] < h[r] ? l++ : r--]; 17 | lev = max(lev, low); 18 | water += lev - low; 19 | } 20 | return water; 21 | } 22 | }; 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/problems/task_028.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description 3 | /// Написать функцию, которая делает RLE сжатие строки, например "abbccc"→ "ab2c3" 4 | //// @Solution 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | class Solution { 19 | public: 20 | string LRE(string &s, string ans = "") { 21 | ans = s[0]; 22 | for (int cnt = 1, i = 1; i < s.size(); ++i) { 23 | if (ans.back() == s[i])++cnt; 24 | else { 25 | ans += (cnt > 1) ? to_string(cnt) : ""; 26 | cnt = 1; 27 | ans.push_back(s[i]); 28 | } 29 | if (i + 1 == s.size() && cnt > 1) ans += to_string(cnt); 30 | } 31 | std::cout << ans << '\n'; 32 | return ans; 33 | } 34 | }; 35 | 36 | 37 | int main() { 38 | using namespace std::string_literals; 39 | string str = "aaabbcccssssc"s; 40 | Solution s; 41 | assert(s.LRE(str) == "a3b2c3s4c"s); 42 | std::cout << "OK!\n"s; 43 | 44 | } -------------------------------------------------------------------------------- /src/problems/task_029.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/19/24. 2 | //// Создать класс с ассимптотиками unordered map, а также способной равновероятно выдавать один из входящих элементов 3 | //// https://leetcode.com/problems/insert-delete-getrandom-o1/ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | class RandomizedSet { 13 | unordered_map mp; 14 | vector v; 15 | public: 16 | RandomizedSet() { 17 | 18 | } 19 | 20 | bool insert(int val) { 21 | if (mp.contains(val)) return false; 22 | mp[val] = v.size(); 23 | v.push_back(val); 24 | return true; 25 | } 26 | 27 | bool remove(int val) { 28 | if (!mp.contains(val)) return false; 29 | auto f = mp[val]; 30 | v[f] = v.back(); 31 | mp[v[f]] = f; 32 | mp.erase(val); 33 | return true; 34 | } 35 | 36 | int getRandom() { 37 | return v[rand() % v.size()]; 38 | } 39 | }; -------------------------------------------------------------------------------- /src/problems/task_030.cpp: -------------------------------------------------------------------------------- 1 | //// Created by Jollu Emil on 5/19/24. 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Solution { 9 | public: 10 | int secondMax(vector &A) { 11 | int first = INT_MIN, sec = INT_MIN; 12 | for (auto i: A) { 13 | if (i > first) { 14 | sec = first; 15 | first = i; 16 | } else if (i > sec && i < first) { 17 | sec = i; 18 | } 19 | } 20 | return sec; 21 | } 22 | }; 23 | 24 | 25 | int main() { 26 | vector v{12, 3, 4, 5}; 27 | Solution s; 28 | std::cout << s.secondMax(v); 29 | } -------------------------------------------------------------------------------- /src/problems/task_031.cpp: -------------------------------------------------------------------------------- 1 | //// Created by Jollu Emil on 5/19/24. 2 | //// Description 560. Subarray Sum Equals K https://leetcode.com/problems/subarray-sum-equals-k/description/ 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Solution { 9 | public: 10 | int subarraySum(vector &A, int k, int sum = 0, int cnt = 0) { 11 | unordered_map mp; 12 | mp[0]++; 13 | for (int i{}; i < A.size(); ++i) { 14 | cnt += A[i]; 15 | if (auto f = mp.find(cnt - k); f != mp.end()) sum += f->second; 16 | mp[cnt]++; 17 | } 18 | return sum; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/problems/task_032.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/find-all-anagrams-in-a-string/description/ 3 | /// 4 | //// @Solution 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | 21 | //// @class 22 | class Solution { 23 | public: 24 | vector findAnagrams(string s, string p) { 25 | ios_base::sync_with_stdio(0); 26 | cin.tie(0); 27 | cout.tie(0); 28 | vector a(26), b(26), ans; 29 | int n = s.size(), m = p.size(); 30 | if(n < m) return {}; 31 | for(int i = 0; i < m; ++i) { 32 | ++a[p[i] - 'a']; 33 | ++b[s[i] - 'a']; 34 | } 35 | if(a == b)ans.push_back(0); 36 | for(int i = m; i < n; ++i) { 37 | --b[s[i-m] - 'a']; 38 | ++b[s[i] - 'a']; 39 | 40 | if(a == b) ans.push_back(i-m+1); 41 | } 42 | return ans; 43 | 44 | } 45 | }; 46 | 47 | int main() { 48 | Solution s; 49 | 50 | auto ans = s.findAnagrams("abacb", "abc"); // Выводит: (0,2) 51 | 52 | std::cout << ans.size(); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /src/problems/task_033.cpp: -------------------------------------------------------------------------------- 1 | //// Created by @Jollu8 on 5/18/24. 2 | //// Description https://leetcode.com/problems/add-strings/description/ 3 | /// 4 | //// @Solution_1 , @Solution_2 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | //// @class 21 | class Solution_1 { 22 | public: 23 | string addStrings(string A1, string A2) { 24 | int cnt{}; 25 | string ans; 26 | ans.reserve(max(A1.size(), A2.size()) + 2); 27 | auto a1 = A1.rbegin(); 28 | auto a2 = A2.rbegin(); 29 | for (; a1 != A1.rend() || a2 != A2.rend() || cnt; cnt /= 10) { 30 | if (a1 != A1.rend()) cnt += (*a1 - '0'), a1++; 31 | if (a2 != A2.rend()) cnt += (*a2 - '0'), a2++; 32 | ans += (char) ('0' + cnt % 10); 33 | } 34 | reverse(ans.begin(), ans.end()); 35 | return ans; 36 | } 37 | }; 38 | 39 | 40 | //// @class 41 | class Solution_2 { 42 | public: 43 | string addStrings(string A1, string A2) { 44 | [&]() { 45 | int n = A1.size(), m = A2.size(); 46 | if (n > m) 47 | A2 = string(n - m, '0') + A2; 48 | else if (m > n) 49 | A1 = string(m - n, '0') + A1; 50 | }(); 51 | string ans; 52 | int cnt{}; 53 | ans.reserve(A1.size() + 2); 54 | for (int i = A1.size() - 1; i >= 0; ++i, cnt /= 10) { 55 | cnt += (A1[i] - '0') + (A2[i] - 'a'); 56 | ans += (char) ('0' + cnt % 10); 57 | } 58 | if (cnt) 59 | ans += (char) ('0' + cnt); 60 | reverse(ans.begin(), ans.end()); 61 | return ans; 62 | } 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /start.md: -------------------------------------------------------------------------------- 1 | # Вот полный гид для вас 2 | 3 | # Важно! 4 | 5 | Чтобы быстро стать профессионалом, не делайте следующее: 6 | 1. Копипаста 7 | 2. Откладывание 8 | 3. Прыжки с места (если что-то не получается, отложите и вернитесь к этому через некоторое время) 9 | 4. Чтение всех больших книг 10 | --- 11 | 12 | 13 | ## 1. Основы языка 14 | - Прежде всего, перейдите: 15 | - [ссылке eng](https://www.hackerrank.com/domains/cpp?filters%5Bstatus%5D%5B%5D=unsolved&badge_type=cpp). 16 | - [база с практикой ru](https://stepik.org/course/7/promo) 17 | - [средний с практикой ru](https://stepik.org/course/3206) 18 | 19 | Если что-то не получается, прочитайте [гид](./readme.md) по остальным темам. 20 | 21 | ## 2. DSA 22 | - Как только вы освоите основы языка, перейдите по этой [ссылке](https://leetcode.com/explore/learn/card/the-leetcode-beginners-guide/679/sql-syntax/4358/). 23 | - Если некоторые материалы доступны только для премиум-аккаунта, переходите по этим ссылкам. 24 | - [graph](https://www.hackerearth.com/practice/algorithms/graphs/graph-representation/practice-problems/) 25 | - вот еще [мап](https://neetcode.io/roadmap) 26 | > Прежде начать создай себе вот такую таблицу 27 | 28 | 29 | 30 | ## 3. SQL 31 | - Выполните все эти [задачи и теория](https://rocksql.com/main_page). 32 | 33 | ## 4. Проектирование систем 34 | - Перейдите по этой [ссылке](https://leetcode.com/explore/learn/card/system-design/). 35 | - здесь [бесплатно](https://leetdesign.com/library/introduction) 36 | 37 | # 5. Работа 38 | - Напишите мне в [Telegram](https://www.t.me/jollu8). Я предоставлю материалы о том, как составить резюме, за чашечку кофе =) 39 | -------------------------------------------------------------------------------- /stash/merge_recursive_sort.md: -------------------------------------------------------------------------------- 1 | Да, это отличная идея! Разделение кода и комментариев может сделать статью более читаемой. Вот как это может выглядеть: 2 | 3 | --- 4 | 5 | # Рекурсивная сортировка слиянием 6 | 7 | #### Введение: 8 | 9 | В этой статье я попытаюсь объяснить вам алгоритм сортировки слиянием, известный как `merge_sort`, простым языком. Если 10 | вы ранее не могли понять, как он работает, то эта статья для вас. Здесь не будет обсуждаться сложность асимптотики или 11 | математическое доказательство, так как они усложняют все, и в интернете уже много написано и доказано на эту тему. 12 | 13 | > Этот учебник - отрывок из моего объяснения сути алгоритма сортировки и как они работают. 14 | 15 | #### Что от вас требуется: 16 | 17 | 1. Знать функциональное программирование и основы языка C++ 18 | 2. Хотя бы раз в жизни слышать, что такое рекурсия и как она работает 19 | 20 | #### Начало: 21 | 22 | Есть много видов сортировки, такие как `quick_sort`, `bubble_sort`, `shell_sort` и многие другие. 23 | Но самый простой из них - это `bubble_sort`, то есть вложенный цикл и обмен элементов. Но на практике он очень 24 | медленный. 25 | Поверьте, когда вы будете решать задачи, вам обязательно пригодится сортировка слиянием. 26 | 27 | Конечно, вот как сортировка слиянием разделяет и собирает массив: 28 | 29 | 1. Исходный массив: 30 | 31 | | 1 | 5 | 8 | 9 | 6 | 32 | |---|---|---|---|---| 33 | 34 | 2. Разделение на подмассивы: 35 | 36 | | 1 | 5 | 8 | 9 | 6 | 37 | |---|---|---|---|---| 38 | | 1 | 5 | 8 | - | - | 39 | | 9 | 6 | - | - | - | 40 | | 1 | 5 | - | - | - | 41 | | 9 | - | - | - | - | 42 | | 6 | - | - | - | - | 43 | | 1 | - | - | - | - | 44 | | 5 | - | - | - | - | 45 | 46 | 3. Слияние подмассивов: 47 | 48 | | 1 | 5 | - | - | - | 49 | |---|---|---|---|---| 50 | | 5 | 1 | - | - | - | 51 | | 9 | 6 | - | - | - | 52 | | 6 | 9 | - | - | - | 53 | | 1 | 5 | 6 | 9 | - | 54 | | 1 | 5 | 6 | 8 | 9 | 55 | 56 | 4. Итоговый отсортированный массив: 57 | 58 | | 1 | 5 | 6 | 8 | 9 | 59 | |---|---|---|---|---| 60 | 61 | ```c++ 62 | std::vector arr {1,5,8,9,6}; // массив будет в std векторе 63 | ``` 64 | 65 | ```c++ 66 | void merge_sort(std::vector& arr, int start, int end); 67 | ``` 68 | 69 | Как вы видите, функция будет принимать сам массив (важно! массив нужно передать через ссылку) 70 | и два типа `start` и `end` 71 | 72 | ```c++ 73 | int main() { 74 | std::vector arr {1,5,8,9,6}; 75 | merge_sort(arr, 0, arr.size()); // здесь 0 - это начало массива, то есть это start 76 | // arr.size() - это конец массива, то есть end == 5 77 | std::cout << "Вывод на косноль отсортированный массив\n"; 78 | for(auto i : arr) std::cout << i " "; 79 | } 80 | ``` 81 | 82 | Как показано выше на схеме, массив должен разделиться на две части, а затем еще на две части, пока размер массива больше '1' 83 | 84 | ```c++ 85 | void merge_sort(std::vector& arr, int start, int end) { // дальше код не будет дублироваться, так что читайте внимательно :) 86 | if(end - start < 2) return; // вот это и есть условие рекурсии. Если не поставить эту строку, то скорее всего 87 | // рекурсия будет выполняться до тех пор, пока не переполнится стек 88 | ``` 89 | 90 | Как выше было написано, ты должен разделить массив на две части. Но до этого надо найти центр массива. 91 | 92 | ```c++ 93 | const std::size_t mid = (start + end) / 2 // в первой рекурсии массив просто разделится на две части, вот и все 94 | 95 | // теперь надо разделить массив (на самом деле сам вектор не будет разделен, а только индексы будут разделены) 96 | 97 | merge_sort(arr, start, mid) // как видите, передал самой рекурсии часть диапазона массива 98 | // то есть выше будут переданы индексы для (1,5,8) 99 | merge_sort(arr, mid, end) // а вот здесь передается остальная часть 100 | // вот выше будет разделено, пока вот это условие верно if(end - start < 2) 101 | ``` 102 | 103 | В этом участке кода будет выполнен после того, как массив раздроблен до мелочей. Теперь обратно надо собрать все, то 104 | есть раскатать язык обратно (шутка). Но прежде всего нужен временный буфер. 105 | 106 | ```c++ 107 | std::vector buff; 108 | buff.reserve(end - start); // будет лучше, если сразу зарезервировать память (если не знаете, читайте про std vector capacity) 109 | 110 | std::size_t left = start; // это типа arr[i], то есть arr[left]. Диапазон его всегда до mid, так как массив разделен на две части 111 | // и у левой части последний индекс всегда до mid 112 | std::size_t right = mid; // а это точно такой же, как left, только у него диапазон с mid до end 113 | ``` 114 | 115 | Теперь надо заполнить временный вектор, ой, то есть буфер (buff). 116 | 117 | ```c++ 118 | while((left < mid) && (right < end)) { // обратите внимание здесь 119 | // как видите, условие поставлено очень странно. Здесь условие говорит, что цикл будет выполняться до тех пор, пока start меньше, чем mid, а right меньше end 120 | 121 | if(arr[left] < arr[right]) { // здесь на самом деле можно ставить какой-нибудь предикат. Я решил специально не ставить его, так как он усложняет код 122 | buff.push_back(arr[left]); // Если условие выполняется, добавляем элемент из левой части массива в буфер 123 | ++left; // условие сработало, значит, индекс надо увеличить на один, то есть i++ 124 | } else { 125 | buff.push_back(arr[right]); 126 | ++right; 127 | } 128 | } // выше в условии if говорится так: если левая часть удовлетворяет условию, то добавить в буфер элемент из левой части массива, а иначе - из правой части 129 | ``` 130 | 131 | Как выше в буфер добавились элементы, то скорее всего некоторые элементы останутся из левой или правой части. Здесь у 132 | вас должен быть вопрос: а как может остаться элемент, если в начале массив разделен на две части? Это очень просто. Как 133 | вы заметили, размер массива нечетный, а это 5%2 приводит к остатку, а это и есть наш оставшийся элемент. 134 | 135 | ```c++ 136 | while(left < mid) { 137 | buff.push_back(arr[left]); 138 | ++left; // как видите, здесь как в вышестоящем цикле 139 | } 140 | 141 | while(right < end) { 142 | buff.push_back(arr[right]); 143 | ++right; 144 | } 145 | ``` 146 | 147 | Ой, все, наконец-то написал почти все. Теперь самый последний штрих. Помните, выше я напомнил, чтобы массив обязательно 148 | передали через ссылку. Вот это сейчас пригодится. Теперь просто в массив вставить данные из буфера и все. Не буду 149 | выпендриваться, просто буду использовать std::copy. 150 | 151 | ```c++ 152 | std::copy(buff.begin(), buff.end(), arr.begin() + start); 153 | // обратите внимание на условие копирования 154 | // как видите, весь буфер копируется в массив, начиная с индекса start. Это сделано из-за т 155 | 156 | } 157 | ``` 158 | 159 | Исходный код [здесь](https://github.com/Jollu8/Algorithms/blob/7725440e3f4508dc37afee12fb001d46ab1f2639/Sort/Merge.cpp#L10) 160 | 161 | > Если ты понял все, попробуй реализовать merge_sort с функцией merge 162 | 163 | > Если получилось все, попробуй merge_sort сделать для single_linked_list 164 | -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // TODO: установите здесь ссылки на дополнительные заголовки, требующиеся для программы. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include /** for ostream_iterator */ 14 | #include /** for stack */ 15 | #include /** for queue */ 16 | #include /** for strcpy() */ 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | using namespace std; 28 | using namespace chrono; 29 | 30 | 31 | using write_sequence = vector; 32 | 33 | using test_pair = pair; 34 | using modify_sequence = vector; 35 | using read_sequence = vector; 36 | 37 | ifstream& operator >> (ifstream& _is, test_pair& _value) 38 | { 39 | _is >> _value.first; 40 | _is >> _value.second; 41 | 42 | return _is; 43 | } 44 | 45 | template 46 | S get_sequence(const string& _file_name) 47 | { 48 | ifstream infile(_file_name); 49 | S result; 50 | 51 | typename S::value_type item; 52 | 53 | while (infile >> item) 54 | { 55 | result.emplace_back(move(item)); 56 | } 57 | 58 | return result; 59 | } 60 | 61 | 62 | 63 | class storage 64 | { 65 | public: 66 | 67 | static const uint64_t Shirina_Massive = 128; 68 | 69 | 70 | //Node structure. 71 | struct TreeNode 72 | { 73 | char data[Shirina_Massive]; //data field 74 | TreeNode* l, * r; //left and right childs. 75 | 76 | TreeNode* parent; 77 | 78 | uint64_t LeftCounter; 79 | uint64_t RightCounter; 80 | 81 | }; 82 | 83 | 84 | //Variables 85 | TreeNode* pRoot; //pointer to the root of a tree 86 | uint64_t treeTotal; //The number of nodes in the tree 87 | 88 | 89 | storage() 90 | { 91 | treeTotal = 0; 92 | pRoot = nullptr; 93 | 94 | cout << "DEBUG: Constructor called... " << endl; 95 | }/* storage()*/ 96 | 97 | ~storage() 98 | { 99 | /** free allocated memory */ 100 | cout << "DEBUG: Destructor called... " << endl; 101 | 102 | DeleteTree_no_recursive(pRoot); 103 | 104 | cout << "Our Binary Tree Removed From Memory: treeTotal = " << treeTotal << endl << endl; 105 | 106 | }/* ref. to ~storage() */ 107 | 108 | void push_no_recursive(const char* a, TreeNode** troot) 109 | { 110 | TreeNode** t = troot; 111 | TreeNode* pParent = nullptr; 112 | 113 | while ((*t) != NULL) { 114 | 115 | if (strcmp(a, (*t)->data) < 0) { 116 | 117 | (*t)->LeftCounter++; 118 | pParent = (*t); 119 | 120 | t = &(*t)->l; 121 | continue; 122 | } 123 | else if (strcmp(a, (*t)->data) > 0) { 124 | 125 | (*t)->RightCounter++; 126 | pParent = (*t); 127 | 128 | t = &(*t)->r; 129 | continue; 130 | } 131 | 132 | } 133 | 134 | if ((*t) == NULL) 135 | { 136 | 137 | if (pRoot == nullptr) { 138 | (*t) = new TreeNode; 139 | strcpy((*t)->data, a); 140 | (*t)->l = (*t)->r = NULL; 141 | 142 | (*t)->parent = nullptr; 143 | (*t)->LeftCounter = 0; 144 | (*t)->RightCounter = 0; 145 | cout << "Starting initialization. " << "(*t)->data = " << (*t)->data << endl; 146 | } 147 | else { 148 | 149 | (*t) = new TreeNode; 150 | strcpy((*t)->data, a); 151 | (*t)->l = (*t)->r = NULL; 152 | 153 | (*t)->parent = pParent; 154 | 155 | (*t)->LeftCounter = 0; 156 | (*t)->RightCounter = 0; 157 | } 158 | treeTotal++; 159 | 160 | return; 161 | } 162 | 163 | }/*end of push_no_recursive() */ 164 | 165 | 166 | 167 | /* 168 | * Delete the tree, 169 | * Uses queue to delete all the tree. 170 | */ 171 | 172 | uint64_t DeleteTree_no_recursive(TreeNode* tRoot) 173 | { 174 | // Base Case 175 | if (tRoot == nullptr) 176 | return 0; 177 | 178 | // Create an empty queue for level order traversal 179 | queue q; 180 | 181 | // Do level order traversal starting from root 182 | q.push(tRoot); 183 | while (!q.empty()) 184 | { 185 | TreeNode* node = q.front(); 186 | q.pop(); 187 | 188 | if (node->l != nullptr) 189 | q.push(node->l); 190 | if (node->r != nullptr) 191 | q.push(node->r); 192 | 193 | delete node; 194 | } 195 | 196 | return 0; 197 | }/*end DeleteTree_no_recursive()*/ 198 | 199 | 200 | 201 | /* 202 | * Can show tree's elements. 203 | * Useful for debug purposes. 204 | * InOrder Traversal. 205 | * 206 | */ 207 | void Show_Simmetrich_no_recursive(TreeNode* troot) 208 | { 209 | stack s; 210 | TreeNode* curr = troot; 211 | 212 | uint64_t deb_cc = 0; 213 | while (curr != nullptr || s.empty() == false) 214 | { 215 | /* Reach the left most Node of the 216 | curr Node */ 217 | while (curr != nullptr) 218 | { 219 | /* place pointer to a tree node on 220 | the stack before traversing 221 | the node's left subtree */ 222 | s.push(curr); 223 | curr = curr->l; 224 | } 225 | 226 | /* Current must be nullptr at this point */ 227 | curr = s.top(); 228 | s.pop(); 229 | 230 | 231 | if (curr->parent == nullptr) { 232 | cout << "curr ptr= " << curr << " " << curr->data << " index = " << deb_cc++ << " curr->parent = " << "nullptr" << endl; 233 | } 234 | else { 235 | cout << "curr ptr= " << curr << " " << curr->data << " index = " << deb_cc++ << " curr->parent = " << curr->parent << " curr->parent->data = " << curr->parent->data << endl; 236 | } 237 | 238 | /* we have visited the node and its 239 | left subtree. Now, it's right 240 | subtree's turn */ 241 | curr = curr->r; 242 | 243 | } /* end of while */ 244 | 245 | 246 | }/*end Show_Simmetrich_no_recursive() */ 247 | 248 | 249 | 250 | /* 251 | * SUPPORT INDICES. 252 | * Delete node with current pointer _root 253 | * and parent _prev. 254 | * 255 | */ 256 | 257 | void delete_elem(TreeNode* _root, TreeNode* _prev) 258 | { 259 | TreeNode* curr = _root; 260 | TreeNode* prev = _prev; 261 | 262 | // Base case 263 | if (_root == nullptr) { 264 | return; 265 | } 266 | 267 | if (curr->l == nullptr && curr->r == nullptr) { /**this is a leaf */ 268 | 269 | if (prev != nullptr) { /** if remains the last node in the tree - root node ( i.e. prev=nullptr). */ 270 | 271 | if (curr == prev->l) { 272 | prev->l = nullptr; 273 | } 274 | else if (curr == prev->r) { 275 | prev->r = nullptr; 276 | } 277 | delete curr; 278 | } 279 | else { 280 | delete curr; 281 | pRoot = nullptr; 282 | } 283 | 284 | 285 | }/*ref. to if (curr->l == nullptr && curr->r == nullptr) */ 286 | 287 | 288 | // Check if the node to be 289 | // deleted has at most one child. 290 | else if (curr->l == nullptr || curr->r == nullptr) { 291 | 292 | // newCurr will replace 293 | // the node to be deleted. 294 | TreeNode* newCurr; 295 | 296 | // if the left child does not exist. 297 | if (curr->l == nullptr) { 298 | newCurr = curr->r; 299 | } 300 | else { 301 | newCurr = curr->l; 302 | } 303 | 304 | // check if the node to 305 | // be deleted is the root. 306 | if (prev == nullptr) { 307 | 308 | if (curr->r != nullptr) { 309 | newCurr = curr->r; 310 | newCurr->parent = nullptr; 311 | pRoot = newCurr; 312 | } 313 | else { /** closest left element must become the root. */ 314 | if (curr->l != nullptr) { 315 | newCurr = curr->l; 316 | newCurr->parent = nullptr; 317 | pRoot = newCurr; 318 | } 319 | 320 | } 321 | delete curr; 322 | return; 323 | } 324 | 325 | // check if the node to be deleted 326 | // is prev's left or right child 327 | // and then replace this with newCurr 328 | if (curr == prev->l) { 329 | prev->l = newCurr; 330 | } 331 | else { 332 | prev->r = newCurr; 333 | } 334 | 335 | // free memory of the 336 | // node to be deleted. 337 | newCurr->parent = prev; 338 | 339 | delete curr; 340 | } 341 | 342 | // node to be deleted has 343 | // two children. 344 | else { 345 | TreeNode* p = nullptr; 346 | TreeNode* temp; 347 | 348 | // Compute the inorder successor 349 | temp = curr->r; 350 | while (temp->l != nullptr) { 351 | p = temp; 352 | 353 | if (p->LeftCounter > 0) { 354 | p->LeftCounter--; 355 | } 356 | 357 | temp = temp->l; 358 | } 359 | 360 | // check if the parent of the inorder 361 | // successor is the curr or not(i.e. curr= 362 | // the node which has the same data as 363 | // the given data by the user to be 364 | // deleted). if it isn't, then make the 365 | // the left child of its parent equal to 366 | // the inorder successor'd right child. 367 | if (p != nullptr) { 368 | p->l = temp->r; 369 | 370 | if (temp->r == nullptr) { /** No right subtree of the left minimum node. */ 371 | p->LeftCounter = 0; 372 | } 373 | else { /** if there is right subtree of the left minimum node. */ 374 | p->LeftCounter = temp->RightCounter; 375 | temp->r->parent = p; 376 | } 377 | 378 | if (curr->RightCounter > 0 ) { 379 | curr->RightCounter--; 380 | } 381 | 382 | } 383 | 384 | // if the inorder successor was the 385 | // curr (i.e. curr = the node which has the 386 | // same data as the given data by the 387 | // user to be deleted), then make the 388 | // right child of the node to be 389 | // deleted equal to the right child of 390 | // the inorder successor. 391 | else { 392 | curr->r = temp->r; 393 | 394 | if (temp->r != nullptr) { 395 | temp->r->parent = curr; 396 | } 397 | 398 | curr->RightCounter = temp->RightCounter; 399 | } 400 | 401 | strcpy(curr->data, temp->data); 402 | 403 | delete temp; 404 | } 405 | 406 | }/* end delete_elem() */ 407 | 408 | 409 | /* 410 | * Classic version. Traversal through the tree. 411 | * Find wanted element by its number in sorted order 412 | * and return it. 413 | * Use InOrder Traversal. 414 | * 415 | */ 416 | char* get_by_num_no_recursive(TreeNode* troot, uint64_t num) 417 | { 418 | uint64_t OrderNum = 0; 419 | 420 | stack s; 421 | TreeNode* curr = troot; 422 | //int count = 1; 423 | 424 | while (curr != nullptr || s.empty() == false) 425 | { 426 | /* Reach the left most Node of the 427 | curr Node */ 428 | while (curr != nullptr) 429 | { 430 | /* place pointer to a tree node on 431 | the stack before traversing 432 | the node's left subtree */ 433 | s.push(curr); 434 | curr = curr->l; 435 | } 436 | 437 | /* Current must be nullptr at this point */ 438 | curr = s.top(); 439 | s.pop(); 440 | 441 | if (OrderNum == num) { 442 | return curr->data; 443 | } 444 | OrderNum++; 445 | 446 | 447 | /* we have visited the node and its 448 | left subtree. Now, it's right 449 | subtree's turn */ 450 | curr = curr->r; 451 | 452 | } /* end of while */ 453 | 454 | return nullptr; 455 | 456 | }/*end get_by_num_no_recursive() */ 457 | 458 | 459 | /* 460 | * Classic version. Traversal through the tree. 461 | * Find wanted element to delete by its number in sorted order 462 | * and delete it. 463 | * use InOrder Traversal. 464 | * 465 | */ 466 | void del_by_num_no_recursive(TreeNode* troot, uint64_t num) 467 | { 468 | uint64_t OrderNum = 0; 469 | 470 | struct __NODE { 471 | TreeNode* curr; 472 | TreeNode* prev; 473 | }node; 474 | 475 | stack s; 476 | TreeNode* curr = troot; 477 | TreeNode* prev = nullptr; 478 | 479 | while (curr != nullptr || s.empty() == false) 480 | { 481 | 482 | /* Reach the left most Node of the 483 | curr Node */ 484 | while (curr != NULL) 485 | { 486 | /* place pointer to a tree node on 487 | the stack before traversing 488 | the node's left subtree */ 489 | 490 | node.curr = curr; 491 | node.prev = prev; 492 | s.push(node); 493 | 494 | if (curr->l != nullptr) { 495 | prev = curr; 496 | } 497 | curr = curr->l; 498 | } 499 | 500 | /* Current must be NULL at this point */ 501 | node = s.top(); 502 | s.pop(); 503 | curr = node.curr; 504 | prev = node.prev; 505 | 506 | if (OrderNum == num) { 507 | delete_elem(node.curr, node.prev); 508 | break; 509 | 510 | } 511 | OrderNum++; 512 | 513 | if (curr->r != nullptr) { 514 | prev = curr; 515 | } 516 | 517 | /* we have visited the node and its 518 | left subtree. Now, it's right 519 | subtree's turn */ 520 | curr = curr->r; 521 | 522 | } /* end of while */ 523 | 524 | 525 | }/*end del_by_num_no_recursive() - Classic version. Traversal through the tree.*/ 526 | 527 | 528 | 529 | /* 530 | * Support indices. 531 | * Get an element by index from the tree. 532 | * 533 | */ 534 | char* get_elem_by_index(TreeNode* proot, uint64_t ind) 535 | { 536 | 537 | char* pRet = nullptr; 538 | TreeNode* ptr = proot; 539 | uint64_t sought_for_ind = ind; 540 | 541 | if (proot == nullptr) { 542 | cout << "The Tree is Emty !!! "; 543 | return 0; 544 | } 545 | 546 | if (ind > (treeTotal-1) ) { 547 | cout << "Too big index to get, index = " << ind << " treeTotal = " << treeTotal << " Stop. " << endl << endl; 548 | return 0; 549 | } 550 | 551 | while (ptr != nullptr) { 552 | 553 | if (sought_for_ind < ptr->LeftCounter) { /** work out left branch */ 554 | ptr = ptr->l; 555 | 556 | if (ptr == nullptr) { 557 | cout << " DEBUG POINT XXX L: ptr = nullptr from Left ind = " << ind << endl; 558 | } 559 | 560 | } 561 | else if (sought_for_ind == ptr->LeftCounter) { 562 | return ptr->data; 563 | } 564 | else if (sought_for_ind > ptr->LeftCounter) { /** work out right branch */ 565 | 566 | sought_for_ind = sought_for_ind - ptr->LeftCounter - 1; 567 | 568 | if (ptr->r == nullptr) { 569 | cout << " --DEBUG POINT XXX R: ptr->data=" << ptr->data << " ptr->LeftCounter=" << 570 | ptr->LeftCounter << " ptr->RightCounter=" << ptr->RightCounter << endl; 571 | } 572 | 573 | ptr = ptr->r; 574 | 575 | if (ptr == nullptr) { 576 | cout << " DEBUG POINT XXX R: ptr = nullptr from Right ind = " << ind << endl; 577 | } 578 | 579 | } 580 | } 581 | 582 | 583 | return pRet; 584 | 585 | }/*ref. to get_elem_by_index() */ 586 | 587 | 588 | 589 | 590 | /* 591 | * Support indices. 592 | * Delete an element by index from the tree. 593 | * 594 | */ 595 | char* delete_elem_by_index(TreeNode* proot, uint64_t ind) 596 | { 597 | 598 | char* pRet = nullptr; 599 | TreeNode* ptr = proot; 600 | uint64_t sought_for_ind = ind; 601 | 602 | if (proot == nullptr) { 603 | cout << "Can not delete. The Tree is Emty !!! "; 604 | return 0; 605 | } 606 | 607 | if (ind > (treeTotal - 1)) { 608 | cout << "Too big index to delete, index = " << ind << " treeTotal = " << treeTotal << " Stop. " << endl << endl; 609 | return 0; 610 | } 611 | 612 | 613 | while (ptr != nullptr) { 614 | 615 | if (sought_for_ind < ptr->LeftCounter) { /** work out left branch */ 616 | 617 | if (ptr->LeftCounter > 0) { 618 | ptr->LeftCounter--; 619 | } 620 | ptr = ptr->l; 621 | 622 | } 623 | else if (sought_for_ind == ptr->LeftCounter) { 624 | delete_elem(ptr, ptr->parent); 625 | break; 626 | } 627 | if (sought_for_ind > ptr->LeftCounter) { /** work out right branch */ 628 | 629 | sought_for_ind = sought_for_ind - ptr->LeftCounter - 1; 630 | 631 | if (ptr->RightCounter > 0) { 632 | ptr->RightCounter--; 633 | } 634 | 635 | ptr = ptr->r; 636 | 637 | } 638 | } 639 | 640 | 641 | return pRet; 642 | 643 | }/*ref. to delete_elem_by_index() */ 644 | 645 | 646 | 647 | 648 | public: 649 | void insert(const string& _str) 650 | { 651 | //TODO insert str with sorting 652 | push_no_recursive(_str.c_str(), &pRoot); //put a node in the tree 653 | 654 | }/*ref. to insert() */ 655 | 656 | 657 | 658 | 659 | void erase(uint64_t _index) 660 | { 661 | //TODO erase string via index 662 | //del_by_num_no_recursive(pRoot, _index); // - classic func. 663 | 664 | delete_elem_by_index(pRoot, _index); 665 | treeTotal--; 666 | 667 | }/** erase() */ 668 | 669 | 670 | 671 | const string& get(uint64_t _index) 672 | { 673 | static string retStr; 674 | char* pGet; 675 | 676 | //TODO return string via index 677 | 678 | retStr.clear(); 679 | 680 | //pGet=get_by_num_no_recursive(pRoot, _index); // - classic func. 681 | 682 | pGet = get_elem_by_index(pRoot, _index); 683 | 684 | if (pGet != nullptr) { 685 | retStr.assign(pGet, std::strlen(pGet)); 686 | } 687 | 688 | return retStr; 689 | } 690 | 691 | /* 692 | * Can print tree's elements as 693 | * sorted array. 694 | * Useful for debug. 695 | */ 696 | void print_container(TreeNode* container) 697 | { 698 | cout << "\nprint_container: " << endl; 699 | 700 | //Show_Simmetrich_no_recursive(pRoot); 701 | 702 | cout << "Get all elements in the tree by index: \n"; 703 | cout << "treeTotal = " << treeTotal << endl << endl;; 704 | char* resNum = nullptr; 705 | for (int i = 0; i < static_cast(treeTotal); i++) { 706 | 707 | resNum = get_elem_by_index(pRoot, i); 708 | cout << "[" << i << "] = " << resNum << endl; 709 | } 710 | }/* end of print_container() */ 711 | 712 | 713 | 714 | 715 | /* 716 | * Recursive function. 717 | * Return true if the tree is BST 718 | * and false if the tree is not BST. 719 | */ 720 | 721 | bool IsItBinarysearchTree(TreeNode* troot) 722 | { 723 | static TreeNode* prev = nullptr; 724 | 725 | if (troot == nullptr) 726 | { 727 | return true; 728 | } 729 | 730 | if (!IsItBinarysearchTree(troot->l)) 731 | { 732 | return false; 733 | } 734 | 735 | if ((prev != nullptr) && (strcmp(troot->data, prev->data) < 0)) 736 | { 737 | return false; 738 | } 739 | 740 | prev = troot; 741 | return IsItBinarysearchTree(troot->r);; 742 | 743 | }/*end of IsItBinarysearchTree() */ 744 | 745 | 746 | 747 | 748 | };/* ref. to class storage */ 749 | 750 | 751 | 752 | 753 | int main() 754 | { 755 | write_sequence write = get_sequence("write.txt"); 756 | modify_sequence modify = get_sequence("modify.txt"); 757 | read_sequence read = get_sequence("read.txt"); 758 | 759 | storage st; 760 | 761 | time_point time1; 762 | nanoseconds total_time1(0); 763 | time1 = system_clock::now(); 764 | 765 | for (const string& item : write) 766 | { 767 | st.insert(item); 768 | } 769 | 770 | cout << "Filling complete." << " The Tree size = " << st.treeTotal << " nodes." << endl; 771 | 772 | total_time1 += system_clock::now() - time1; 773 | cout << "Filling time: " << duration_cast(total_time1).count() << "ms" << endl; 774 | 775 | uint64_t progress = 0; 776 | uint64_t percent = modify.size() / 100; 777 | ////uint64_t percent = modify.size() / 10000; 778 | 779 | time_point time; 780 | nanoseconds total_time(0); 781 | 782 | modify_sequence::const_iterator mitr = modify.begin(); 783 | read_sequence::const_iterator ritr = read.begin(); 784 | 785 | int deb_count = 0; 786 | for (; mitr != modify.end() && ritr != read.end(); ++mitr, ++ritr) 787 | { 788 | time = system_clock::now(); 789 | 790 | st.erase(mitr->first); 791 | st.insert(mitr->second); 792 | const string& str = st.get(ritr->first); 793 | total_time += system_clock::now() - time; 794 | 795 | 796 | if (ritr->second != str) 797 | { 798 | cout << "test failed" << endl; 799 | //============= DEBUG 800 | 801 | cout << "mitr->first = " << mitr->first << " mitr->second = " << mitr->second << 802 | " ritr->first = " << ritr->first << endl; 803 | cout << "ritr->second = " << ritr->second << " str = " << str << endl; 804 | 805 | cout << "deb_count = " << deb_count << endl; // FOR DEBUG ONLY. 806 | cout << "ritr->second = " << ritr->second << " ritr->second.size() = " << ritr->second.size() << endl; 807 | cout << "str = " << str << " str.size() = " << str.size() << endl; 808 | 809 | //============= END: DEBUG 810 | 811 | return 1; 812 | } 813 | 814 | // if size() / 100 = 0 815 | if (percent == 0) { 816 | percent = 1; 817 | } 818 | 819 | 820 | if (++progress % (5 * percent) == 0) 821 | { 822 | cout << "time: " << duration_cast(total_time).count() 823 | << "ms progress: " << progress << " / " << modify.size() << "\n"; 824 | } 825 | 826 | // cout << "deb_count = " << deb_count << " progress = " << progress 827 | // << " percent = " << percent << endl; 828 | deb_count++; 829 | 830 | } 831 | 832 | cout << endl; 833 | cout << "===========" << endl; 834 | cout << "Test OK!" << endl; 835 | cout << "===========" << endl; 836 | 837 | /** Examine if the tree is BST */ 838 | bool IsTheTreeBST = st.IsItBinarysearchTree(st.pRoot); 839 | if (IsTheTreeBST) { 840 | cout << "\n\n This Tree Is The TRUE BST !!! \n\n"; 841 | } 842 | else { 843 | cout << "\n\n This Tree Is FALSE ??? \n\n"; 844 | } 845 | /** END: Examine if the tree is BST */ 846 | 847 | return 0; 848 | } 849 | 850 | --------------------------------------------------------------------------------