├── .gitignore ├── Ex0001_StandardLibraries ├── Ex0001_StandardLibraries.cpp ├── Ex0001_StandardLibraries.vcxproj └── Ex0001_StandardLibraries.vcxproj.filters ├── Ex0002_WarmingUp ├── Ex0002_WarmingUp.cpp ├── Ex0002_WarmingUp.vcxproj └── Ex0002_WarmingUp.vcxproj.filters ├── Ex0101_Addition ├── Ex0101_Addition.cpp ├── Ex0101_Addition.vcxproj └── Ex0101_Addition.vcxproj.filters ├── Ex0102_Subtraction ├── Ex0102_Subtraction.cpp ├── Ex0102_Subtraction.vcxproj └── Ex0102_Subtraction.vcxproj.filters ├── Ex0103_Multiplication ├── Ex0103_Multiplication.cpp ├── Ex0103_Multiplication.vcxproj └── Ex0103_Multiplication.vcxproj.filters ├── Ex0104_Karatsuba ├── Ex0104_Karatsuba.cpp ├── Ex0104_Karatsuba.vcxproj └── Ex0104_Karatsuba.vcxproj.filters ├── Ex0201_InsertionSort ├── Ex0201_InsertionSort.cpp ├── Ex0201_InsertionSort.vcxproj └── Ex0201_InsertionSort.vcxproj.filters ├── Ex0202_InsertionSortPerformance ├── Ex0202_InsertionSortPerformance.cpp ├── Ex0202_InsertionSortPerformance.vcxproj └── Ex0202_InsertionSortPerformance.vcxproj.filters ├── Ex0301_TopdownMergesort ├── Ex0301_TopdownMergesort.cpp ├── Ex0301_TopdownMergesort.vcxproj └── Ex0301_TopdownMergesort.vcxproj.filters ├── Ex0302_BottomupMergesort ├── Ex0302_BottomupMergesort.cpp ├── Ex0302_BottomupMergesort.vcxproj └── Ex0302_BottomupMergesort.vcxproj.filters ├── Ex0401_CountOccurrences ├── Ex0401_CountOccurrences.cpp ├── Ex0401_CountOccurrences.vcxproj └── Ex0401_CountOccurrences.vcxproj.filters ├── Ex0402_PartialSelectionSort ├── Ex0402_PartialSelectionSort.cpp ├── Ex0402_PartialSelectionSort.vcxproj └── Ex0402_PartialSelectionSort.vcxproj.filters ├── Ex0403_MinAndMax ├── Ex0403_MinAndMax.cpp ├── Ex0403_MinAndMax.vcxproj └── Ex0403_MinAndMax.vcxproj.filters ├── Ex0404_PartitionByPivot ├── Ex0404_PartitionByPivot.cpp ├── Ex0404_PartitionByPivot.vcxproj └── Ex0404_PartitionByPivot.vcxproj.filters ├── Ex0405_ExpectedLinearSelection ├── Ex0405_ExpectedLinearSelection.cpp ├── Ex0405_ExpectedLinearSelection.vcxproj └── Ex0405_ExpectedLinearSelection.vcxproj.filters ├── Ex0406_WorstcaseLinearSelection ├── Ex0406_WorstcaseLinearSelection.cpp ├── Ex0406_WorstcaseLinearSelection.vcxproj └── Ex0406_WorstcaseLinearSelection.vcxproj.filters ├── Ex0501_RandomizedQuicksort ├── Ex0501_RandomizedQuicksort.cpp ├── Ex0501_RandomizedQuicksort.vcxproj └── Ex0501_RandomizedQuicksort.vcxproj.filters ├── Ex0502_Quick3way ├── Ex0502_Quick3way.cpp ├── Ex0502_Quick3way.vcxproj └── Ex0502_Quick3way.vcxproj.filters ├── Ex0601_CountingSort ├── Ex0601_CountingSort.cpp ├── Ex0601_CountingSort.vcxproj └── Ex0601_CountingSort.vcxproj.filters ├── Ex0602_RadixSort ├── Ex0602_RadixSort.cpp ├── Ex0602_RadixSort.vcxproj └── Ex0602_RadixSort.vcxproj.filters ├── Ex0603_SortingWords ├── Ex0603_SortingWords.cpp ├── Ex0603_SortingWords.vcxproj └── Ex0603_SortingWords.vcxproj.filters ├── Ex0604_BucketSort ├── Ex0604_BucketSort.cpp ├── Ex0604_BucketSort.vcxproj └── Ex0604_BucketSort.vcxproj.filters ├── Ex0701_RedBlackTree ├── Ex0701_RedBlackTree.cpp ├── Ex0701_RedBlackTree.vcxproj └── Ex0701_RedBlackTree.vcxproj.filters ├── Ex0801_SeparateChaining ├── Ex0801_SeparateChaining.cpp ├── Ex0801_SeparateChaining.vcxproj └── Ex0801_SeparateChaining.vcxproj.filters ├── Ex0802_UnorderedMap ├── Ex0802_UnorderedMap.cpp ├── Ex0802_UnorderedMap.vcxproj └── Ex0802_UnorderedMap.vcxproj.filters ├── Ex0803_RomanNumeral ├── Ex0803_RomanNumeral.cpp ├── Ex0803_RomanNumeral.vcxproj └── Ex0803_RomanNumeral.vcxproj.filters ├── Ex0901_DepthFirstPaths ├── Ex0901_DepthFirstPaths.cpp ├── Ex0901_DepthFirstPaths.vcxproj └── Ex0901_DepthFirstPaths.vcxproj.filters ├── Ex0902_QueueBasedTopologicalSorting ├── Ex0902_QueueBasedTopologicalSorting.cpp ├── Ex0902_QueueBasedTopologicalSorting.vcxproj └── Ex0902_QueueBasedTopologicalSorting.vcxproj.filters ├── Ex0903_TopologicalSorting ├── Ex0903_TopologicalSorting.cpp ├── Ex0903_TopologicalSorting.vcxproj └── Ex0903_TopologicalSorting.vcxproj.filters ├── Ex0904_DegreesOfSeparation ├── Ex0904_DegreesOfSeparation.cpp ├── Ex0904_DegreesOfSeparation.vcxproj ├── Ex0904_DegreesOfSeparation.vcxproj.filters └── movies.txt ├── Ex0905_SymbolGraph ├── Ex0905_SymbolGraph.cpp ├── Ex0905_SymbolGraph.vcxproj └── Ex0905_SymbolGraph.vcxproj.filters ├── Ex0906_DirectedCycleDetection ├── Ex0906_DirectedCycleDetection.cpp ├── Ex0906_DirectedCycleDetection.vcxproj └── Ex0906_DirectedCycleDetection.vcxproj.filters ├── Ex0908_TracingDFS ├── Ex0908_TracingDFS.cpp ├── Ex0908_TracingDFS.vcxproj └── Ex0908_TracingDFS.vcxproj.filters ├── Ex1001_ConnectedComponents ├── Ex1001_ConnectedComponents.cpp ├── Ex1001_ConnectedComponents.vcxproj └── Ex1001_ConnectedComponents.vcxproj.filters ├── Ex1002_StrongComponents(BruteForce) ├── Ex1002_StrongComponents(BruteForce).cpp ├── Ex1002_StrongComponents(BruteForce).vcxproj └── Ex1002_StrongComponents(BruteForce).vcxproj.filters ├── Ex1003_KosarajuStrongComponents ├── Ex1003_KosarajuStrongComponents.cpp ├── Ex1003_KosarajuStrongComponents.vcxproj └── Ex1003_KosarajuStrongComponents.vcxproj.filters ├── Ex1101_PriorityQueue ├── Ex1101_PriorityQueue.cpp ├── Ex1101_PriorityQueue.vcxproj └── Ex1101_PriorityQueue.vcxproj.filters ├── Ex1102_IndexMinPQ ├── Ex1102_IndexMinPQ.cpp ├── Ex1102_IndexMinPQ.vcxproj ├── Ex1102_IndexMinPQ.vcxproj.filters └── IndexMinPQ.h ├── Ex1103_Dijkstra(IndexMinPQ) ├── Ex1103_Dijkstra(IndexMinPQ).cpp ├── Ex1103_Dijkstra(IndexMinPQ).vcxproj └── Ex1103_Dijkstra(IndexMinPQ).vcxproj.filters ├── Ex1104_Dijkstra(LinearSearch) ├── Ex1104_Dijkstra(LinearSearch).cpp ├── Ex1104_Dijkstra(LinearSearch).vcxproj └── Ex1104_Dijkstra(LinearSearch).vcxproj.filters ├── Ex1105_Dijkstra ├── Ex1105_Dijkstra.cpp ├── Ex1105_Dijkstra.vcxproj └── Ex1105_Dijkstra.vcxproj.filters ├── Ex1201_Fibonacci ├── Ex1201_Fibonacci.cpp ├── Ex1201_Fibonacci.vcxproj └── Ex1201_Fibonacci.vcxproj.filters ├── Ex1202_RodCutting ├── Ex1202_RodCutting.cpp ├── Ex1202_RodCutting.vcxproj └── Ex1202_RodCutting.vcxproj.filters ├── Ex1203_BellmanFord ├── Ex1203_BellmanFord.cpp ├── Ex1203_BellmanFord.vcxproj └── Ex1203_BellmanFord.vcxproj.filters ├── Ex1204_Arbitrage ├── Ex1204_Arbitrage.cpp ├── Ex1204_Arbitrage.vcxproj └── Ex1204_Arbitrage.vcxproj.filters ├── Ex1205_FloydWarshall ├── Ex1205_FloydWarshall.cpp ├── Ex1205_FloydWarshall.vcxproj └── Ex1205_FloydWarshall.vcxproj.filters ├── Ex1301_LongestCommonSequence ├── Ex1301_LongestCommonSequence.cpp ├── Ex1301_LongestCommonSequence.vcxproj └── Ex1301_LongestCommonSequence.vcxproj.filters ├── Ex1302_ZeroOneKnapsack ├── Ex1302_ZeroOneKnapsack.cpp ├── Ex1302_ZeroOneKnapsack.vcxproj └── Ex1302_ZeroOneKnapsack.vcxproj.filters ├── Ex1303_UnboundedKnapsack ├── Ex1303_UnboundedKnapsack.cpp ├── Ex1303_UnboundedKnapsack.vcxproj └── Ex1303_UnboundedKnapsack.vcxproj.filters ├── Ex1304_LargestIndependentSet ├── Ex1304_LargestIndependentSet.cpp ├── Ex1304_LargestIndependentSet.vcxproj └── Ex1304_LargestIndependentSet.vcxproj.filters ├── Ex1401_FractionalKnapsack ├── Ex1401_FractionalKnapsack.cpp ├── Ex1401_FractionalKnapsack.vcxproj └── Ex1401_FractionalKnapsack.vcxproj.filters ├── Ex1402_ActivitySelection ├── Ex1402_ActivitySelection.cpp ├── Ex1402_ActivitySelection.vcxproj └── Ex1402_ActivitySelection.vcxproj.filters ├── Ex1403_HuffmanCoding ├── Ex1403_HuffmanCoding.cpp ├── Ex1403_HuffmanCoding.vcxproj └── Ex1403_HuffmanCoding.vcxproj.filters ├── Ex1501_PrimMST ├── Ex1501_PrimMST.cpp ├── Ex1501_PrimMST.vcxproj └── Ex1501_PrimMST.vcxproj.filters ├── Ex1502_UnionFind ├── Ex1502_UnionFind.cpp ├── Ex1502_UnionFind.vcxproj ├── Ex1502_UnionFind.vcxproj.filters └── UnionFind.h ├── Ex1503_KruskalMST ├── Ex1503_KruskalMST.cpp ├── Ex1503_KruskalMST.vcxproj └── Ex1503_KruskalMST.vcxproj.filters ├── Ex1601_FordFulkerson ├── Ex1601_FordFulkerson.cpp ├── Ex1601_FordFulkerson.vcxproj └── Ex1601_FordFulkerson.vcxproj.filters ├── Ex1701_BipartiteGraph ├── Ex1701_BipartiteGraph.cpp ├── Ex1701_BipartiteGraph.vcxproj └── Ex1701_BipartiteGraph.vcxproj.filters ├── Ex1702_GaleShapley ├── Ex1702_GaleShapley.cpp ├── Ex1702_GaleShapley.vcxproj └── Ex1702_GaleShapley.vcxproj.filters ├── Ex1801_LongestPath ├── Ex1801_LongestPath.cpp ├── Ex1801_LongestPath.vcxproj └── Ex1801_LongestPath.vcxproj.filters ├── Ex1802_TravellingSalesmanProblem ├── Ex1802_TravellingSalesmanProblem.cpp ├── Ex1802_TravellingSalesmanProblem.vcxproj └── Ex1802_TravellingSalesmanProblem.vcxproj.filters ├── HongLabAlgorithmsPart1.sln ├── README.md ├── VSCode ├── Ex0001_StandardLibraries │ └── Ex0001_StandardLibraries.cpp ├── Ex0002_WarmingUp │ └── Ex0002_WarmingUp.cpp ├── Ex0101_Addition │ └── Ex0101_Addition.cpp ├── Ex0102_Subtraction │ └── Ex0102_Subtraction.cpp ├── Ex0103_Multiplication │ └── Ex0103_Multiplication.cpp ├── Ex0104_Karatsuba │ └── Ex0104_Karatsuba.cpp ├── Ex0201_InsertionSort │ └── Ex0201_InsertionSort.cpp ├── Ex0202_InsertionSortPerformance │ └── Ex0202_InsertionSortPerformance.cpp ├── Ex0301_TopdownMergesort │ └── Ex0301_TopdownMergesort.cpp ├── Ex0302_BottomupMergesort │ └── Ex0302_BottomupMergesort.cpp ├── Ex0401_CountOccurrences │ └── Ex0401_CountOccurrences.cpp ├── Ex0402_PartialSelectionSort │ └── Ex0402_PartialSelectionSort.cpp ├── Ex0403_MinAndMax │ └── Ex0403_MinAndMax.cpp ├── Ex0404_PartitionByPivot │ └── Ex0404_PartitionByPivot.cpp ├── Ex0405_ExpectedLinearSelection │ └── Ex0405_ExpectedLinearSelection.cpp ├── Ex0406_WorstcaseLinearSelection │ └── Ex0406_WorstcaseLinearSelection.cpp ├── Ex0501_RandomizedQuicksort │ └── Ex0501_RandomizedQuicksort.cpp ├── Ex0502_Quick3way │ └── Ex0502_Quick3way.cpp ├── Ex0601_CountingSort │ └── Ex0601_CountingSort.cpp ├── Ex0602_RadixSort │ └── Ex0602_RadixSort.cpp ├── Ex0603_SortingWords │ └── Ex0603_SortingWords.cpp ├── Ex0604_BucketSort │ └── Ex0604_BucketSort.cpp ├── Ex0701_RedBlackTree │ └── Ex0701_RedBlackTree.cpp ├── Ex0801_SeparateChaining │ └── Ex0801_SeparateChaining.cpp ├── Ex0802_UnorderedMap │ └── Ex0802_UnorderedMap.cpp ├── Ex0803_RomanNumeral │ └── Ex0803_RomanNumeral.cpp ├── Ex0901_DepthFirstPaths │ └── Ex0901_DepthFirstPaths.cpp ├── Ex0902_QueueBasedTopologicalSorting │ └── Ex0902_QueueBasedTopologicalSorting.cpp ├── Ex0903_TopologicalSorting │ └── Ex0903_TopologicalSorting.cpp ├── Ex0904_DegreesOfSeparation │ └── Ex0904_DegreesOfSeparation.cpp ├── Ex0905_SymbolGraph │ └── Ex0905_SymbolGraph.cpp ├── Ex0906_DirectedCycleDetection │ └── Ex0906_DirectedCycleDetection.cpp ├── Ex0908_TracingDFS │ └── Ex0908_TracingDFS.cpp ├── Ex1001_ConnectedComponents │ └── Ex1001_ConnectedComponents.cpp ├── Ex1002_StrongComponents(BruteForce) │ └── Ex1002_StrongComponents(BruteForce).cpp ├── Ex1003_KosarajuStrongComponents │ └── Ex1003_KosarajuStrongComponents.cpp ├── Ex1101_PriorityQueue │ └── Ex1101_PriorityQueue.cpp ├── Ex1102_IndexMinPQ │ ├── Ex1102_IndexMinPQ.cpp │ └── IndexMinPQ.h ├── Ex1103_Dijkstra(IndexMinPQ) │ └── Ex1103_Dijkstra(IndexMinPQ).cpp ├── Ex1104_Dijkstra(LinearSearch) │ └── Ex1104_Dijkstra(LinearSearch).cpp ├── Ex1105_Dijkstra │ └── Ex1105_Dijkstra.cpp ├── Ex1201_Fibonacci │ └── Ex1201_Fibonacci.cpp ├── Ex1202_RodCutting │ └── Ex1202_RodCutting.cpp ├── Ex1203_BellmanFord │ └── Ex1203_BellmanFord.cpp ├── Ex1204_Arbitrage │ └── Ex1204_Arbitrage.cpp ├── Ex1205_FloydWarshall │ └── Ex1205_FloydWarshall.cpp ├── Ex1301_LongestCommonSequence │ └── Ex1301_LongestCommonSequence.cpp ├── Ex1302_ZeroOneKnapsack │ └── Ex1302_ZeroOneKnapsack.cpp ├── Ex1303_UnboundedKnapsack │ └── Ex1303_UnboundedKnapsack.cpp ├── Ex1304_LargestIndependentSet │ └── Ex1304_LargestIndependentSet.cpp ├── Ex1401_FractionalKnapsack │ └── Ex1401_FractionalKnapsack.cpp ├── Ex1402_ActivitySelection │ └── Ex1402_ActivitySelection.cpp ├── Ex1403_HuffmanCoding │ └── Ex1403_HuffmanCoding.cpp ├── Ex1501_PrimMST │ └── Ex1501_PrimMST.cpp ├── Ex1502_UnionFind │ ├── Ex1502_UnionFind.cpp │ └── UnionFind.h ├── Ex1503_KruskalMST │ └── Ex1503_KruskalMST.cpp ├── Ex1601_FordFulkerson │ └── Ex1601_FordFulkerson.cpp ├── Ex1701_BipartiteGraph │ └── Ex1701_BipartiteGraph.cpp ├── Ex1702_GaleShapley │ └── Ex1702_GaleShapley.cpp ├── Ex1801_LongestPath │ └── Ex1801_LongestPath.cpp └── Ex1802_TravellingSalesmanProblem │ └── Ex1802_TravellingSalesmanProblem.cpp └── copy_files.py /Ex0001_StandardLibraries/Ex0001_StandardLibraries.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0002_WarmingUp/Ex0002_WarmingUp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | // 문제 1. 10진수 -> 2진수 8 | { 9 | int decimal = 105; 10 | string binary; 11 | 12 | //TODO: 13 | 14 | cout << binary << endl; // 1101001 15 | } 16 | 17 | // 문제 2. 문자열 뒤집기 18 | { 19 | string input = "Hello, World!"; 20 | 21 | // TODO: 22 | 23 | cout << input << endl; // !dlroW ,olleH 24 | } 25 | 26 | // 문제 3. 모든 자리 다 더하기 27 | { 28 | string n = "789789"; 29 | 30 | // TODO: 31 | 32 | cout << n << endl; 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /Ex0002_WarmingUp/Ex0002_WarmingUp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0101_Addition/Ex0101_Addition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string Add(string str1, string str2) 8 | { 9 | // TODO: 10 | 11 | return string("0"); 12 | } 13 | 14 | int main() 15 | { 16 | vector> tests = { 17 | {"12", "34", to_string(12 + 34)} 18 | , {"123", "45", to_string(123 + 45)} 19 | , {"54544", "44545", to_string(54544 + 44545)} 20 | , {"5555", "55", to_string(5555 + 55)} 21 | , {"5555", "5555", to_string(5555 + 5555)} 22 | , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "11538017781967960909090003089999089"} 23 | }; 24 | 25 | for (const auto& t : tests) 26 | { 27 | const string str1 = t[0]; // "12" 28 | const string str2 = t[1]; // "34" 29 | const string expected = t[2]; // "46" 30 | 31 | cout << str1 << " + " << str2 << " = " << expected << endl; 32 | 33 | const string result = Add(str1, str2); 34 | 35 | cout << result << " " << expected << " "; 36 | 37 | if (result == expected) 38 | cout << "OK" << endl; 39 | else { 40 | cout << "Not OK" << endl; 41 | exit(-1); 42 | } 43 | cout << endl << endl; 44 | } 45 | 46 | cout << "Congratulations. All OK!" << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Ex0101_Addition/Ex0101_Addition.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0102_Subtraction/Ex0102_Subtraction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // 항상 큰 수에서 작은 수를 빼는 경우(결과가 음수가 되지 않는 경우)를 가정 8 | string Subtract(string str1, string str2) 9 | { 10 | // 둘이 같을 경우 바로 "0" 반환 11 | if (str1 == str2) 12 | return "0"; // '0'은 char, "0"은 string 13 | 14 | int N = max(str1.size(), str2.size()); 15 | str1 = string(N - str1.size(), '0') + str1; // 문자열끼리의 더하기도 가능 16 | str2 = string(N - str2.size(), '0') + str2; 17 | 18 | string result(N, '0'); 19 | 20 | // TODO: 더하기와 거의 비슷합니다. 21 | 22 | // 불필요한 '0' 제거 (예: "078" -> "78") 23 | // TODO: 24 | 25 | return result; 26 | } 27 | 28 | int main() 29 | { 30 | // 항상 큰 수에서 작은 수를 빼는 경우(결과가 음수가 되지 않는 경우)를 가정 31 | vector> tests = { 32 | {"34", "12", std::to_string(34 - 12)} 33 | , {"123", "45", std::to_string(123 - 45)} 34 | , {"54544", "44545", std::to_string(54544 - 44545)} 35 | , {"5555", "55", std::to_string(5555 - 55)} 36 | , {"5555", "5555", std::to_string(5555 - 5555)} 37 | , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "8108924688874870000000906000909999"} 38 | }; 39 | 40 | for (const auto& t : tests) 41 | { 42 | const string str1 = t[0]; 43 | const string str2 = t[1]; 44 | const string expected = t[2]; 45 | 46 | cout << str1 << " - " << str2 << " = " << expected << endl; 47 | 48 | const string result = Subtract(str1, str2); 49 | 50 | cout << result << " " << expected << " "; 51 | 52 | if (result == expected) 53 | cout << "OK"; 54 | else { 55 | cout << "Not OK"; 56 | exit(-1); 57 | } 58 | cout << endl << endl; 59 | } 60 | 61 | cout << "Congratulations. All OK!" << endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Ex0102_Subtraction/Ex0102_Subtraction.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0103_Multiplication/Ex0103_Multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string Multiply(string str1, string str2) 8 | { 9 | // TODO: 10 | 11 | return "0"; 12 | } 13 | 14 | int main() 15 | { 16 | vector> tests = { 17 | {"12", "34", std::to_string(12 * 34)}, 18 | {"123", "45", std::to_string(123 * 45)}, 19 | {"5555", "55", std::to_string(5555 * 55)}, 20 | {"5555", "5555", std::to_string(5555 * 5555)}, 21 | {"98234712354214154", "171454654654655", "16842798681791158832220782986870"} 22 | // , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "16842798681791114273590624445460185389471221520083884298838480662480"} 23 | }; 24 | 25 | for (const auto& t : tests) 26 | { 27 | const string str1 = t[0]; 28 | const string str2 = t[1]; 29 | const string expected = t[2]; 30 | 31 | cout << str1 << " * " << str2 << " = " << expected << endl; 32 | 33 | const string result = Multiply(str1, str2); 34 | 35 | cout << result << " " << expected << " "; 36 | 37 | if (result == expected) 38 | cout << "OK"; 39 | else { 40 | cout << "Not OK"; 41 | exit(-1); 42 | } 43 | cout << endl << endl; 44 | } 45 | 46 | cout << "Congratulations. All OK!" << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Ex0103_Multiplication/Ex0103_Multiplication.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0104_Karatsuba/Ex0104_Karatsuba.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0201_InsertionSort/Ex0201_InsertionSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool CheckSorted(vector& arr) 6 | { 7 | for (int i = 0; i < arr.size() - 1; i++) 8 | { 9 | if (arr[i] > arr[i + 1]) 10 | return false; 11 | } 12 | 13 | return true; 14 | } 15 | 16 | void Print(vector& arr) 17 | { 18 | for (auto v : arr) 19 | cout << v << " "; 20 | cout << endl; 21 | } 22 | 23 | int main() 24 | { 25 | // vector a = { 6, 5, 4, 3, 2, 1 }; 26 | vector a = { 6, 4, 3, 8, 5 }; 27 | 28 | int N = a.size(); 29 | for (int i = 1; i < N; i++) 30 | { 31 | // TODO: 딱 2줄만 사용 32 | 33 | Print(a); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Ex0201_InsertionSort/Ex0201_InsertionSort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0202_InsertionSortPerformance/Ex0202_InsertionSortPerformance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include // std::iota 8 | 9 | using namespace std; 10 | using namespace std::chrono; 11 | 12 | void Print(vector& arr) 13 | { 14 | for (int i = 0; i < arr.size(); i++) 15 | cout << arr[i] << " "; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | void InsertionSort1(vector& a) 31 | { 32 | int N = a.size(); 33 | for (int i = 1; i < N; i++) 34 | for (int j = i; j > 0 && a[j - 1] > a[j]; j--) 35 | swap(a[j - 1], a[j]); 36 | } 37 | 38 | void InsertionSort2(vector& a) 39 | { 40 | int N = a.size(); 41 | int i; 42 | for (i = 1; i < N; i++) 43 | { 44 | int key = a[i]; 45 | int j = i; 46 | for (; j > 0 && a[j - 1] > key; j--) 47 | a[j] = a[j - 1]; 48 | a[j] = key; 49 | } 50 | } 51 | 52 | struct Sample { 53 | int n; 54 | double duration; 55 | }; 56 | 57 | int main() 58 | { 59 | random_device rd; 60 | mt19937 gen(rd()); 61 | 62 | vector samples; 63 | samples.reserve(5000); 64 | 65 | for (int n = 1; n <= 5000; n += 1) 66 | { 67 | vector my_vector(n); 68 | 69 | for (int r = 0; r < n; r += max(1, n / 100)) 70 | { 71 | // 0 이상 n-1 이하의 정수가 균일한 확률로 생성되는 난수 (uniform distribution) 72 | //uniform_int_distribution value_distribution(0, n - 1); 73 | //generate(my_vector.begin(), my_vector.end(), [&]() { return value_distribution(gen); }); 74 | 75 | std::iota(my_vector.begin(), my_vector.end(), 0); // iota는 0, 1, 2, ... , n-1 까지 순서대로 채워주는 함수 76 | std::reverse(my_vector.begin(), my_vector.end()); // 최악의 경우를 만들기 위해 순서를 뒤집어주기 77 | std::random_shuffle(my_vector.begin(), my_vector.begin() + r); // 일부만 순서를 바꿔줌 (shuffle은 딜러가 카드 섞는 것 생각하면 됩니다.) 78 | 79 | // Print(my_vector); 80 | 81 | // Random case 82 | auto start = high_resolution_clock::now(); 83 | 84 | InsertionSort2(my_vector); 85 | 86 | auto stop = high_resolution_clock::now(); 87 | auto dur = double(duration_cast(stop - start).count()) / 1000000000.0; 88 | 89 | if (!CheckSorted(my_vector)) 90 | { 91 | cout << "Failed." << endl; 92 | exit(-1); 93 | } 94 | 95 | samples.push_back({ n, dur }); 96 | 97 | if (n % 1000 == 0 && r == 0) 98 | { 99 | cout << n << " : " << dur << endl; 100 | } 101 | } 102 | } 103 | 104 | ofstream ofile("result_insertion2_worstshuffle.txt"); 105 | for (auto& s : samples) 106 | ofile << s.n << ", " << s.duration << endl; 107 | 108 | ofile.close(); 109 | 110 | cout << "\a" << endl; 111 | } 112 | -------------------------------------------------------------------------------- /Ex0202_InsertionSortPerformance/Ex0202_InsertionSortPerformance.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0301_TopdownMergesort/Ex0301_TopdownMergesort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // setfill(), setw() 4 | #include // iota 5 | 6 | using namespace std; 7 | 8 | void Print(vector& arr, int lo, int hi) 9 | { 10 | // setfill(), setw()는 줄맞춤에 사용 11 | 12 | for (int i = 0; i < lo; i++) 13 | cout << " "; 14 | for (int i = lo; i <= hi; i++) 15 | cout << setfill(' ') << setw(3) << arr[i]; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | // Sedgewick p. 273 31 | class TopDownMerge 32 | { 33 | public: 34 | void Sort(vector& a) 35 | { 36 | count = 0; // 분석용 37 | aux.resize(a.size()); 38 | 39 | SortHelper(a, 0, a.size() - 1); 40 | } 41 | 42 | private: 43 | void Merge(vector& a, int lo, int mid, int hi) 44 | { 45 | cout << "Before: "; 46 | Print(a, lo, hi); 47 | 48 | int i = lo, j = mid + 1; 49 | 50 | for (int k = lo; k <= hi; k++) 51 | aux[k] = a[k]; 52 | 53 | for (int k = lo; k <= hi; k++) 54 | { 55 | //if (i > mid) TODO; 56 | //else if (j > hi) TODO; 57 | //else if (aux[j] < aux[i]) TODO; 58 | //else a[k] = TODO; 59 | } 60 | 61 | cout << "After : "; 62 | Print(a, lo, hi); 63 | 64 | //count += hi - lo + 1; 65 | //cout << "Count : " << hi - lo + 1 << ", " << count << endl; // 누적 카운트 (디버깅용) 66 | } 67 | 68 | void SortHelper(vector& a, int lo, int hi) 69 | { 70 | if (hi <= lo) return; 71 | 72 | int mid = lo + (hi - lo) / 2; 73 | 74 | //TODO: 75 | //TODO: 76 | 77 | Merge(a, lo, mid, hi); 78 | } 79 | 80 | vector aux; // 추가 메모리 필요 81 | int count = 0; // 연산 횟수 세보기용 82 | }; 83 | 84 | int main() 85 | { 86 | vector my_vector(16); 87 | std::iota(my_vector.begin(), my_vector.end(), 0); 88 | std::reverse(my_vector.begin(), my_vector.end()); 89 | 90 | cout << " "; 91 | Print(my_vector, 0, my_vector.size() - 1); 92 | 93 | TopDownMerge merge; 94 | merge.Sort(my_vector); 95 | 96 | cout << " "; 97 | Print(my_vector, 0, my_vector.size() - 1); 98 | } 99 | -------------------------------------------------------------------------------- /Ex0301_TopdownMergesort/Ex0301_TopdownMergesort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0302_BottomupMergesort/Ex0302_BottomupMergesort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // std::iota 5 | 6 | using namespace std; 7 | 8 | void Print(vector& arr, int lo, int hi) 9 | { 10 | // setfill(), setw()는 줄맞춤에 사용 11 | 12 | for (int i = 0; i < lo; i++) 13 | cout << " "; 14 | for (int i = lo; i <= hi; i++) 15 | cout << setfill(' ') << setw(3) << arr[i]; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | // Sedgewick p. 278 31 | class BottomupMerge 32 | { 33 | public: 34 | void Sort(vector& a) 35 | { 36 | aux.resize(a.size()); 37 | 38 | int N = a.size(); 39 | // TODO: 재귀호출 사용하지 않습니다. 40 | } 41 | 42 | private: 43 | void Merge(vector& a, int lo, int mid, int hi) 44 | { 45 | // TODO: Top-down과 동일 46 | } 47 | 48 | vector aux; // 추가 메모리 49 | }; 50 | 51 | int main() 52 | { 53 | vector my_vector(16); 54 | std::iota(my_vector.begin(), my_vector.end(), 0); 55 | std::reverse(my_vector.begin(), my_vector.end()); 56 | 57 | cout << " "; 58 | Print(my_vector, 0, my_vector.size() - 1); 59 | 60 | BottomupMerge merge; 61 | merge.Sort(my_vector); 62 | 63 | cout << " "; 64 | Print(my_vector, 0, my_vector.size() - 1); 65 | } 66 | -------------------------------------------------------------------------------- /Ex0302_BottomupMergesort/Ex0302_BottomupMergesort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0401_CountOccurrences/Ex0401_CountOccurrences.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | void Print(vector& arr) 10 | { 11 | for (int i = 0; i < arr.size(); i++) 12 | cout << arr[i] << " "; 13 | cout << endl; 14 | } 15 | 16 | int Count1(const vector& arr, int x) 17 | { 18 | //TODO: O(n) 19 | return 0; 20 | } 21 | 22 | int Count2(const vector& arr, int x) 23 | { 24 | //TODO: O(log(n) + count) 25 | return 0; 26 | } 27 | 28 | int Count3(const vector& arr, int x) 29 | { 30 | //TODO: O(log(n)) 31 | return 0; 32 | } 33 | 34 | int main() 35 | { 36 | random_device rd; 37 | mt19937 gen(rd()); 38 | 39 | const int n = 20; 40 | vector my_vector(n); 41 | 42 | int x = 6; // target to find 43 | 44 | for (int r = 0; r < 100; r++) 45 | { 46 | uniform_int_distribution value_distribution(1, 10); 47 | generate(my_vector.begin(), my_vector.end(), [&]() { return value_distribution(gen); }); 48 | sort(my_vector.begin(), my_vector.end()); 49 | 50 | Print(my_vector); 51 | 52 | const int expected_count = std::count(my_vector.begin(), my_vector.end(), x); 53 | 54 | cout << "Expected count = " << expected_count << endl; 55 | 56 | // 1. O(n) brute force 57 | if (Count1(my_vector, x) != expected_count) 58 | { 59 | cout << "Wrong count1: " << Count1(my_vector, x) << endl; 60 | exit(-1); 61 | } 62 | 63 | // 2. O(log(n) + count) 64 | if (Count2(my_vector, x) != expected_count) 65 | { 66 | cout << "Wrong count2: " << Count2(my_vector, x) << endl; 67 | exit(-1); 68 | } 69 | 70 | // 3. O(log(n)) 71 | if (Count3(my_vector, x) != expected_count) 72 | { 73 | cout << "Wrong count3: " << Count3(my_vector, x) << endl; 74 | exit(-1); 75 | } 76 | } 77 | 78 | cout << "Good!" << endl; 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Ex0401_CountOccurrences/Ex0401_CountOccurrences.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0402_PartialSelectionSort/Ex0402_PartialSelectionSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | void Print(vector& arr) 10 | { 11 | for (int i = 0; i < arr.size(); i++) 12 | cout << arr[i] << " "; 13 | cout << endl; 14 | } 15 | 16 | // 가장 작은 값이 arr[lo]에 오도록 17 | void SelectionSortPass(vector& arr, int lo, int hi) 18 | { 19 | // TODO: 20 | } 21 | 22 | void PartialSelectionSort(vector& arr, int k) 23 | { 24 | Print(arr); 25 | 26 | for (int i = 0; i < k; i++) 27 | { 28 | // SelectionSortPass( TODO: ); 29 | 30 | Print(arr); 31 | } 32 | } 33 | 34 | int main() 35 | { 36 | vector my_vector = { 7, 10, 4, 3, 20, 15 }; 37 | 38 | int k = 3; 39 | 40 | PartialSelectionSort(my_vector, k); 41 | 42 | cout << my_vector[k - 1] << endl; 43 | } 44 | -------------------------------------------------------------------------------- /Ex0402_PartialSelectionSort/Ex0402_PartialSelectionSort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0403_MinAndMax/Ex0403_MinAndMax.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | vector arr = { 8, 2, 3, 5, 9, 1, 9, 4, 3, 7, 6, 7 }; 8 | 9 | // TODO: 10 | 11 | cout << "Min value = " << arr[0] << ", Max value = " << arr[1] << endl; // Min value = 1, Max value = 9 12 | } 13 | -------------------------------------------------------------------------------- /Ex0403_MinAndMax/Ex0403_MinAndMax.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0404_PartitionByPivot/Ex0404_PartitionByPivot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void Print(vector& arr) 6 | { 7 | for (int i = 0; i < arr.size(); i++) 8 | cout << arr[i] << " "; 9 | cout << endl; 10 | } 11 | 12 | int main() 13 | { 14 | vector arr = { 5, 2, 7, 3, 8, 5, 6, 4 }; 15 | //vector arr = { 2, 8, 7, 1, 3, 5, 6, 4 }; 16 | //vector arr = { 9, 8, 7, 6, 4, 3, 2, 1, 5 }; 17 | //vector arr = { 5, 2, 7, 3, 4, 4, 6, 4 }; 18 | 19 | int lo = 0; // 첫 인덱스 20 | int hi = arr.size() - 1; // 마지막 인덱스 21 | int x = arr[hi]; // 분할 기준으로 사용하는 pivot 4 22 | 23 | int i = lo - 1; // pivot보다 것들중 가장 큰 인덱스 24 | 25 | Print(arr); 26 | 27 | // TODO: 28 | 29 | swap(arr[i + 1], arr[hi]); 30 | Print(arr); 31 | 32 | cout << i + 1 << endl; // 피벗 이하인 값들의 마지막 인덱스 33 | } 34 | -------------------------------------------------------------------------------- /Ex0404_PartitionByPivot/Ex0404_PartitionByPivot.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0405_ExpectedLinearSelection/Ex0405_ExpectedLinearSelection.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0406_WorstcaseLinearSelection/Ex0406_WorstcaseLinearSelection.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0501_RandomizedQuicksort/Ex0501_RandomizedQuicksort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void Print(vector& arr, int lo, int hi, string sep = "") 7 | { 8 | //cout << "Index: "; 9 | //for (int i = 0; i < arr.size(); i++) 10 | // cout << setfill(' ') << setw(3) << i; 11 | //cout << endl; 12 | 13 | cout << "Value: "; 14 | for (int i = 0; i < arr.size(); i++) { 15 | 16 | if (lo <= i && i <= hi) 17 | cout << setfill(' ') << setw(3) << arr[i] << sep; 18 | else 19 | cout << " "; 20 | } 21 | cout << endl; 22 | } 23 | 24 | int Partition(vector& arr, int lo, int hi) 25 | { 26 | cout << "Pivot = " << arr[hi] << endl; 27 | 28 | int x = arr[hi]; 29 | int i = lo - 1; 30 | for (int j = lo; j < hi; j++) 31 | if (arr[j] <= x) 32 | { 33 | i += 1; 34 | swap(arr[i], arr[j]); 35 | } 36 | 37 | swap(arr[i + 1], arr[hi]); 38 | 39 | Print(arr, lo, hi); 40 | 41 | return i + 1; // 피벗이 이동한 위치 반환 42 | } 43 | 44 | int RandomizedPartition(vector& arr, int lo, int hi) 45 | { 46 | int random = lo + rand() % (hi - lo + 1); 47 | swap(arr[random], arr[hi]); 48 | return Partition(arr, lo, hi); 49 | } 50 | 51 | void RandomizedQuicksort(vector& arr, int lo, int hi) 52 | { 53 | Print(arr, lo, hi); 54 | 55 | // TODO: 56 | } 57 | 58 | int main() 59 | { 60 | srand(2); 61 | 62 | vector arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; 63 | 64 | RandomizedQuicksort(arr, 0, arr.size() - 1); 65 | 66 | Print(arr, 0, arr.size() - 1); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Ex0501_RandomizedQuicksort/Ex0501_RandomizedQuicksort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0502_Quick3way/Ex0502_Quick3way.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void Print(vector& arr, int lo, int hi, string sep = "") 7 | { 8 | //cout << "Index: "; 9 | //for (int i = 0; i < arr.size(); i++) 10 | // cout << setfill(' ') << setw(3) << i; 11 | //cout << endl; 12 | 13 | cout << "Value: "; 14 | for (int i = 0; i < arr.size(); i++) { 15 | 16 | if (lo <= i && i <= hi) 17 | cout << setfill(' ') << setw(3) << arr[i] << sep; 18 | else 19 | cout << " "; 20 | } 21 | cout << endl; 22 | } 23 | 24 | // Quicksort with 3-way partitioning, Sedgewick p299 25 | // (Dijkstra's Dutch national flag problem) 26 | void Quick3way(vector& arr, int lo, int hi) 27 | { 28 | if (hi <= lo) return; 29 | 30 | int lt = lo, i = lo + 1, gt = hi; 31 | int v = arr[lo]; 32 | 33 | //while (i <= gt) 34 | //{ 35 | // // TODO: 36 | //} 37 | 38 | Print(arr, lo, hi); 39 | 40 | //Quick3way(arr, lo, lt - 1); 41 | //Quick3way(arr, gt + 1, hi); 42 | } 43 | 44 | int main() 45 | { 46 | srand(0); 47 | 48 | vector arr = { 3, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 2, 3, 4, 5, 1, 3, 5 }; 49 | 50 | Print(arr, 0, arr.size() - 1); 51 | 52 | Quick3way(arr, 0, arr.size() - 1); 53 | 54 | Print(arr, 0, arr.size() - 1); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Ex0502_Quick3way/Ex0502_Quick3way.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0601_CountingSort/Ex0601_CountingSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto a : arr) 14 | if (a == -1) 15 | cout << "X "; 16 | else 17 | cout << a << " "; 18 | cout << endl; 19 | } 20 | 21 | // 입력은 0 이상 k 이하의 정수, CSLR 8.2 22 | // 결과를 반환하는 구조 (In-place가 아님) 23 | vector CountingSort(const vector& arr, int k) 24 | { 25 | vector count(k + 1, 0); // 0이상 k이하니까 k + 1개를 0으로 초기화 26 | 27 | // TODO: 28 | 29 | cout << "Count: "; 30 | Print(count); 31 | 32 | vector output(arr.size(), -1); // -1로 초기화하는 것은 디버깅용 33 | 34 | // 역순으로 복사 35 | for (int i = output.size() - 1; i >= 0; i--) 36 | { 37 | // TODO: 38 | 39 | cout << "Count: "; 40 | Print(count); 41 | 42 | cout << "Output: "; 43 | Print(output); 44 | } 45 | 46 | return output; 47 | } 48 | 49 | int main() 50 | { 51 | vector arr = { 2, 5, 3, 0, 2, 3, 0, 3 }; 52 | 53 | Print(arr); 54 | 55 | int k = *std::max_element(arr.begin(), arr.end()); 56 | // 아래 CountingSort()에서 사용할 가장 작은 인덱스(arr에서 가장 작은 값)은 0 57 | // 가장 큰 인덱스(arr에서 가장 큰 값)이 k 58 | 59 | vector result = CountingSort(arr, k); 60 | 61 | Print(result); 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Ex0601_CountingSort/Ex0601_CountingSort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0602_RadixSort/Ex0602_RadixSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto& a : arr) 14 | cout << a << " "; 15 | cout << endl; 16 | } 17 | 18 | // 편의상 결과가 arr에 저장되도록 바꿨습니다. 19 | void CountingSort(vector& arr, int k, int exp) 20 | { 21 | vector temp = arr; // 복사 22 | 23 | vector count(k + 1, 0); 24 | // TODO: 25 | 26 | for (int i = arr.size() - 1; i >= 0; i--) 27 | { 28 | // TODO: 29 | } 30 | } 31 | 32 | void RadixSort(vector& arr) 33 | { 34 | int k = 9; // 0 이상 9 이하 35 | int m = *max_element(arr.begin(), arr.end()); 36 | 37 | //for (TODO) 38 | //{ 39 | // cout << "exp = " << exp << endl; 40 | // TODO: 41 | // Print(arr); 42 | //} 43 | } 44 | 45 | int main() 46 | { 47 | vector arr = { 170, 45, 75, 90, 802, 24, 2, 66 }; 48 | //vector arr = { 2, 5, 3, 0, 2, 3, 0, 3 }; 49 | 50 | Print(arr); 51 | 52 | RadixSort(arr); 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /Ex0602_RadixSort/Ex0602_RadixSort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0603_SortingWords/Ex0603_SortingWords.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | template 13 | void Print(vector& arr) 14 | { 15 | for (auto& a : arr) 16 | cout << a << " "; 17 | cout << endl; 18 | } 19 | 20 | void CountingSort(vector& arr, int k, int d) 21 | { 22 | // vector temp = arr; // 복사 23 | // std::fill(arr.begin(), arr.end(), " "); // 디버깅 편의 24 | 25 | // TODO: 26 | } 27 | 28 | void RadixSort(vector& arr) 29 | { 30 | // TODO: 31 | } 32 | 33 | int main() 34 | { 35 | // CLRS 8.3-1 36 | vector arr = { "COW", "DOG", "SEA", "RUG", 37 | "ROW", "MOB", "BOX", "TAB", "BAR", "EAR", "TAR", 38 | "DIG", "BIG", "TEA", "NOW", "FOX" }; 39 | 40 | Print(arr); 41 | 42 | RadixSort(arr); 43 | 44 | Print(arr); 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /Ex0603_SortingWords/Ex0603_SortingWords.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0604_BucketSort/Ex0604_BucketSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto& a : arr) 14 | cout << a << " "; 15 | cout << endl; 16 | } 17 | 18 | void PrintBuckets(vector>& buckets) 19 | { 20 | for (int i = 0; i < buckets.size(); i++) 21 | { 22 | cout << i << ": "; 23 | for (int j = 0; j < buckets[i].size(); j++) 24 | cout << buckets[i][j] << " "; 25 | cout << endl; 26 | } 27 | } 28 | 29 | // 다른 정렬을 사용해도 됩니다. 30 | void InsertionSort(vector& bucket) 31 | { 32 | for (int i = 1; i < bucket.size(); ++i) { 33 | float key = bucket[i]; 34 | int j = i - 1; 35 | while (j >= 0 && bucket[j] > key) { 36 | bucket[j + 1] = bucket[j]; 37 | j--; 38 | } 39 | bucket[j + 1] = key; 40 | } 41 | } 42 | 43 | void BucketSort(vector& arr, int num_buckets) 44 | { 45 | vector> buckets(num_buckets); 46 | 47 | // TODO: 48 | 49 | cout << "Before sorting" << endl; 50 | PrintBuckets(buckets); 51 | 52 | // TODO: 53 | 54 | cout << "After sorting" << endl; 55 | PrintBuckets(buckets); 56 | 57 | // TODO: 58 | } 59 | 60 | int main() 61 | { 62 | vector arr = { 0.78f, 0.17f, 0.39f, 0.26f, 0.72f, 0.94f, 0.21f, 0.12f, 0.23f, 0.67f }; 63 | 64 | Print(arr); 65 | 66 | BucketSort(arr, 10); 67 | 68 | Print(arr); 69 | 70 | return 0; 71 | } -------------------------------------------------------------------------------- /Ex0604_BucketSort/Ex0604_BucketSort.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0701_RedBlackTree/Ex0701_RedBlackTree.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0801_SeparateChaining/Ex0801_SeparateChaining.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0802_UnorderedMap/Ex0802_UnorderedMap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include // map 11 | #include // unordered_map 12 | using namespace std; 13 | 14 | template 15 | void Print(const unordered_map& map) 16 | { 17 | for (int i = 0; i < map.bucket_count(); i++) // 버킷에 대해 반복 18 | { 19 | auto b = map.bucket(i); 20 | cout << i << ": "; 21 | for (auto i = map.begin(b); i != map.end(b); i++) // 버킷에 저장된 것들 출력 22 | cout << "(" << i->first << ", " << i->second << ")->"; 23 | cout << endl; 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | // 기본적인 사용 방법 30 | { 31 | //unordered_map map; 32 | map map; 33 | 34 | // 새로운 키-값 추가 35 | map.insert({ "Orange", 1 }); 36 | map.insert({ "Apple", 10 }); 37 | map.insert({ "Strawberry", 7 }); 38 | 39 | // 새로운 키-값 추가(배열처럼 인덱싱 연산자 사용) 40 | map["Kiwi"] = 5; // map.insert({"Kiwi", 5}); 41 | 42 | // 값 변경 43 | map.find("Kiwi")->second += 1; // 이터레이터 사용 44 | map["Kiwi"] += 1; // 인덱싱(더 편리) 45 | 46 | cout << map.count("Apple") << endl; // 1 아니면 0 반환 (중복허용X) 47 | 48 | // map은 내부적으로 정렬된 순서 유지 (unordered_map과 출력 순서가 다를 수 있음) 49 | for (auto i : map) 50 | cout << i.first << " " << i.second << endl; 51 | } 52 | 53 | // 난수 생성기 54 | random_device rd; 55 | mt19937 g(rd()); 56 | uniform_int_distribution dist(1, 365); 57 | 58 | // 모인 인원 수 59 | int num_people = 23; 60 | 61 | std::unordered_map map(num_people); // 버킷 수를 스스로 조절 62 | 63 | int num_try = 1000; 64 | int all_samebirthday_count = 0; 65 | 66 | for (int t = 0; t < num_try; t++) 67 | { 68 | int samebirthday_count = 0; 69 | 70 | for (int i = 0; i < num_people; i++) 71 | { 72 | int birthday = dist(g); 73 | 74 | // TODO: 75 | } 76 | 77 | if (samebirthday_count > 0) 78 | all_samebirthday_count += 1; 79 | 80 | //Print(map); // 디버깅용 81 | //exit(0); 82 | 83 | map.clear(); 84 | } 85 | 86 | std::cout << (all_samebirthday_count * 100.0 / num_try) << " % " << endl; 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /Ex0802_UnorderedMap/Ex0802_UnorderedMap.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0803_RomanNumeral/Ex0803_RomanNumeral.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // LeetCode: Roman to Integer 7 | // https://leetcode.com/problems/roman-to-integer/description/ 8 | 9 | int RomanToInt(string s) 10 | { 11 | unordered_map m; 12 | 13 | m['I'] = 1; 14 | m['V'] = 5; 15 | m['X'] = 10; 16 | m['L'] = 50; 17 | m['C'] = 100; 18 | m['D'] = 500; 19 | m['M'] = 1000; 20 | 21 | int ans = 0; 22 | 23 | for (int i = 0; i < s.length(); i++) 24 | { 25 | // TODO: 26 | } 27 | 28 | cout << s << " = " << ans << endl; 29 | 30 | return ans; 31 | } 32 | 33 | int main() 34 | { 35 | RomanToInt("II"); 36 | 37 | RomanToInt("III"); 38 | 39 | RomanToInt("XII"); 40 | 41 | RomanToInt("XXVII"); 42 | 43 | RomanToInt("IV"); 44 | 45 | RomanToInt("IX"); 46 | 47 | RomanToInt("XL"); 48 | 49 | RomanToInt("XC"); 50 | 51 | RomanToInt("CD"); 52 | 53 | RomanToInt("CM"); 54 | 55 | RomanToInt("LVIII"); 56 | 57 | RomanToInt("MCMXCIV"); 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /Ex0803_RomanNumeral/Ex0803_RomanNumeral.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0901_DepthFirstPaths/Ex0901_DepthFirstPaths.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0902_QueueBasedTopologicalSorting/Ex0902_QueueBasedTopologicalSorting.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0903_TopologicalSorting/Ex0903_TopologicalSorting.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0904_DegreesOfSeparation/Ex0904_DegreesOfSeparation.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Ex0905_SymbolGraph/Ex0905_SymbolGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Vertex 8 | { 9 | Vertex(string k, int i) 10 | { 11 | key = k; 12 | index = i; 13 | } 14 | 15 | string key = ""; 16 | int index = -1; // 이 Vertex의 포인터가 저장된 vertices 배열의 인덱스 17 | bool visited = false; 18 | 19 | vector out_neighbors; 20 | }; 21 | 22 | class SymbolGraph 23 | { 24 | public: 25 | SymbolGraph(vector keys) 26 | { 27 | table.clear(); 28 | vertices.clear(); 29 | vertices.reserve(keys.size()); 30 | 31 | // TODO: vertices와 table 초기화 32 | 33 | // 확인용 34 | for (auto v : vertices) 35 | cout << v->key << " " << v->index << endl; 36 | for (auto i : table) 37 | cout << i.first << " " << i.second << endl; 38 | } 39 | 40 | ~SymbolGraph() 41 | { 42 | for (auto* v : vertices) 43 | delete v; 44 | } 45 | 46 | void AddDiEdge(string kv, string kw) 47 | { 48 | // TODO: table 이용 49 | } 50 | 51 | void AddDiEdge(int v, int w) // 단방향 간선 52 | { 53 | vertices[v]->out_neighbors.push_back(vertices[w]); 54 | } 55 | 56 | void DFS(string k) 57 | { 58 | // TODO: table 이용 59 | } 60 | 61 | void DFS(int source) 62 | { 63 | for (auto* v : this->vertices) 64 | v->visited = false; 65 | DFS(vertices[source]); 66 | cout << endl; 67 | } 68 | 69 | void DFS(Vertex* source) 70 | { 71 | source->visited = true; 72 | 73 | // Preorder 74 | // cout << source->key << " "; 75 | 76 | for (auto* w : source->out_neighbors) 77 | if (!w->visited) 78 | DFS(w); 79 | 80 | // Postorder 81 | cout << source->key << " "; 82 | } 83 | 84 | private: 85 | vector vertices; 86 | 87 | unordered_map table; // key -> index 88 | }; 89 | 90 | int main() 91 | { 92 | SymbolGraph g({ "A", "B", "C", "D", "E", "F", "G", "H", "I" }); 93 | 94 | g.AddDiEdge("F", "B"); 95 | g.AddDiEdge("F", "G"); 96 | g.AddDiEdge("B", "A"); 97 | g.AddDiEdge("B", "D"); 98 | g.AddDiEdge("D", "C"); 99 | g.AddDiEdge("D", "E"); 100 | g.AddDiEdge("G", "I"); 101 | g.AddDiEdge("I", "H"); 102 | 103 | g.DFS("F"); 104 | 105 | return 0; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /Ex0905_SymbolGraph/Ex0905_SymbolGraph.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0906_DirectedCycleDetection/Ex0906_DirectedCycleDetection.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex0908_TracingDFS/Ex0908_TracingDFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // Vertex에는 용도에 따라서 int 외에 string 같은 다른 정보들도 저장할 수 있습니다. 8 | // 삽입/삭제가 많으면 list, 접근(읽기/쓰기)이 많으면 vector 권장 9 | 10 | struct Vertex 11 | { 12 | Vertex(int v) { value = v; } 13 | 14 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 15 | bool visited = false; 16 | 17 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 18 | }; 19 | 20 | class Graph 21 | { 22 | public: 23 | Graph(int num_vertices) 24 | { 25 | vertices.resize(num_vertices); 26 | for (int i = 0; i < num_vertices; i++) 27 | vertices[i] = new Vertex(i); 28 | } 29 | 30 | ~Graph() 31 | { 32 | for (auto* v : vertices) 33 | delete v; 34 | } 35 | 36 | void AddDiEdge(int v, int w) // 단방향 간선 37 | { 38 | vertices[v]->out_neighbors.push_back(vertices[w]); 39 | } 40 | 41 | void AddBiEdge(int v, int w) // 양방향 간선 42 | { 43 | vertices[v]->out_neighbors.push_back(vertices[w]); 44 | vertices[w]->out_neighbors.push_back(vertices[v]); 45 | } 46 | 47 | void DFS(int source) 48 | { 49 | for (auto* v : this->vertices) 50 | v->visited = false; 51 | 52 | current_time = 0; 53 | DFS(vertices[source], 0); 54 | } 55 | 56 | void DFS(Vertex* source, int level) 57 | { 58 | current_time += 1; 59 | cout << setw(2) << current_time << ": "; 60 | cout << string(2 * level, ' '); // 출력탭 61 | cout << "DFS(" << source->value << ")" << endl; 62 | 63 | source->visited = true; 64 | for (auto* w : source->out_neighbors) 65 | if (!w->visited) 66 | DFS(w, level + 1); 67 | 68 | current_time += 1; 69 | cout << setw(2) << current_time << ": "; 70 | cout << string(2 * level, ' '); // 출력탭 71 | cout << source->value << " done" << endl; 72 | } 73 | 74 | private: 75 | vector vertices; 76 | int current_time = 0; // 실행 순서 추적용 77 | 78 | void PrintPath(vector path) 79 | { 80 | for (auto& v : path) { 81 | cout << v->value; 82 | if (&v != &path.back()) 83 | cout << " -> "; 84 | } 85 | cout << endl; 86 | } 87 | }; 88 | 89 | int main() 90 | { 91 | // 한 경로 안에서 한 번 방문한 정점은 다시 방문하지 않는다. 92 | 93 | // 간단한 경우 94 | { 95 | // 0: 애피타이저 96 | // 1: 메인요리 97 | // 2: 디저트 98 | 99 | Graph g(3); 100 | g.AddDiEdge(0, 1); // 애피타이저 -> 메인요리 101 | g.AddDiEdge(1, 2); // 메인요리 -> 디저트 102 | g.AddDiEdge(0, 2); // 애피타이저 -> 디저트 103 | 104 | g.DFS(0); 105 | } 106 | 107 | // Sedgewick Algorithm 4.1 p.536 (조금 달라요) 108 | { 109 | Graph g(6); 110 | 111 | g.AddDiEdge(0, 2); 112 | g.AddDiEdge(2, 1); 113 | g.AddDiEdge(2, 3); 114 | g.AddDiEdge(3, 4); 115 | g.AddDiEdge(1, 5); 116 | g.AddDiEdge(2, 4); 117 | g.AddBiEdge(3, 5); // 주의: 양방향 간선 118 | 119 | g.DFS(2); 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /Ex0908_TracingDFS/Ex0908_TracingDFS.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1001_ConnectedComponents/Ex1001_ConnectedComponents.cpp: -------------------------------------------------------------------------------- 1 |  2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Vertex 9 | { 10 | Vertex(int v) { value = v; } 11 | 12 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 13 | bool visited = false; 14 | 15 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 16 | }; 17 | 18 | class Graph 19 | { 20 | public: 21 | Graph(int num_vertices) 22 | { 23 | vertices.resize(num_vertices); 24 | for (int i = 0; i < num_vertices; i++) 25 | vertices[i] = new Vertex(i); 26 | } 27 | 28 | ~Graph() 29 | { 30 | for (auto* v : vertices) 31 | delete v; 32 | } 33 | 34 | //void AddDiEdge(int v, int w) // 단방향 간선 35 | //{ 36 | // vertices[v]->out_neighbors.push_back(vertices[w]); 37 | //} 38 | 39 | void AddBiEdge(int v, int w) // 양방향 간선 40 | { 41 | vertices[v]->out_neighbors.push_back(vertices[w]); 42 | vertices[w]->out_neighbors.push_back(vertices[v]); 43 | } 44 | 45 | void DFS(Vertex* v) 46 | { 47 | // TODO: 48 | } 49 | 50 | void ConnectedComponents() 51 | { 52 | count = 0; 53 | id.resize(vertices.size(), -1); 54 | 55 | // TODO: 56 | 57 | // 결과 정리 후 출력 58 | //vector> components(count); 59 | //for (int s = 0; s < vertices.size(); s++) 60 | // components[id[s]].push_back(s); 61 | //cout << count << " components" << endl; 62 | //for (int i = 0; i < components.size(); i++) 63 | //{ 64 | // cout << "Component " << i + 1 << ": "; 65 | // for (auto v : components[i]) 66 | // cout << v << " "; 67 | // cout << endl; 68 | //} 69 | } 70 | 71 | private: 72 | vector vertices; 73 | vector id; 74 | int count = 0; 75 | }; 76 | 77 | 78 | int main() 79 | { 80 | // Sedgewick p544 81 | // 무방향(양방향) 그래프 82 | vector> edges = { {0, 5}, {4, 3}, {0, 1}, 83 | {9, 12}, {6, 4}, {5, 4}, {0, 2}, {11, 12}, {9, 10}, 84 | {0, 6}, {7, 8}, {9, 11}, {5, 3} }; 85 | 86 | Graph g(13); 87 | 88 | for (vector& p : edges) 89 | g.AddBiEdge(p[0], p[1]); 90 | 91 | g.ConnectedComponents(); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /Ex1001_ConnectedComponents/Ex1001_ConnectedComponents.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1002_StrongComponents(BruteForce)/Ex1002_StrongComponents(BruteForce).cpp: -------------------------------------------------------------------------------- 1 |  2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Vertex 9 | { 10 | Vertex(int v) { value = v; } 11 | 12 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 13 | bool visited = false; 14 | 15 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 16 | vector in_neighbors; // 들어오는 방향의 이웃 vertex들에 대한 포인터 17 | }; 18 | 19 | class Graph 20 | { 21 | public: 22 | Graph(int num_vertices) 23 | { 24 | vertices.resize(num_vertices); 25 | for (int i = 0; i < num_vertices; i++) 26 | vertices[i] = new Vertex(i); 27 | } 28 | 29 | ~Graph() 30 | { 31 | for (auto* v : vertices) 32 | delete v; 33 | } 34 | 35 | void AddDiEdge(int v, int w) // 단방향 간선 36 | { 37 | vertices[v]->out_neighbors.push_back(vertices[w]); 38 | vertices[w]->in_neighbors.push_back(vertices[v]); 39 | } 40 | 41 | bool HasPath(int start, int target) 42 | { 43 | for (auto* v : vertices) 44 | v->visited = false; 45 | return HasPathHelper(vertices[start], vertices[target]); 46 | } 47 | 48 | void BruteForceStrongComponents() 49 | { 50 | int count = 0; 51 | vector id(vertices.size(), -1); 52 | 53 | // TODO: HasPath()를 이용해서 서로 강하게 연결된 요소들을 찾습니다. 54 | 55 | // 결과 정리 후 출력 56 | //vector> components(count); 57 | //for (int s = 0; s < vertices.size(); s++) 58 | // components[id[s]].push_back(s); 59 | //cout << count << " strong components" << endl; 60 | //for (int i = 0; i < components.size(); i++) 61 | //{ 62 | // cout << "Strong component " << i + 1 << ": "; 63 | // for (auto v : components[i]) 64 | // cout << v << " "; 65 | // cout << endl; 66 | //} 67 | } 68 | 69 | private: 70 | vector vertices; 71 | 72 | bool HasPathHelper(Vertex* v, Vertex* t) 73 | { 74 | // TODO: DFS 방식으로 v와 t가 만날 수 있는 지를 확인합니다. 75 | 76 | return false; 77 | } 78 | }; 79 | 80 | int main() 81 | { 82 | // Sedgewick p569 83 | // 방향(directed) 그래프 84 | vector> edges = { 85 | {4, 2}, {2, 3}, {3, 2}, {6, 0}, {0, 1}, {2, 0}, {11, 12}, {12, 9}, {9, 10}, 86 | {9, 11}, {7, 9}, {10, 12}, {11, 4}, {4, 3}, {3, 5}, {6, 8}, {8, 6}, {5, 4}, 87 | {0, 5}, {6, 4}, {6, 9}, {7, 6} }; 88 | 89 | Graph g(13); 90 | 91 | for (vector& p : edges) 92 | g.AddDiEdge(p[0], p[1]); 93 | 94 | g.BruteForceStrongComponents(); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /Ex1002_StrongComponents(BruteForce)/Ex1002_StrongComponents(BruteForce).vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1003_KosarajuStrongComponents/Ex1003_KosarajuStrongComponents.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | struct Vertex 10 | { 11 | Vertex(int v) { value = v; } 12 | 13 | int value = -1; 14 | 15 | bool visited = false; 16 | 17 | vector out_neighbors; 18 | vector in_neighbors; // Transpose 쉽게 하려고 저장 19 | }; 20 | 21 | class Graph 22 | { 23 | public: 24 | Graph(int num_vertices) 25 | { 26 | vertices.resize(num_vertices); 27 | for (int i = 0; i < num_vertices; i++) 28 | vertices[i] = new Vertex(i); 29 | } 30 | 31 | ~Graph() 32 | { 33 | for (auto* v : vertices) 34 | delete v; 35 | } 36 | 37 | void AddDiEdge(int v, int w) 38 | { 39 | vertices[v]->out_neighbors.push_back(vertices[w]); 40 | vertices[w]->in_neighbors.push_back(vertices[v]); 41 | } 42 | 43 | deque ReversePostorderDFS() 44 | { 45 | revpost = deque(); 46 | 47 | for (auto* v : this->vertices) 48 | v->visited = false; 49 | 50 | for (auto* v : this->vertices) 51 | if (!v->visited) 52 | ReversePostorderDFS(v); 53 | 54 | return revpost; 55 | } 56 | 57 | void Transpose() 58 | { 59 | // TODO: 60 | 61 | // 인접 행렬 표현에서 행렬을 transpose 시키는 것과 동일 62 | } 63 | 64 | void KosarajuStrongComponents() 65 | { 66 | Transpose(); // 생략하면 출력 순서는 달라지만 결과는 동일 67 | 68 | // deque revpost = TODO; // 아래 for문 편의상 stack대신 deque 사용 69 | 70 | cout << "Reverse Post-order: "; 71 | //for (auto* v : revpost) 72 | // cout << v->value << " "; 73 | //cout << endl; 74 | 75 | Transpose(); 76 | 77 | // TODO: 78 | 79 | // 결과 정리 후 출력 80 | //vector> components(count); 81 | //for (int s = 0; s < vertices.size(); s++) 82 | // components[id[s]].push_back(s); 83 | //cout << count << " strong components" << endl; 84 | //for (int i = 0; i < components.size(); i++) 85 | //{ 86 | // cout << "Kosaraju strong component " << i + 1 << ": "; 87 | // for (auto v : components[i]) 88 | // cout << v << " "; 89 | // cout << endl; 90 | //} 91 | } 92 | 93 | private: 94 | vector vertices; 95 | deque revpost; 96 | vector id; 97 | int count = 0; 98 | 99 | // void TopologicalSortHelper(Vertex* v) 100 | void ReversePostorderDFS(Vertex* v) 101 | { 102 | // TODO: 103 | } 104 | 105 | void DFS(Vertex* v) 106 | { 107 | // TODO: 108 | } 109 | 110 | // ReversePostorderDFS()도 깊이우선탐색이라서 DSF()와 합칠 수 있으나 111 | // 여기서는 디버깅 편의를 위해 분리하였습니다. 112 | }; 113 | 114 | int main() 115 | { 116 | // Sedgewick p569 117 | // 방향(directed) 그래프 118 | vector> edges = { 119 | {4, 2}, {2, 3}, {3, 2}, {6, 0}, {0, 1}, {2, 0}, {11, 12}, {12, 9}, {9, 10}, 120 | {9, 11}, {7, 9}, {10, 12}, {11, 4}, {4, 3}, {3, 5}, {6, 8}, {8, 6}, {5, 4}, 121 | {0, 5}, {6, 4}, {6, 9}, {7, 6} }; 122 | Graph g(13); 123 | 124 | for (vector& p : edges) 125 | g.AddDiEdge(p[0], p[1]); 126 | 127 | g.KosarajuStrongComponents(); 128 | 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /Ex1003_KosarajuStrongComponents/Ex1003_KosarajuStrongComponents.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1101_PriorityQueue/Ex1101_PriorityQueue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | // C++ 우선순위큐 std::priority_queue 사용법 8 | 9 | // 기본 설정은 큰 값의 우선순위가 높은 max queue 10 | { 11 | priority_queue max_queue; // double값들을 저장하는 우선순위큐 12 | 13 | for (double v : vector{ 3.5, 2.4, 8.3, 9.9, 1.2, 3.9 }) 14 | max_queue.push(v); // 추가 15 | 16 | // 큰 값부터 출력됩니다. 17 | while (!max_queue.empty()) 18 | { 19 | cout << max_queue.top() << " "; 20 | max_queue.pop(); 21 | } 22 | cout << endl; 23 | } 24 | 25 | // 작은 값의 우선순위가 높은 min queue 26 | { 27 | priority_queue, greater> min_queue; 28 | 29 | // 위에서 double은 저장될 자료형 30 | // vector은 pq에서 내부적으로 사용할 컨테이너 31 | // greater는 우선순위를 결정할 때 사용할 비교 32 | // greater대신에 less을 사용하면 max queue 33 | // https://en.cppreference.com/w/cpp/container/priority_queue 34 | // 아래 예제코드에 min priority queue 부분 참고 35 | // std::greater makes the max priority queue act as a min priority queue 36 | 37 | for (auto v : vector{ 3.5, 2.4, 8.3, 9.9, 1.2, 3.9 }) 38 | min_queue.push(v); 39 | 40 | // 작은 값부터 출력 41 | while (!min_queue.empty()) 42 | { 43 | cout << min_queue.top() << " "; 44 | min_queue.pop(); 45 | } 46 | cout << endl; 47 | } 48 | 49 | // 우선순위큐에 std::pair 저장 50 | // double형 변수 하나와 int형 변수 하나를 묶어 놓은 쌍(pair) 51 | // 중복 저장 가능: {3.5, 1}이 여러 번 저장됩니다. 52 | { 53 | priority_queue, vector>, greater>> pq; 54 | 55 | for (pair v : vector>{ {3.5, 3}, {8.3, 1}, {3.5, 1}, {3.5, 2}, {2.4, 8}, {8.3, 5}, {3.5, 1}, {3.5, 1} }) 56 | pq.push(v); 57 | 58 | // pair에서 double값이 같으면 int값이 작은 쪽 먼저 출력 59 | while (!pq.empty()) 60 | { 61 | cout << "(" << pq.top().first << ", " << pq.top().second << ") "; 62 | // first: pair에서 첫 번째(여기서는 double형) 63 | // second: pair에서 두 번째(여기서는 int) 64 | 65 | pq.pop(); 66 | } 67 | cout << endl; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Ex1101_PriorityQueue/Ex1101_PriorityQueue.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1102_IndexMinPQ/Ex1102_IndexMinPQ.cpp: -------------------------------------------------------------------------------- 1 | #include "IndexMinPQ.h" 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | IndexMinPQ pq(10); 8 | 9 | for (pair p : vector>{ {3.5, 3}, {8.3, 1}, {1.5, 1}, {1.6, 3}, {0.5, 8}, {0.1, 5} }) 10 | { 11 | if (!pq.Contains(p.second)) pq.Insert(p.second, p.first); 12 | else pq.ChangeKey(p.second, p.first); 13 | 14 | pq.Print(); 15 | } 16 | 17 | while (!pq.Empty()) 18 | { 19 | cout << "(" << pq.MinKey() << ", " << pq.MinIndex() << ") "; 20 | 21 | pq.DelMin(); 22 | } 23 | cout << endl; 24 | } 25 | -------------------------------------------------------------------------------- /Ex1102_IndexMinPQ/Ex1102_IndexMinPQ.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /Ex1103_Dijkstra(IndexMinPQ)/Ex1103_Dijkstra(IndexMinPQ).vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1104_Dijkstra(LinearSearch)/Ex1104_Dijkstra(LinearSearch).vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1105_Dijkstra/Ex1105_Dijkstra.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1201_Fibonacci/Ex1201_Fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int RecurFibonacci(int n) 7 | { 8 | cout << "RecurFibonacci(" << setw(2) << n << ")" << endl; 9 | 10 | if (n == 0) return 0; 11 | if (n == 1) return 1; 12 | 13 | return RecurFibonacci(n - 2) + RecurFibonacci(n - 1); 14 | } 15 | 16 | // 메모에 vector 대신에 unordered_map을 사용하는 경우도 있습니다. 17 | int MemoizedTopDownFibonacciHelper(int n, std::vector& memo) 18 | { 19 | // TODO: 20 | 21 | for (auto& t : memo) cout << setw(4) << t; cout << endl; 22 | 23 | return memo[n]; 24 | } 25 | 26 | int MemoizedTopDownFibonacci(int n) 27 | { 28 | vector memo(n + 1, -1); // -1로 초기화 29 | memo[0] = 0; 30 | memo[1] = 1; 31 | 32 | return MemoizedTopDownFibonacciHelper(n, memo); 33 | } 34 | 35 | int BottomUpFibonacciTabulation(int n) 36 | { 37 | if (n == 0) return 0; 38 | if (n == 1) return 1; 39 | 40 | vector table(n + 1, -1); 41 | table[0] = 0; 42 | table[1] = 1; 43 | 44 | // for ( TODO ) 45 | { 46 | // TODO: 47 | 48 | for (auto& t : table) cout << setw(4) << t; cout << endl; 49 | } 50 | 51 | return table[n]; // The N-th Fibonacci number 52 | } 53 | 54 | // 재미로 배열 없이 구현해보기 55 | int BottomUpFibonacci(int n) 56 | { 57 | if (n == 0 || n == 1) 58 | return n; 59 | 60 | int a = 0; 61 | int b = 1; 62 | 63 | // TODO: 64 | 65 | return b; // The N-th Fibonacci number 66 | } 67 | 68 | int main() 69 | { 70 | int n = 7; // 숫자가 크면 단순 재귀 버전은 많이 느립니다. 71 | 72 | cout << RecurFibonacci(n) << endl; 73 | 74 | cout << MemoizedTopDownFibonacci(n) << endl; 75 | 76 | cout << BottomUpFibonacciTabulation(n) << endl; 77 | 78 | cout << BottomUpFibonacci(n) << endl; 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /Ex1201_Fibonacci/Ex1201_Fibonacci.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1202_RodCutting/Ex1202_RodCutting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // CLRS 4판 14.1 Rod Cutting 8 | 9 | int RecurCutRod(const vector& prices, int length) 10 | { 11 | if (length == 0) 12 | return 0; // return length* prices[0]; 13 | 14 | int max_price = numeric_limits::min(); 15 | 16 | for (int i = 1; i <= length; i++) 17 | { 18 | // TODO: 19 | } 20 | 21 | return max_price; 22 | } 23 | 24 | int MemoizedCutRodHelper(const vector& prices, int length, vector& memo) 25 | { 26 | if (memo[length] >= 0) 27 | return memo[length]; 28 | 29 | // TODO: 30 | 31 | for (auto& t : memo) cout << setw(3) << t; cout << endl; 32 | 33 | return memo[length]; 34 | } 35 | 36 | int MemoizedCutRod(const vector& prices, int length) 37 | { 38 | vector memo(length + 1, -1); 39 | memo[0] = 0; 40 | 41 | return MemoizedCutRodHelper(prices, length, memo); 42 | } 43 | 44 | int BottomUpCutRod(const vector& prices, int length) 45 | { 46 | vector table(length + 1, -1); // 가격은 음수가 될 수 없으니까 디버깅 편의를 위해 -1로 초기화 47 | table[0] = 0; // length* prices[0]; 48 | 49 | for (int j = 1; j <= length; j++) 50 | { 51 | int max_price = numeric_limits::min(); 52 | 53 | // TODO: 54 | 55 | for (auto& t : table) cout << setw(3) << t; cout << endl; 56 | } 57 | 58 | return table[length]; 59 | } 60 | 61 | // 어떻게 자르는지까지 출력하는 버전 (실행 예시 참고) 62 | int ExtendedBottomUpCutRod(const vector& prices, int length) 63 | { 64 | vector table(length + 1, -1); // 가격은 음수가 될 수 없으니까 디버깅 편의를 위해 -1로 초기화 65 | table[0] = 0; // length* prices[0]; 66 | 67 | // TODO: 68 | 69 | return table[length]; 70 | } 71 | 72 | int main() 73 | { 74 | // Length: 0 1 2 3 4 5 6 7 8 9 10 75 | vector price_table = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 }; 76 | //vector price_table = { 0, 3, 5, 8, 9, 10, 17, 17, 20, 24, 30 }; 77 | 78 | // 주의: price_table은 문제에서 주어진 조건입니다. 메모가 아닙니다. 79 | 80 | cout << "Naive recursion" << endl; 81 | for (int length = 0; length < price_table.size(); length++) 82 | { 83 | int revenue = RecurCutRod(price_table, length); 84 | cout << "Optimal revenue for length " << length << ": " << revenue << endl; 85 | } 86 | cout << endl; 87 | 88 | cout << "TopDown with Memoization" << endl; 89 | cout << "Optimal revenue for length " << 10 << ": " << MemoizedCutRod(price_table, 10) << endl; 90 | cout << endl; 91 | 92 | cout << "BottomUpTabulation" << endl; 93 | cout << "Optimal revenue for length " << 10 << ": " << BottomUpCutRod(price_table, 10) << endl; 94 | cout << endl; 95 | 96 | for (int length = 0; length < price_table.size(); length++) 97 | { 98 | cout << "Length: " << length << endl; 99 | int revenue = ExtendedBottomUpCutRod(price_table, length); 100 | cout << "Optimal revenue: " << revenue << endl; 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /Ex1202_RodCutting/Ex1202_RodCutting.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1203_BellmanFord/Ex1203_BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | void Print(vector& dist) 10 | { 11 | for (int i = 0; i < dist.size(); i++) 12 | cout << setw(6) << dist[i]; 13 | cout << endl; 14 | } 15 | 16 | void PrintPathHelper(vector& prev, int j) 17 | { 18 | // TODO: 19 | } 20 | 21 | void PrintPaths(vector& prev) 22 | { 23 | for (int j = 0; j < prev.size(); j++) 24 | { 25 | PrintPathHelper(prev, j); 26 | cout << endl; 27 | } 28 | } 29 | 30 | struct Edge 31 | { 32 | int v, w; 33 | double weight; 34 | }; 35 | 36 | int main() 37 | { 38 | constexpr double kInf = numeric_limits::infinity(); 39 | 40 | // CLRS p.621 (다익스트라 예제와 같음) 41 | //vector edges = { 42 | //{0, 1, 10.0}, 43 | //{0, 3, 5.0}, 44 | //{1, 2, 1.0}, 45 | //{1, 3, 2.0}, 46 | //{2, 4, 4.0}, 47 | //{3, 1, 3.0}, 48 | //{3, 2, 9.0}, 49 | //{3, 4, 2.0}, 50 | //{4, 0, 7.0}, 51 | //{4, 2, 6.0}, 52 | //}; 53 | //int V = 5; // number of vertices 54 | 55 | // 간선이 왼쪽에서 오른쪽 방향일 경우 56 | vector edges = { 57 | {0, 1, 1.0}, // A->B 1 58 | {1, 2, 5.0}, 59 | {1, 3, 4.0}, 60 | {2, 3, -3.0}, 61 | {3, 4, 1.0}, 62 | {4, 3, -100.0} // 음의 싸이클이 추가된 경우 63 | }; 64 | int V = 5; // number of vertices 65 | 66 | //std::reverse(edges.begin(), edges.end()); // 간선 순서 뒤집어서 해보기 67 | 68 | // 간선 순서는 CLRS p613 예시 순서 69 | //vector edges = { 70 | // {1, 2, 5.0}, 71 | // {1, 3, 8.0}, 72 | // {1, 4, -4.0}, 73 | // {2, 1, -2.0}, 74 | // {3, 2, -3.0}, 75 | // {3, 4, 9.0}, 76 | // {4, 2, 7.0}, 77 | // {4, 0, 2.0}, 78 | // {0, 1, 6.0}, 79 | // {0, 3, 7.0}, 80 | //}; 81 | //int V = 5; // number of vertices 82 | 83 | int E = int(edges.size()); // number of edges 84 | 85 | vector dist(V, kInf); 86 | vector prev(V, -1); 87 | 88 | int s = 0; // 시작 정점의 인덱스 89 | dist[s] = 0.0; 90 | 91 | Print(dist); 92 | 93 | for (int v = 1; v < V; v++) 94 | { 95 | for (auto e : edges) 96 | { 97 | // TODO: 98 | } 99 | 100 | Print(dist); 101 | } 102 | 103 | // 참고: infinity() 비교 연산 104 | // cout << bool(numeric_limits::infinity() + 100 > numeric_limits::infinity()) << endl; // 0 false 105 | // cout << bool(numeric_limits::infinity() + 100 < numeric_limits::infinity()) << endl; // 0 false 106 | // cout << bool(numeric_limits::infinity() + 100 == numeric_limits::infinity()) << endl; // 1 true 107 | // https://en.wikipedia.org/wiki/IEEE_754 부동소수점 표준에 따르면 수학적 정의와 동일하게 무한대 더하기 무한대는 무한대입니다. 108 | 109 | for (auto e : edges) 110 | { 111 | // if ( TODO ) 112 | { 113 | cout << "Negative cycle was found." << endl; 114 | return -1; 115 | } 116 | } 117 | 118 | cout << "Negative cycle was not found." << endl; 119 | 120 | PrintPaths(prev); 121 | 122 | return 0; 123 | } -------------------------------------------------------------------------------- /Ex1203_BellmanFord/Ex1203_BellmanFord.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1204_Arbitrage/Ex1204_Arbitrage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | template 11 | void Print(vector& dist) 12 | { 13 | for (int i = 0; i < dist.size(); i++) 14 | cout << setw(10) << dist[i]; 15 | cout << endl; 16 | } 17 | 18 | struct Edge 19 | { 20 | int v, w; 21 | double weight; 22 | }; 23 | 24 | int main() 25 | { 26 | constexpr double kInf = numeric_limits::infinity(); 27 | 28 | // Sedgewick p. 679 29 | vector> rates = { 30 | /* USD EUR GBP CHF CAD */ 31 | /*USD*/ { 1.0, 0.741, 0.657, 1.061, 1.005}, 32 | /*EUR*/ {1.349, 1.0, 0.888, 1.433, 1.366}, 33 | /*GBP*/ {1.521, 1.126, 1.0, 1.614, 1.538}, 34 | /*CHF*/ {0.942, 0.698, 0.619, 1.0, 0.953}, 35 | /*CAD*/ {0.995, 0.732, 0.650, 1.049, 1.0} 36 | }; 37 | 38 | int V = 5; 39 | 40 | vector edges; 41 | for (int i = 0; i < V; i++) 42 | for (int j = 0; j < V; j++) 43 | { 44 | if (i != j) 45 | edges.push_back({ i, j, rates[i][j] }); 46 | } 47 | 48 | // reverse(edges.begin(), edges.end()); 49 | 50 | int E = int(edges.size()); // number of edges 51 | 52 | vector dist(V, -kInf); 53 | vector prev(V, -1); 54 | 55 | int s = 0; // 시작 정점의 인덱스 56 | dist[s] = 1.0; 57 | 58 | Print(dist); 59 | 60 | for (int v = 1; v < V; v++) 61 | { 62 | for (auto e : edges) 63 | { 64 | // TODO: 65 | } 66 | 67 | Print(dist); 68 | } 69 | 70 | for (auto e : edges) 71 | { 72 | if (dist[e.w] < dist[e.v] * e.weight) 73 | { 74 | cout << "Arbitrage opportunity was found." << endl; 75 | prev[e.w] = e.v; 76 | 77 | // TODO: 78 | 79 | exit(0); 80 | } 81 | } 82 | 83 | cout << "Arbitrage opportunity was not found." << endl; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Ex1204_Arbitrage/Ex1204_Arbitrage.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1205_FloydWarshall/Ex1205_FloydWarshall.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1301_LongestCommonSequence/Ex1301_LongestCommonSequence.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1302_ZeroOneKnapsack/Ex1302_ZeroOneKnapsack.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1303_UnboundedKnapsack/Ex1303_UnboundedKnapsack.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1304_LargestIndependentSet/Ex1304_LargestIndependentSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | public: 10 | int value = 0; 11 | int memo = 0; // <- Memoization에 사용 12 | Node* left = nullptr; 13 | Node* right = nullptr; 14 | 15 | // 꼭 이진 트리가 아니라 싸이클이 없는 트리 구조면 다 가능합니다. 16 | }; 17 | 18 | int RecurLIS(Node* root) 19 | { 20 | if (root == nullptr) 21 | return 0; 22 | 23 | // Root 노드가 포함 되지 않는 경우: 자식들 포함 가능 24 | int case1 = RecurLIS(root->left) + RecurLIS(root->right); 25 | 26 | // Root 노드가 포함되는 경우는 하나 건너서 자식들의 자식들만 포함 가능합니다. 27 | int case2 = 1; 28 | if (root->left) 29 | case2 += RecurLIS(root->left->left) + RecurLIS(root->left->right); 30 | if (root->right) 31 | case2 += RecurLIS(root->right->left) + RecurLIS(root->right->right); 32 | 33 | // 두 가지 경우 중 큰 경우 반환 34 | return max(case1, case2); 35 | } 36 | 37 | int MemoLIS(Node* root) 38 | { 39 | // TODO: 40 | 41 | return 0; 42 | } 43 | 44 | Node* MakeNode(int data) 45 | { 46 | Node* temp = new Node(); 47 | temp->value = data; 48 | temp->left = temp->right = nullptr; 49 | return temp; 50 | } 51 | 52 | int main() 53 | { 54 | // 이진 트리 만들기 55 | Node* root = MakeNode(1); 56 | root->left = MakeNode(2); 57 | root->left->left = MakeNode(4); 58 | root->left->right = MakeNode(5); 59 | root->left->right->left = MakeNode(7); 60 | root->left->right->right = MakeNode(8); 61 | root->right = MakeNode(3); 62 | root->right->right = MakeNode(6); 63 | 64 | cout << RecurLIS(root) << endl; 65 | cout << MemoLIS(root) << endl; 66 | 67 | return 0; 68 | } 69 | 70 | // GeeksForGeeks 예제를 약간 변형하였습니다. 71 | // https://www.geeksforgeeks.org/largest-independent-set-problem-using-dynamic-programming/ 72 | -------------------------------------------------------------------------------- /Ex1304_LargestIndependentSet/Ex1304_LargestIndependentSet.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1401_FractionalKnapsack/Ex1401_FractionalKnapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Item 8 | { 9 | double value; 10 | double weight; 11 | }; 12 | 13 | void Print(vector& items) 14 | { 15 | for (auto i : items) 16 | { 17 | // (가성비 = value/weight = ratio, value, weight) 18 | cout << "(" << i.value / i.weight << ", " << i.value << ", " << i.weight << ") "; 19 | } 20 | cout << endl; 21 | } 22 | 23 | bool Compare(struct Item a, struct Item b) 24 | { 25 | double ratio_a = a.value / a.weight; 26 | double ratio_b = b.value / b.weight; 27 | 28 | return ratio_a > ratio_b; // ratio가 큰 쪽이 앞으로 오도록 정렬 29 | } 30 | 31 | double FractionalKnapsack(vector items, double W) 32 | { 33 | sort(items.begin(), items.end(), Compare); // Compare() 함수를 이용해서 정렬 34 | 35 | cout << "W = " << W << endl; 36 | Print(items); 37 | 38 | double vsum = 0.0; 39 | 40 | for (auto& i : items) 41 | { 42 | // TODO: 43 | } 44 | 45 | return vsum; 46 | } 47 | 48 | int main() 49 | { 50 | double W = 6.0; 51 | 52 | vector items = { { 10, 1 }, { 28, 4 }, { 12, 2 }, { 12, 3 } }; 53 | 54 | cout << FractionalKnapsack(items, W) << endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Ex1401_FractionalKnapsack/Ex1401_FractionalKnapsack.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1402_ActivitySelection/Ex1402_ActivitySelection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Activity 7 | { 8 | int start; 9 | int end; 10 | }; 11 | 12 | bool Compare(struct Activity a, struct Activity b) 13 | { 14 | // TODO: 15 | return false; 16 | } 17 | 18 | void Print(vector& activities) 19 | { 20 | if (activities.empty()) 21 | { 22 | cout << "Empty." << endl; 23 | return; 24 | } 25 | 26 | vector temp(activities.size() * 2); 27 | memcpy(&temp[0], &activities[0], sizeof(int) * temp.size()); 28 | int min_time = *std::min_element(temp.begin(), temp.end()); 29 | int max_time = *std::max_element(temp.begin(), temp.end()); 30 | 31 | for (int i = min_time; i <= max_time; i++) 32 | cout << i % 10; 33 | cout << endl; 34 | for (auto a : activities) 35 | { 36 | for (int i = min_time; i <= max_time; i++) 37 | cout << (a.start <= i && i <= a.end ? "#" : " "); 38 | cout << " (" << a.start << ", " << a.end << ")" << endl; 39 | } 40 | cout << endl; 41 | } 42 | 43 | vector GreedyActivitySelection(vector& activities) 44 | { 45 | sort(activities.begin(), activities.end(), Compare); 46 | 47 | Print(activities); 48 | 49 | vector schedule; 50 | 51 | // TODO: 52 | 53 | return schedule; 54 | } 55 | 56 | int main() 57 | { 58 | vector activities = 59 | { {5, 7}, {2, 5}, {6, 13}, {1, 8}, { 6, 9 }, {3, 8}, {9, 11}, {5, 12}, {8, 10}, {1, 4}, {3, 6}, {8, 14}, {13, 15} }; 60 | 61 | Print(activities); 62 | 63 | auto schedule = GreedyActivitySelection(activities); 64 | 65 | cout << schedule.size() << " activities selected." << endl; 66 | Print(schedule); 67 | 68 | return 0; 69 | } 70 | 71 | // CS161 예제에서는 끝나는 시간이 포함이고 CLRS p.422에서는 half-open이라서 끝나는 시간 미포함입니다. 72 | // 여기서는 CS161 방식이 더 직관적이라서 그대로 사용하였습니다. 예) {5, 12}이면 12도 활동 시간에 포함 -------------------------------------------------------------------------------- /Ex1402_ActivitySelection/Ex1402_ActivitySelection.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1403_HuffmanCoding/Ex1403_HuffmanCoding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | string data; // char보다 디버깅 편리 10 | int freq; 11 | Node* left = nullptr; 12 | Node* right = nullptr; 13 | }; 14 | 15 | // std::priority_queue에서 사용할 MinHeapNode의 비교 16 | struct Compare 17 | { 18 | bool operator()(Node* l, Node* r) 19 | { 20 | // TODO: 21 | return false; 22 | } 23 | }; 24 | 25 | void PrintCodes(Node* root, string str) 26 | { 27 | if (!root) 28 | return; 29 | 30 | if (!root->left && !root->right) // leaf node이면 출력 31 | cout << root->data << ": " << str << "\n"; 32 | 33 | PrintCodes(root->left, str + "0"); 34 | PrintCodes(root->right, str + "1"); 35 | } 36 | 37 | void HuffmanCoding(vector data, vector freq) 38 | { 39 | // freq가 작을 수록 우선순위가 높은 힙 40 | // struct Compare에서 우선순위 비교 41 | priority_queue, Compare> heap; 42 | 43 | for (int i = 0; i < data.size(); ++i) 44 | heap.push(new Node{ string(1, data[i]), freq[i] }); 45 | 46 | /* 47 | while (heap.size() != 1) 48 | { 49 | Node* left, * right, * top; 50 | 51 | // TODO: 52 | 53 | cout << "(" << left->data << ", " << left->freq << ") + (" << right->data << ", " << right->freq << ") -> "; 54 | cout << "(" << top->data << ", " << top->freq << ")" << endl; 55 | } 56 | */ 57 | 58 | PrintCodes(heap.top(), ""); 59 | } 60 | 61 | int main() 62 | { 63 | vector data = { 'a', 'b', 'c', 'd', 'e', 'f' }; 64 | vector freq = { 45, 13, 12, 16, 9, 5 }; 65 | 66 | HuffmanCoding(data, freq); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Ex1403_HuffmanCoding/Ex1403_HuffmanCoding.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1501_PrimMST/Ex1501_PrimMST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Ex1102_IndexMinPQ/IndexMinPQ.h" 5 | using namespace std; 6 | 7 | constexpr double kInf = numeric_limits::infinity(); 8 | 9 | struct DirectedEdge 10 | { 11 | int u; // 간선 시작(edge tail, 화살표 꼬리) 정점의 인덱스 12 | int v; // 간선 끝(edge head, 화살촉) 정점의 인덱스 13 | double weight; // edge weight (여기서는 u-v 이동 비용) 14 | }; 15 | 16 | class EdgeWeightedDigraph 17 | { 18 | public: 19 | vector> adj; 20 | 21 | EdgeWeightedDigraph(int num_vertices) 22 | { 23 | adj.resize(num_vertices); 24 | } 25 | 26 | void AddBiEdge(DirectedEdge e) // 양방향(무방향) 27 | { 28 | adj[e.u].push_back(e); 29 | adj[e.v].push_back({ e.v, e.u, e.weight }); 30 | } 31 | 32 | vector& Adj(int v) 33 | { 34 | return adj[v]; 35 | } 36 | 37 | void PrimMST() 38 | { 39 | int V = int(adj.size()); 40 | 41 | vector key(V, kInf); // dist in Sedgewick Algorithm 4.7, key in CLRS p. 596 42 | vector pre(V); // pi in CLRS 43 | 44 | double cost_sum = 0.0; 45 | 46 | key[0] = 0.0; 47 | pre[0] = -1; 48 | 49 | IndexMinPQ pq(V); 50 | 51 | // TODO: 우선순위큐에다가 일단 모든 정점의 인덱스를 넣는다. 52 | // 위에서 key[0] = 0.0 이기 때문에 0번이 가장 위로 온다. 53 | 54 | while (!pq.Empty()) 55 | { 56 | int u = pq.DelMin(); 57 | 58 | if (pre[u] >= 0) 59 | { 60 | cost_sum += key[u]; 61 | cout << pre[u] << " - " << u << " : " << key[u] << endl; 62 | } 63 | 64 | for (DirectedEdge& e : Adj(u)) 65 | { 66 | int v = e.v; 67 | double weight = e.weight; // u-v 간선 비용 68 | 69 | // if( TODO: v가 pq안에 아직 있는지 && u-v 비용이 더 적은지) 70 | //{ 71 | // pre[v] = u; 72 | // key[v] = weight; 73 | // pq.ChangeKey(v, weight); 74 | //} 75 | } 76 | } 77 | 78 | cout << cost_sum << endl; 79 | } 80 | }; 81 | 82 | int main() 83 | { 84 | vector edges = 85 | { 86 | { 0, 1, 4.0 }, 87 | { 0, 7, 9.0 }, 88 | { 1, 2, 8.0 }, 89 | { 1, 7, 11.0 }, 90 | { 2, 3, 7.0 }, 91 | { 2, 5, 4.0 }, 92 | { 2, 8, 2.0 }, 93 | { 3, 4, 9.0 }, 94 | { 3, 5, 14.0 }, 95 | { 4, 5, 10.0 }, 96 | { 5, 6, 2.0 }, 97 | { 6, 7, 1.0 }, 98 | { 6, 8, 6.0 }, 99 | { 7, 8, 7.0 }, 100 | }; 101 | 102 | EdgeWeightedDigraph g(9); 103 | 104 | for (auto e : edges) 105 | { 106 | g.AddBiEdge(e); 107 | } 108 | 109 | g.PrimMST(); 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /Ex1501_PrimMST/Ex1501_PrimMST.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1502_UnionFind/Ex1502_UnionFind.cpp: -------------------------------------------------------------------------------- 1 | #include "UnionFind.h" 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | UnionFind uf(4); 8 | vector> tests = 9 | { 10 | {0, 1}, {1, 2}, {2, 3}, {3, 0} 11 | }; 12 | 13 | uf.Print(); 14 | 15 | for (auto t : tests) 16 | { 17 | int u = t.first; 18 | int v = t.second; 19 | bool connected = uf.Connected(u, v); // uf.Find(p) == uf.Find(q); 20 | 21 | cout << u << " " << v << " " << std::boolalpha << connected << endl; 22 | cout << "Union " << u << " " << v << endl; 23 | 24 | uf.Union(u, v); 25 | 26 | uf.Print(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Ex1502_UnionFind/Ex1502_UnionFind.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /Ex1502_UnionFind/UnionFind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; // 편의용 8 | 9 | class UnionFind 10 | { 11 | public: 12 | vector group; 13 | int num_groups; 14 | 15 | UnionFind(int N) 16 | : group(N), num_groups(N) 17 | { 18 | for (int i = 0; i < group.size(); i++) 19 | group[i] = i; 20 | } 21 | 22 | int NumGroups() 23 | { 24 | return num_groups; 25 | } 26 | 27 | bool Connected(int p, int q) 28 | { 29 | return Find(p) == Find(q); 30 | } 31 | 32 | /* Quick-Find 방식: Union()에서 미리 정리하기 때문에 Find()는 빠름 */ 33 | int Find(int p) 34 | { 35 | return group[p]; 36 | } 37 | 38 | void Union(int p, int q) 39 | { 40 | int pid = Find(p); 41 | int qid = Find(q); 42 | 43 | if (pid == qid) return; 44 | 45 | for (int i = 0; i < group.size(); i++) 46 | { 47 | // TODO: 48 | } 49 | 50 | num_groups--; 51 | } 52 | 53 | /* Quick-Union 방식: Union()은 빠르고 Find()할 때 정리 */ 54 | /* 55 | int Find(int p) 56 | { 57 | while (p != group[p]) 58 | { 59 | // TODO: 60 | } 61 | 62 | return p; 63 | } 64 | 65 | void Union(int p, int q) 66 | { 67 | int i = Find(p); 68 | int j = Find(q); 69 | if (i == j) return; 70 | 71 | group[i] = j; 72 | 73 | num_groups--; 74 | } 75 | */ 76 | 77 | void Print() 78 | { 79 | cout << "Num groups = " << NumGroups() << endl; 80 | 81 | cout << "Index:"; 82 | for (int i = 0; i < group.size(); i++) 83 | cout << setw(3) << i; 84 | cout << endl; 85 | 86 | cout << "Group:"; 87 | for (auto i : group) 88 | cout << setw(3) << i; 89 | cout << endl; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /Ex1503_KruskalMST/Ex1503_KruskalMST.cpp: -------------------------------------------------------------------------------- 1 | #include "../Ex1502_UnionFind/UnionFind.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct Edge 9 | { 10 | int u; // 한쪽 끝 11 | int v; // 다른쪽 끝 12 | double weight; 13 | 14 | // 정렬할 때 사용 15 | bool operator < (const Edge& other) const 16 | { 17 | return weight < other.weight; 18 | } 19 | }; 20 | 21 | void PrintEdges(vector& edges) 22 | { 23 | for (auto e : edges) 24 | cout << "(" << e.u << ", " << e.v << ", " << e.weight << ")" << endl; 25 | } 26 | 27 | int main() 28 | { 29 | // Kruskal 알고리듬에서는 간선만 사용하기 때문에 edges만 가지고 진행 30 | vector edges = 31 | { 32 | { 0, 1, 4.0 }, 33 | { 0, 7, 9.0 }, 34 | { 1, 2, 8.0 }, 35 | { 1, 7, 11.0 }, 36 | { 2, 3, 7.0 }, 37 | { 2, 5, 4.0 }, 38 | { 2, 8, 2.0 }, 39 | { 3, 4, 9.0 }, 40 | { 3, 5, 14.0 }, 41 | { 4, 5, 10.0 }, 42 | { 5, 6, 2.0 }, 43 | { 6, 7, 1.0 }, 44 | { 6, 8, 6.0 }, 45 | { 7, 8, 7.0 }, 46 | }; 47 | 48 | // 여기서는 간선의 weight가 정점 사이의 이동 비용을 의미합니다. 49 | sort(edges.begin(), edges.end()); // 간선의 weight 오름차순 50 | 51 | PrintEdges(edges); // 정렬 결과 확인 52 | 53 | double mst_wt = 0.0; 54 | 55 | UnionFind uf(9); 56 | 57 | for (auto& e : edges) 58 | { 59 | // TODO: 60 | 61 | mst_wt += e.weight; 62 | 63 | cout << e.u << " - " << e.v << " : " << e.weight << endl; 64 | } 65 | 66 | cout << mst_wt << endl; 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Ex1503_KruskalMST/Ex1503_KruskalMST.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1601_FordFulkerson/Ex1601_FordFulkerson.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1701_BipartiteGraph/Ex1701_BipartiteGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | void Print(vector& colors) 9 | { 10 | for (auto c : colors) 11 | cout << std::setw(3) << c; 12 | cout << endl; 13 | } 14 | 15 | bool IsBipartite(vector>& graph) 16 | { 17 | int V = int(graph.size()); 18 | vector colors(V, -1); 19 | 20 | colors[0] = 0; 21 | 22 | queue q; 23 | q.push(0); 24 | 25 | while (!q.empty()) 26 | { 27 | int u = q.front(); 28 | q.pop(); 29 | 30 | assert(graph[u][u] == 0); 31 | 32 | for (int v = 0; v < V; ++v) 33 | { 34 | Print(colors); 35 | 36 | if (graph[u][v] && colors[v] == -1) 37 | { 38 | colors[v] = 1 - colors[u]; // color는 0 또는 1, 이웃은 다른 색으로 설정 39 | q.push(v); 40 | } 41 | //else if ( TODO ) 42 | //{ 43 | // cout << u << " " << v << endl; 44 | // return false; 45 | //} 46 | } 47 | 48 | Print(colors); 49 | } 50 | 51 | return true; 52 | } 53 | 54 | int main() 55 | { 56 | { 57 | vector> graph = 58 | { 59 | {0, 1, 1}, 60 | {1, 0, 1}, 61 | {1, 1, 0} 62 | }; 63 | 64 | cout << std::boolalpha << IsBipartite(graph) << endl; 65 | } 66 | 67 | { 68 | vector> graph = 69 | { 70 | {0, 0, 1, 1}, 71 | {0, 0, 1, 0}, 72 | {1, 1, 0, 0}, 73 | {1, 0, 0, 0} 74 | }; 75 | 76 | cout << std::boolalpha << IsBipartite(graph) << endl; 77 | } 78 | 79 | { 80 | vector> graph = 81 | { 82 | {0, 1, 1, 1}, // <- 0-1 추가 83 | {1, 0, 1, 0}, 84 | {1, 1, 0, 0}, 85 | {1, 0, 0, 0} 86 | }; 87 | 88 | cout << std::boolalpha << IsBipartite(graph) << endl; 89 | } 90 | 91 | return 0; 92 | } 93 | 94 | // 참고자료 95 | // https://www.geeksforgeeks.org/bipartite-graph/ -------------------------------------------------------------------------------- /Ex1701_BipartiteGraph/Ex1701_BipartiteGraph.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1702_GaleShapley/Ex1702_GaleShapley.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | struct Vertex 12 | { 13 | string name = ""; 14 | vector priority; // 선호도 우선순위 15 | int current = -1; // 현재 자신의 몇 "순위"와 연결되어 있는지 기록 16 | 17 | int Rank(string name) 18 | { 19 | for (int i = 0; i < priority.size(); i++) 20 | if (priority[i] == name) return i; 21 | 22 | assert(false); 23 | 24 | return -1; 25 | 26 | // Rank() 반환값이 작을 수록 우선순위가 높다 27 | // unordered_map<이름, 우선순위>를 만들어서 더 빠르게 확인 가능 28 | } 29 | 30 | string ConnectedName() 31 | { 32 | if (current == -1) return "NA"; 33 | else return priority[current]; 34 | } 35 | 36 | void Print() 37 | { 38 | cout << name << "("; 39 | for (auto& p : priority) 40 | cout << p; 41 | cout << ")"; 42 | } 43 | }; 44 | 45 | void Print(map& interns, unordered_map& teams) 46 | { 47 | for (auto& i : interns) 48 | { 49 | i.second.Print(); 50 | cout << " - "; 51 | if (i.second.current == -1) 52 | cout << "No Team"; 53 | else { 54 | teams[i.second.ConnectedName()].Print(); 55 | if (i.second.name != teams[i.second.ConnectedName()].ConnectedName()) 56 | cout << "*"; // 서로 연결이 아니라면 임시라는 의미로 * 추가 57 | } 58 | cout << endl; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | map interns; // 디버깅할때 순서대로 보기 위해 map 사용, unordered_map 사용 가능 65 | interns["A"] = Vertex{ "A", {"X", "Y", "Z"} }; 66 | interns["B"] = Vertex{ "B", {"Y", "X", "Z"} }; 67 | interns["C"] = Vertex{ "C", {"Y", "Z", "X"} }; 68 | 69 | unordered_map teams; 70 | teams["X"] = Vertex{ "X", {"B", "A", "C"} }; 71 | teams["Y"] = Vertex{ "Y", {"A", "B", "C"} }; 72 | teams["Z"] = Vertex{ "Z", {"B", "C", "A"} }; 73 | //teams["X"] = Vertex{ "X", {"B", "A", "C"} }; 74 | //teams["Y"] = Vertex{ "Y", {"A", "C", "B"} }; 75 | //teams["Z"] = Vertex{ "Z", {"B", "C", "A"} }; 76 | 77 | queue free_interns; 78 | for (auto& i : interns) 79 | free_interns.push(&i.second); // 모든 인턴을 free 큐에 넣기 80 | 81 | while (!free_interns.empty()) 82 | { 83 | Vertex* i = free_interns.front(); 84 | free_interns.pop(); 85 | 86 | cout << "Intern " << i->name << endl; 87 | 88 | // i->current += 1; 89 | 90 | // Vertex* t = &teams[i->ConnectedName()]; 91 | 92 | //if (t->current == -1) 93 | //{ 94 | // t->current = TODO; 95 | //} 96 | //else 97 | //{ 98 | // if ( TODO ) 99 | // { 100 | // free_interns.push(&interns[t->ConnectedName()]); 101 | // t->current = t->Rank(i->name); 102 | // } 103 | // else { 104 | // free_interns.push(i); 105 | // } 106 | //} 107 | 108 | Print(interns, teams); 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /Ex1702_GaleShapley/Ex1702_GaleShapley.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1801_LongestPath/Ex1801_LongestPath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Vertex 7 | { 8 | Vertex(int v) { value = v; } 9 | 10 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 11 | bool visited = false; 12 | 13 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 14 | }; 15 | 16 | class Graph 17 | { 18 | public: 19 | Graph(int num_vertices) 20 | { 21 | vertices.resize(num_vertices); 22 | for (int i = 0; i < num_vertices; i++) 23 | vertices[i] = new Vertex(i); 24 | } 25 | 26 | ~Graph() 27 | { 28 | for (auto* v : vertices) 29 | delete v; 30 | } 31 | 32 | void AddDiEdge(int v, int w) // 단방향 간선 33 | { 34 | vertices[v]->out_neighbors.push_back(vertices[w]); 35 | } 36 | 37 | void AddBiEdge(int v, int w) // 양방향 간선 38 | { 39 | vertices[v]->out_neighbors.push_back(vertices[w]); 40 | vertices[w]->out_neighbors.push_back(vertices[v]); 41 | } 42 | 43 | void DFS(int source) 44 | { 45 | cout << "Depth-first Search: "; 46 | for (auto* v : this->vertices) 47 | v->visited = false; 48 | DFS(vertices[source]); 49 | cout << endl; 50 | } 51 | 52 | void DFS(Vertex* source) 53 | { 54 | cout << source->value << " "; 55 | source->visited = true; 56 | for (auto* w : source->out_neighbors) 57 | if (!w->visited) 58 | DFS(w); 59 | } 60 | 61 | void DepthFirstPath(int source, int sink) 62 | { 63 | cout << "Paths from " << vertices[source]->value << " to " << vertices[sink]->value << endl; 64 | 65 | longest_path.clear(); 66 | 67 | for (auto* v : this->vertices) 68 | v->visited = false; 69 | 70 | DepthFirstPathHelper(vertices[source], vertices[sink], vector()); 71 | 72 | cout << "Longest length : " << int(longest_path.size() - 1) << endl; 73 | cout << "Longest path : "; 74 | PrintPath(longest_path); 75 | } 76 | 77 | private: 78 | vector vertices; 79 | vector longest_path; 80 | 81 | void DepthFirstPathHelper(Vertex* source, Vertex* sink, vector path) 82 | { 83 | // TODO: 84 | } 85 | 86 | void PrintPath(vector path) 87 | { 88 | for (auto& v : path) { 89 | cout << v->value; 90 | if (&v != &path.back()) 91 | cout << " -> "; 92 | } 93 | cout << endl; 94 | } 95 | }; 96 | 97 | int main() 98 | { 99 | Graph g(6); 100 | 101 | // 주의: 양방향 간선 (undirected graph) 102 | g.AddBiEdge(0, 2); 103 | g.AddBiEdge(2, 1); 104 | g.AddBiEdge(2, 3); 105 | g.AddBiEdge(3, 4); 106 | g.AddBiEdge(1, 5); 107 | g.AddBiEdge(2, 4); 108 | g.AddBiEdge(3, 5); 109 | 110 | g.DepthFirstPath(0, 4); 111 | 112 | return 0; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Ex1801_LongestPath/Ex1801_LongestPath.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Ex1802_TravellingSalesmanProblem/Ex1802_TravellingSalesmanProblem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Edge 7 | { 8 | int u = 0; 9 | int v = 0; 10 | int weight = 0; 11 | }; 12 | 13 | struct Vertex 14 | { 15 | Vertex(int v) { value = v; } 16 | 17 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 18 | bool visited = false; 19 | 20 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 21 | }; 22 | 23 | class Graph 24 | { 25 | public: 26 | Graph(int num_vertices) 27 | { 28 | vertices.resize(num_vertices); 29 | for (int i = 0; i < num_vertices; i++) 30 | vertices[i] = new Vertex(i); 31 | } 32 | 33 | ~Graph() 34 | { 35 | for (auto* v : vertices) 36 | delete v; 37 | } 38 | 39 | void AddDiEdge(int u, int v, int weight) // 단방향 간선 40 | { 41 | vertices[u]->out_neighbors.push_back(Edge{ u, v, weight }); 42 | } 43 | 44 | void AddBiEdge(int u, int v, int weight) // 양방향 간선 45 | { 46 | vertices[u]->out_neighbors.push_back(Edge{ u, v, weight }); 47 | vertices[v]->out_neighbors.push_back(Edge{ v, u, weight }); 48 | } 49 | 50 | void TravellingSalesman(int source) 51 | { 52 | cout << "Start : " << vertices[source]->value << endl; 53 | 54 | minimum_path.clear(); 55 | 56 | for (auto* v : this->vertices) 57 | v->visited = false; 58 | 59 | TravellingSalesmanHelper(vertices[source], vertices[source], vector(), 0); 60 | 61 | cout << "Minimum cost : " << min_wsum << endl; 62 | cout << "Minimum path : "; 63 | PrintPath(minimum_path); 64 | } 65 | 66 | private: 67 | vector vertices; 68 | vector minimum_path; 69 | int min_wsum = 1000000; // large number 70 | 71 | void TravellingSalesmanHelper(Vertex* source, Vertex* sink, vector path, int wsum) 72 | { 73 | // TODO: 74 | } 75 | 76 | void PrintPath(vector path) 77 | { 78 | for (auto& v : path) { 79 | cout << v->value; 80 | if (&v != &path.back()) 81 | cout << " -> "; 82 | } 83 | cout << endl; 84 | } 85 | }; 86 | 87 | int main() 88 | { 89 | Graph g(4); 90 | 91 | // 주의: 양방향 간선 (undirected graph) 92 | g.AddBiEdge(0, 1, 20); 93 | g.AddBiEdge(0, 2, 25); 94 | g.AddBiEdge(0, 3, 30); 95 | g.AddBiEdge(1, 2, 10); 96 | g.AddBiEdge(2, 3, 35); 97 | g.AddBiEdge(3, 1, 15); 98 | 99 | g.TravellingSalesman(0); 100 | 101 | return 0; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /Ex1802_TravellingSalesmanProblem/Ex1802_TravellingSalesmanProblem.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [홍정모 연구소](https://honglab.co.kr/) 2 | 3 | - 온라인 강의노트 같은 2차 저작물에는 참고자료에 "[홍정모 연구소](https://honglab.co.kr/)"를 꼭 적어주세요. 4 | - 다른 학생들의 공부를 위해서 실습 문제의 정답이나 풀이를 온라인에 공개하지 마세요. 5 | 6 | ## [알고리듬 압축코스 파트1](https://honglab.co.kr/courses/algorithms) 7 | 8 | ### 선수 과목 9 | - 프로그래밍 입문은 **[홍정모의 파이썬 추월코스](https://honglab.co.kr/courses/python)** 10 | - 코테 공부용 C++ 문법은 **[C++ 핵심정리(무료)](https://honglab.co.kr/courses/cppsummary)** 11 | - 기초적인 자료구조와 프로그래밍 연습은 **[자료구조 압축코스](https://honglab.co.kr/courses/data-structures)** 12 | 13 | ## 예제 사용 방법 14 | - Visual Studio 2022 설정 제공 (**HongLabAlgorithmsPart1.sln 더블 클릭**) 15 | - Visual Studio Code는 VSCode 폴더 사용 ([VSCode 사용법](https://youtu.be/uDq7woPOZ_A?si=3qoGEBENHcFFOttB)) 16 | - 맥에서 VSCode 사용 시에는 tasks.json에 "-std=c++17" 과 "${fileDirname}/*.cpp" 추가해주세요. [샘플](https://github.com/HongLabInc/HongLabCppSummary/blob/main/.vscode_mac/tasks.json) 17 | 18 | ## 주의 사항 19 | - 사용자 이름이나 폴더에 한글 사용 금지 (시간 낭비 방지 차원입니다.) 20 | 21 | -------------------------------------------------------------------------------- /VSCode/Ex0002_WarmingUp/Ex0002_WarmingUp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | // 문제 1. 10진수 -> 2진수 8 | { 9 | int decimal = 105; 10 | string binary; 11 | 12 | //TODO: 13 | 14 | cout << binary << endl; // 1101001 15 | } 16 | 17 | // 문제 2. 문자열 뒤집기 18 | { 19 | string input = "Hello, World!"; 20 | 21 | // TODO: 22 | 23 | cout << input << endl; // !dlroW ,olleH 24 | } 25 | 26 | // 문제 3. 모든 자리 다 더하기 27 | { 28 | string n = "789789"; 29 | 30 | // TODO: 31 | 32 | cout << n << endl; 33 | } 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /VSCode/Ex0101_Addition/Ex0101_Addition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string Add(string str1, string str2) 8 | { 9 | // TODO: 10 | 11 | return string("0"); 12 | } 13 | 14 | int main() 15 | { 16 | vector> tests = { 17 | {"12", "34", to_string(12 + 34)} 18 | , {"123", "45", to_string(123 + 45)} 19 | , {"54544", "44545", to_string(54544 + 44545)} 20 | , {"5555", "55", to_string(5555 + 55)} 21 | , {"5555", "5555", to_string(5555 + 5555)} 22 | , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "11538017781967960909090003089999089"} 23 | }; 24 | 25 | for (const auto& t : tests) 26 | { 27 | const string str1 = t[0]; // "12" 28 | const string str2 = t[1]; // "34" 29 | const string expected = t[2]; // "46" 30 | 31 | cout << str1 << " + " << str2 << " = " << expected << endl; 32 | 33 | const string result = Add(str1, str2); 34 | 35 | cout << result << " " << expected << " "; 36 | 37 | if (result == expected) 38 | cout << "OK" << endl; 39 | else { 40 | cout << "Not OK" << endl; 41 | exit(-1); 42 | } 43 | cout << endl << endl; 44 | } 45 | 46 | cout << "Congratulations. All OK!" << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /VSCode/Ex0102_Subtraction/Ex0102_Subtraction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // 항상 큰 수에서 작은 수를 빼는 경우(결과가 음수가 되지 않는 경우)를 가정 8 | string Subtract(string str1, string str2) 9 | { 10 | // 둘이 같을 경우 바로 "0" 반환 11 | if (str1 == str2) 12 | return "0"; // '0'은 char, "0"은 string 13 | 14 | int N = max(str1.size(), str2.size()); 15 | str1 = string(N - str1.size(), '0') + str1; // 문자열끼리의 더하기도 가능 16 | str2 = string(N - str2.size(), '0') + str2; 17 | 18 | string result(N, '0'); 19 | 20 | // TODO: 더하기와 거의 비슷합니다. 21 | 22 | // 불필요한 '0' 제거 (예: "078" -> "78") 23 | // TODO: 24 | 25 | return result; 26 | } 27 | 28 | int main() 29 | { 30 | // 항상 큰 수에서 작은 수를 빼는 경우(결과가 음수가 되지 않는 경우)를 가정 31 | vector> tests = { 32 | {"34", "12", std::to_string(34 - 12)} 33 | , {"123", "45", std::to_string(123 - 45)} 34 | , {"54544", "44545", std::to_string(54544 - 44545)} 35 | , {"5555", "55", std::to_string(5555 - 55)} 36 | , {"5555", "5555", std::to_string(5555 - 5555)} 37 | , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "8108924688874870000000906000909999"} 38 | }; 39 | 40 | for (const auto& t : tests) 41 | { 42 | const string str1 = t[0]; 43 | const string str2 = t[1]; 44 | const string expected = t[2]; 45 | 46 | cout << str1 << " - " << str2 << " = " << expected << endl; 47 | 48 | const string result = Subtract(str1, str2); 49 | 50 | cout << result << " " << expected << " "; 51 | 52 | if (result == expected) 53 | cout << "OK"; 54 | else { 55 | cout << "Not OK"; 56 | exit(-1); 57 | } 58 | cout << endl << endl; 59 | } 60 | 61 | cout << "Congratulations. All OK!" << endl; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /VSCode/Ex0103_Multiplication/Ex0103_Multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string Multiply(string str1, string str2) 8 | { 9 | // TODO: 10 | 11 | return "0"; 12 | } 13 | 14 | int main() 15 | { 16 | vector> tests = { 17 | {"12", "34", std::to_string(12 * 34)}, 18 | {"123", "45", std::to_string(123 * 45)}, 19 | {"5555", "55", std::to_string(5555 * 55)}, 20 | {"5555", "5555", std::to_string(5555 * 5555)}, 21 | {"98234712354214154", "171454654654655", "16842798681791158832220782986870"} 22 | // , {"9823471235421415454545454545454544", "1714546546546545454544548544544545", "16842798681791114273590624445460185389471221520083884298838480662480"} 23 | }; 24 | 25 | for (const auto& t : tests) 26 | { 27 | const string str1 = t[0]; 28 | const string str2 = t[1]; 29 | const string expected = t[2]; 30 | 31 | cout << str1 << " * " << str2 << " = " << expected << endl; 32 | 33 | const string result = Multiply(str1, str2); 34 | 35 | cout << result << " " << expected << " "; 36 | 37 | if (result == expected) 38 | cout << "OK"; 39 | else { 40 | cout << "Not OK"; 41 | exit(-1); 42 | } 43 | cout << endl << endl; 44 | } 45 | 46 | cout << "Congratulations. All OK!" << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /VSCode/Ex0201_InsertionSort/Ex0201_InsertionSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool CheckSorted(vector& arr) 6 | { 7 | for (int i = 0; i < arr.size() - 1; i++) 8 | { 9 | if (arr[i] > arr[i + 1]) 10 | return false; 11 | } 12 | 13 | return true; 14 | } 15 | 16 | void Print(vector& arr) 17 | { 18 | for (auto v : arr) 19 | cout << v << " "; 20 | cout << endl; 21 | } 22 | 23 | int main() 24 | { 25 | // vector a = { 6, 5, 4, 3, 2, 1 }; 26 | vector a = { 6, 4, 3, 8, 5 }; 27 | 28 | int N = a.size(); 29 | for (int i = 1; i < N; i++) 30 | { 31 | // TODO: 딱 2줄만 사용 32 | 33 | Print(a); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /VSCode/Ex0202_InsertionSortPerformance/Ex0202_InsertionSortPerformance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include // std::iota 8 | 9 | using namespace std; 10 | using namespace std::chrono; 11 | 12 | void Print(vector& arr) 13 | { 14 | for (int i = 0; i < arr.size(); i++) 15 | cout << arr[i] << " "; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | void InsertionSort1(vector& a) 31 | { 32 | int N = a.size(); 33 | for (int i = 1; i < N; i++) 34 | for (int j = i; j > 0 && a[j - 1] > a[j]; j--) 35 | swap(a[j - 1], a[j]); 36 | } 37 | 38 | void InsertionSort2(vector& a) 39 | { 40 | int N = a.size(); 41 | int i; 42 | for (i = 1; i < N; i++) 43 | { 44 | int key = a[i]; 45 | int j = i; 46 | for (; j > 0 && a[j - 1] > key; j--) 47 | a[j] = a[j - 1]; 48 | a[j] = key; 49 | } 50 | } 51 | 52 | struct Sample { 53 | int n; 54 | double duration; 55 | }; 56 | 57 | int main() 58 | { 59 | random_device rd; 60 | mt19937 gen(rd()); 61 | 62 | vector samples; 63 | samples.reserve(5000); 64 | 65 | for (int n = 1; n <= 5000; n += 1) 66 | { 67 | vector my_vector(n); 68 | 69 | for (int r = 0; r < n; r += max(1, n / 100)) 70 | { 71 | // 0 이상 n-1 이하의 정수가 균일한 확률로 생성되는 난수 (uniform distribution) 72 | //uniform_int_distribution value_distribution(0, n - 1); 73 | //generate(my_vector.begin(), my_vector.end(), [&]() { return value_distribution(gen); }); 74 | 75 | std::iota(my_vector.begin(), my_vector.end(), 0); // iota는 0, 1, 2, ... , n-1 까지 순서대로 채워주는 함수 76 | std::reverse(my_vector.begin(), my_vector.end()); // 최악의 경우를 만들기 위해 순서를 뒤집어주기 77 | std::random_shuffle(my_vector.begin(), my_vector.begin() + r); // 일부만 순서를 바꿔줌 (shuffle은 딜러가 카드 섞는 것 생각하면 됩니다.) 78 | 79 | // Print(my_vector); 80 | 81 | // Random case 82 | auto start = high_resolution_clock::now(); 83 | 84 | InsertionSort2(my_vector); 85 | 86 | auto stop = high_resolution_clock::now(); 87 | auto dur = double(duration_cast(stop - start).count()) / 1000000000.0; 88 | 89 | if (!CheckSorted(my_vector)) 90 | { 91 | cout << "Failed." << endl; 92 | exit(-1); 93 | } 94 | 95 | samples.push_back({ n, dur }); 96 | 97 | if (n % 1000 == 0 && r == 0) 98 | { 99 | cout << n << " : " << dur << endl; 100 | } 101 | } 102 | } 103 | 104 | ofstream ofile("result_insertion2_worstshuffle.txt"); 105 | for (auto& s : samples) 106 | ofile << s.n << ", " << s.duration << endl; 107 | 108 | ofile.close(); 109 | 110 | cout << "\a" << endl; 111 | } 112 | -------------------------------------------------------------------------------- /VSCode/Ex0301_TopdownMergesort/Ex0301_TopdownMergesort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // setfill(), setw() 4 | #include // iota 5 | 6 | using namespace std; 7 | 8 | void Print(vector& arr, int lo, int hi) 9 | { 10 | // setfill(), setw()는 줄맞춤에 사용 11 | 12 | for (int i = 0; i < lo; i++) 13 | cout << " "; 14 | for (int i = lo; i <= hi; i++) 15 | cout << setfill(' ') << setw(3) << arr[i]; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | // Sedgewick p. 273 31 | class TopDownMerge 32 | { 33 | public: 34 | void Sort(vector& a) 35 | { 36 | count = 0; // 분석용 37 | aux.resize(a.size()); 38 | 39 | SortHelper(a, 0, a.size() - 1); 40 | } 41 | 42 | private: 43 | void Merge(vector& a, int lo, int mid, int hi) 44 | { 45 | cout << "Before: "; 46 | Print(a, lo, hi); 47 | 48 | int i = lo, j = mid + 1; 49 | 50 | for (int k = lo; k <= hi; k++) 51 | aux[k] = a[k]; 52 | 53 | for (int k = lo; k <= hi; k++) 54 | { 55 | //if (i > mid) TODO; 56 | //else if (j > hi) TODO; 57 | //else if (aux[j] < aux[i]) TODO; 58 | //else a[k] = TODO; 59 | } 60 | 61 | cout << "After : "; 62 | Print(a, lo, hi); 63 | 64 | //count += hi - lo + 1; 65 | //cout << "Count : " << hi - lo + 1 << ", " << count << endl; // 누적 카운트 (디버깅용) 66 | } 67 | 68 | void SortHelper(vector& a, int lo, int hi) 69 | { 70 | if (hi <= lo) return; 71 | 72 | int mid = lo + (hi - lo) / 2; 73 | 74 | //TODO: 75 | //TODO: 76 | 77 | Merge(a, lo, mid, hi); 78 | } 79 | 80 | vector aux; // 추가 메모리 필요 81 | int count = 0; // 연산 횟수 세보기용 82 | }; 83 | 84 | int main() 85 | { 86 | vector my_vector(16); 87 | std::iota(my_vector.begin(), my_vector.end(), 0); 88 | std::reverse(my_vector.begin(), my_vector.end()); 89 | 90 | cout << " "; 91 | Print(my_vector, 0, my_vector.size() - 1); 92 | 93 | TopDownMerge merge; 94 | merge.Sort(my_vector); 95 | 96 | cout << " "; 97 | Print(my_vector, 0, my_vector.size() - 1); 98 | } 99 | -------------------------------------------------------------------------------- /VSCode/Ex0302_BottomupMergesort/Ex0302_BottomupMergesort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // std::iota 5 | 6 | using namespace std; 7 | 8 | void Print(vector& arr, int lo, int hi) 9 | { 10 | // setfill(), setw()는 줄맞춤에 사용 11 | 12 | for (int i = 0; i < lo; i++) 13 | cout << " "; 14 | for (int i = lo; i <= hi; i++) 15 | cout << setfill(' ') << setw(3) << arr[i]; 16 | cout << endl; 17 | } 18 | 19 | bool CheckSorted(vector& a) 20 | { 21 | for (int i = 0; i < a.size() - 1; i++) 22 | { 23 | if (a[i] > a[i + 1]) 24 | return false; 25 | } 26 | 27 | return true; 28 | } 29 | 30 | // Sedgewick p. 278 31 | class BottomupMerge 32 | { 33 | public: 34 | void Sort(vector& a) 35 | { 36 | aux.resize(a.size()); 37 | 38 | int N = a.size(); 39 | // TODO: 재귀호출 사용하지 않습니다. 40 | } 41 | 42 | private: 43 | void Merge(vector& a, int lo, int mid, int hi) 44 | { 45 | // TODO: Top-down과 동일 46 | } 47 | 48 | vector aux; // 추가 메모리 49 | }; 50 | 51 | int main() 52 | { 53 | vector my_vector(16); 54 | std::iota(my_vector.begin(), my_vector.end(), 0); 55 | std::reverse(my_vector.begin(), my_vector.end()); 56 | 57 | cout << " "; 58 | Print(my_vector, 0, my_vector.size() - 1); 59 | 60 | BottomupMerge merge; 61 | merge.Sort(my_vector); 62 | 63 | cout << " "; 64 | Print(my_vector, 0, my_vector.size() - 1); 65 | } 66 | -------------------------------------------------------------------------------- /VSCode/Ex0401_CountOccurrences/Ex0401_CountOccurrences.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | void Print(vector& arr) 10 | { 11 | for (int i = 0; i < arr.size(); i++) 12 | cout << arr[i] << " "; 13 | cout << endl; 14 | } 15 | 16 | int Count1(const vector& arr, int x) 17 | { 18 | //TODO: O(n) 19 | return 0; 20 | } 21 | 22 | int Count2(const vector& arr, int x) 23 | { 24 | //TODO: O(log(n) + count) 25 | return 0; 26 | } 27 | 28 | int Count3(const vector& arr, int x) 29 | { 30 | //TODO: O(log(n)) 31 | return 0; 32 | } 33 | 34 | int main() 35 | { 36 | random_device rd; 37 | mt19937 gen(rd()); 38 | 39 | const int n = 20; 40 | vector my_vector(n); 41 | 42 | int x = 6; // target to find 43 | 44 | for (int r = 0; r < 100; r++) 45 | { 46 | uniform_int_distribution value_distribution(1, 10); 47 | generate(my_vector.begin(), my_vector.end(), [&]() { return value_distribution(gen); }); 48 | sort(my_vector.begin(), my_vector.end()); 49 | 50 | Print(my_vector); 51 | 52 | const int expected_count = std::count(my_vector.begin(), my_vector.end(), x); 53 | 54 | cout << "Expected count = " << expected_count << endl; 55 | 56 | // 1. O(n) brute force 57 | if (Count1(my_vector, x) != expected_count) 58 | { 59 | cout << "Wrong count1: " << Count1(my_vector, x) << endl; 60 | exit(-1); 61 | } 62 | 63 | // 2. O(log(n) + count) 64 | if (Count2(my_vector, x) != expected_count) 65 | { 66 | cout << "Wrong count2: " << Count2(my_vector, x) << endl; 67 | exit(-1); 68 | } 69 | 70 | // 3. O(log(n)) 71 | if (Count3(my_vector, x) != expected_count) 72 | { 73 | cout << "Wrong count3: " << Count3(my_vector, x) << endl; 74 | exit(-1); 75 | } 76 | } 77 | 78 | cout << "Good!" << endl; 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /VSCode/Ex0402_PartialSelectionSort/Ex0402_PartialSelectionSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | void Print(vector& arr) 10 | { 11 | for (int i = 0; i < arr.size(); i++) 12 | cout << arr[i] << " "; 13 | cout << endl; 14 | } 15 | 16 | // 가장 작은 값이 arr[lo]에 오도록 17 | void SelectionSortPass(vector& arr, int lo, int hi) 18 | { 19 | // TODO: 20 | } 21 | 22 | void PartialSelectionSort(vector& arr, int k) 23 | { 24 | Print(arr); 25 | 26 | for (int i = 0; i < k; i++) 27 | { 28 | // SelectionSortPass( TODO: ); 29 | 30 | Print(arr); 31 | } 32 | } 33 | 34 | int main() 35 | { 36 | vector my_vector = { 7, 10, 4, 3, 20, 15 }; 37 | 38 | int k = 3; 39 | 40 | PartialSelectionSort(my_vector, k); 41 | 42 | cout << my_vector[k - 1] << endl; 43 | } 44 | -------------------------------------------------------------------------------- /VSCode/Ex0403_MinAndMax/Ex0403_MinAndMax.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | vector arr = { 8, 2, 3, 5, 9, 1, 9, 4, 3, 7, 6, 7 }; 8 | 9 | // TODO: 10 | 11 | cout << "Min value = " << arr[0] << ", Max value = " << arr[1] << endl; // Min value = 1, Max value = 9 12 | } 13 | -------------------------------------------------------------------------------- /VSCode/Ex0404_PartitionByPivot/Ex0404_PartitionByPivot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void Print(vector& arr) 6 | { 7 | for (int i = 0; i < arr.size(); i++) 8 | cout << arr[i] << " "; 9 | cout << endl; 10 | } 11 | 12 | int main() 13 | { 14 | vector arr = { 5, 2, 7, 3, 8, 5, 6, 4 }; 15 | //vector arr = { 2, 8, 7, 1, 3, 5, 6, 4 }; 16 | //vector arr = { 9, 8, 7, 6, 4, 3, 2, 1, 5 }; 17 | //vector arr = { 5, 2, 7, 3, 4, 4, 6, 4 }; 18 | 19 | int lo = 0; // 첫 인덱스 20 | int hi = arr.size() - 1; // 마지막 인덱스 21 | int x = arr[hi]; // 분할 기준으로 사용하는 pivot 4 22 | 23 | int i = lo - 1; // pivot보다 것들중 가장 큰 인덱스 24 | 25 | Print(arr); 26 | 27 | // TODO: 28 | 29 | swap(arr[i + 1], arr[hi]); 30 | Print(arr); 31 | 32 | cout << i + 1 << endl; // 피벗 이하인 값들의 마지막 인덱스 33 | } 34 | -------------------------------------------------------------------------------- /VSCode/Ex0501_RandomizedQuicksort/Ex0501_RandomizedQuicksort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void Print(vector& arr, int lo, int hi, string sep = "") 7 | { 8 | //cout << "Index: "; 9 | //for (int i = 0; i < arr.size(); i++) 10 | // cout << setfill(' ') << setw(3) << i; 11 | //cout << endl; 12 | 13 | cout << "Value: "; 14 | for (int i = 0; i < arr.size(); i++) { 15 | 16 | if (lo <= i && i <= hi) 17 | cout << setfill(' ') << setw(3) << arr[i] << sep; 18 | else 19 | cout << " "; 20 | } 21 | cout << endl; 22 | } 23 | 24 | int Partition(vector& arr, int lo, int hi) 25 | { 26 | cout << "Pivot = " << arr[hi] << endl; 27 | 28 | int x = arr[hi]; 29 | int i = lo - 1; 30 | for (int j = lo; j < hi; j++) 31 | if (arr[j] <= x) 32 | { 33 | i += 1; 34 | swap(arr[i], arr[j]); 35 | } 36 | 37 | swap(arr[i + 1], arr[hi]); 38 | 39 | Print(arr, lo, hi); 40 | 41 | return i + 1; // 피벗이 이동한 위치 반환 42 | } 43 | 44 | int RandomizedPartition(vector& arr, int lo, int hi) 45 | { 46 | int random = lo + rand() % (hi - lo + 1); 47 | swap(arr[random], arr[hi]); 48 | return Partition(arr, lo, hi); 49 | } 50 | 51 | void RandomizedQuicksort(vector& arr, int lo, int hi) 52 | { 53 | Print(arr, lo, hi); 54 | 55 | // TODO: 56 | } 57 | 58 | int main() 59 | { 60 | srand(2); 61 | 62 | vector arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; 63 | 64 | RandomizedQuicksort(arr, 0, arr.size() - 1); 65 | 66 | Print(arr, 0, arr.size() - 1); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /VSCode/Ex0502_Quick3way/Ex0502_Quick3way.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void Print(vector& arr, int lo, int hi, string sep = "") 7 | { 8 | //cout << "Index: "; 9 | //for (int i = 0; i < arr.size(); i++) 10 | // cout << setfill(' ') << setw(3) << i; 11 | //cout << endl; 12 | 13 | cout << "Value: "; 14 | for (int i = 0; i < arr.size(); i++) { 15 | 16 | if (lo <= i && i <= hi) 17 | cout << setfill(' ') << setw(3) << arr[i] << sep; 18 | else 19 | cout << " "; 20 | } 21 | cout << endl; 22 | } 23 | 24 | // Quicksort with 3-way partitioning, Sedgewick p299 25 | // (Dijkstra's Dutch national flag problem) 26 | void Quick3way(vector& arr, int lo, int hi) 27 | { 28 | if (hi <= lo) return; 29 | 30 | int lt = lo, i = lo + 1, gt = hi; 31 | int v = arr[lo]; 32 | 33 | //while (i <= gt) 34 | //{ 35 | // // TODO: 36 | //} 37 | 38 | Print(arr, lo, hi); 39 | 40 | //Quick3way(arr, lo, lt - 1); 41 | //Quick3way(arr, gt + 1, hi); 42 | } 43 | 44 | int main() 45 | { 46 | srand(0); 47 | 48 | vector arr = { 3, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 2, 3, 4, 5, 1, 3, 5 }; 49 | 50 | Print(arr, 0, arr.size() - 1); 51 | 52 | Quick3way(arr, 0, arr.size() - 1); 53 | 54 | Print(arr, 0, arr.size() - 1); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /VSCode/Ex0601_CountingSort/Ex0601_CountingSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto a : arr) 14 | if (a == -1) 15 | cout << "X "; 16 | else 17 | cout << a << " "; 18 | cout << endl; 19 | } 20 | 21 | // 입력은 0 이상 k 이하의 정수, CSLR 8.2 22 | // 결과를 반환하는 구조 (In-place가 아님) 23 | vector CountingSort(const vector& arr, int k) 24 | { 25 | vector count(k + 1, 0); // k + 1개를 0으로 초기화 26 | 27 | // TODO: 28 | 29 | cout << "Count: "; 30 | Print(count); 31 | 32 | vector output(arr.size(), -1); // -1로 초기화하는 것은 디버깅용 33 | 34 | // 역순으로 복사 35 | for (int i = output.size() - 1; i >= 0; i--) 36 | { 37 | // TODO: 38 | 39 | cout << "Count: "; 40 | Print(count); 41 | 42 | cout << "Output: "; 43 | Print(output); 44 | } 45 | 46 | return output; 47 | } 48 | 49 | int main() 50 | { 51 | vector arr = { 2, 5, 3, 0, 2, 3, 0, 3 }; 52 | 53 | Print(arr); 54 | 55 | int k = *std::max_element(arr.begin(), arr.end()); // 가장 큰 값 찾기 56 | // 가장 작은 값은 0이라고 고정 57 | 58 | vector result = CountingSort(arr, k); 59 | 60 | Print(result); 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /VSCode/Ex0602_RadixSort/Ex0602_RadixSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto& a : arr) 14 | cout << a << " "; 15 | cout << endl; 16 | } 17 | 18 | // 편의상 결과가 arr에 저장되도록 바꿨습니다. 19 | void CountingSort(vector& arr, int k, int exp) 20 | { 21 | vector temp = arr; // 복사 22 | 23 | vector count(k + 1, 0); 24 | // TODO: 25 | 26 | for (int i = arr.size() - 1; i >= 0; i--) 27 | { 28 | // TODO: 29 | } 30 | } 31 | 32 | void RadixSort(vector& arr) 33 | { 34 | int k = 10; // 여기서는 10으로 고정 35 | int m = *max_element(arr.begin(), arr.end()); 36 | 37 | //for (TODO) 38 | //{ 39 | // cout << "exp = " << exp << endl; 40 | // TODO: 41 | // Print(arr); 42 | //} 43 | } 44 | 45 | int main() 46 | { 47 | vector arr = { 170, 45, 75, 90, 802, 24, 2, 66 }; 48 | //vector arr = { 2, 5, 3, 0, 2, 3, 0, 3 }; 49 | 50 | Print(arr); 51 | 52 | RadixSort(arr); 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /VSCode/Ex0603_SortingWords/Ex0603_SortingWords.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | template 13 | void Print(vector& arr) 14 | { 15 | for (auto& a : arr) 16 | cout << a << " "; 17 | cout << endl; 18 | } 19 | 20 | void CountingSort(vector& arr, int k, int d) 21 | { 22 | // vector temp = arr; // 복사 23 | // std::fill(arr.begin(), arr.end(), " "); // 디버깅 편의 24 | 25 | // TODO: 26 | } 27 | 28 | void RadixSort(vector& arr) 29 | { 30 | // TODO: 31 | } 32 | 33 | int main() 34 | { 35 | // CLRS 8.3-1 36 | vector arr = { "COW", "DOG", "SEA", "RUG", 37 | "ROW", "MOB", "BOX", "TAB", "BAR", "EAR", "TAR", 38 | "DIG", "BIG", "TEA", "NOW", "FOX" }; 39 | 40 | Print(arr); 41 | 42 | RadixSort(arr); 43 | 44 | Print(arr); 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /VSCode/Ex0604_BucketSort/Ex0604_BucketSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void Print(vector& arr) 12 | { 13 | for (auto& a : arr) 14 | cout << a << " "; 15 | cout << endl; 16 | } 17 | 18 | void PrintBuckets(vector>& buckets) 19 | { 20 | for (int i = 0; i < buckets.size(); i++) 21 | { 22 | cout << i << ": "; 23 | for (int j = 0; j < buckets[i].size(); j++) 24 | cout << buckets[i][j] << " "; 25 | cout << endl; 26 | } 27 | } 28 | 29 | // 다른 정렬을 사용해도 됩니다. 30 | void InsertionSort(vector& bucket) 31 | { 32 | for (int i = 1; i < bucket.size(); ++i) { 33 | float key = bucket[i]; 34 | int j = i - 1; 35 | while (j >= 0 && bucket[j] > key) { 36 | bucket[j + 1] = bucket[j]; 37 | j--; 38 | } 39 | bucket[j + 1] = key; 40 | } 41 | } 42 | 43 | void BucketSort(vector& arr, int num_buckets) 44 | { 45 | vector> buckets(num_buckets); 46 | 47 | // TODO: 48 | 49 | cout << "Before sorting" << endl; 50 | PrintBuckets(buckets); 51 | 52 | // TODO: 53 | 54 | cout << "After sorting" << endl; 55 | PrintBuckets(buckets); 56 | 57 | // TODO: 58 | } 59 | 60 | int main() 61 | { 62 | vector arr = { 0.78f, 0.17f, 0.39f, 0.26f, 0.72f, 0.94f, 0.21f, 0.12f, 0.23f, 0.67f }; 63 | 64 | Print(arr); 65 | 66 | BucketSort(arr, 10); 67 | 68 | Print(arr); 69 | 70 | return 0; 71 | } -------------------------------------------------------------------------------- /VSCode/Ex0802_UnorderedMap/Ex0802_UnorderedMap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include // map 11 | #include // unordered_map 12 | using namespace std; 13 | 14 | template 15 | void Print(const unordered_map& map) 16 | { 17 | for (int i = 0; i < map.bucket_count(); i++) // 버킷에 대해 반복 18 | { 19 | auto b = map.bucket(i); 20 | cout << i << ": "; 21 | for (auto i = map.begin(b); i != map.end(b); i++) // 버킷에 저장된 것들 출력 22 | cout << "(" << i->first << ", " << i->second << ")->"; 23 | cout << endl; 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | // 기본적인 사용 방법 30 | { 31 | //unordered_map map; 32 | map map; 33 | 34 | // 새로운 키-값 추가 35 | map.insert({ "Orange", 1 }); 36 | map.insert({ "Apple", 10 }); 37 | map.insert({ "Strawberry", 7 }); 38 | 39 | // 새로운 키-값 추가(배열처럼 인덱싱 연산자 사용) 40 | map["Kiwi"] = 5; // map.insert({"Kiwi", 5}); 41 | 42 | // 값 변경 43 | map.find("Kiwi")->second += 1; // 이터레이터 사용 44 | map["Kiwi"] += 1; // 인덱싱(더 편리) 45 | 46 | cout << map.count("Apple") << endl; // 1 아니면 0 반환 (중복허용X) 47 | 48 | // map은 내부적으로 정렬된 순서 유지 (unordered_map과 출력 순서가 다를 수 있음) 49 | for (auto i : map) 50 | cout << i.first << " " << i.second << endl; 51 | } 52 | 53 | // 난수 생성기 54 | random_device rd; 55 | mt19937 g(rd()); 56 | uniform_int_distribution dist(1, 365); 57 | 58 | // 모인 인원 수 59 | int num_people = 23; 60 | 61 | std::unordered_map map(num_people); // 버킷 수를 스스로 조절 62 | 63 | int num_try = 1000; 64 | int all_samebirthday_count = 0; 65 | 66 | for (int t = 0; t < num_try; t++) 67 | { 68 | int samebirthday_count = 0; 69 | 70 | for (int i = 0; i < num_people; i++) 71 | { 72 | int birthday = dist(g); 73 | 74 | // TODO: 75 | } 76 | 77 | if (samebirthday_count > 0) 78 | all_samebirthday_count += 1; 79 | 80 | //Print(map); // 디버깅용 81 | //exit(0); 82 | 83 | map.clear(); 84 | } 85 | 86 | std::cout << (all_samebirthday_count * 100.0 / num_try) << " % " << endl; 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /VSCode/Ex0803_RomanNumeral/Ex0803_RomanNumeral.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // LeetCode: Roman to Integer 7 | // https://leetcode.com/problems/roman-to-integer/description/ 8 | 9 | int RomanToInt(string s) 10 | { 11 | unordered_map m; 12 | 13 | m['I'] = 1; 14 | m['V'] = 5; 15 | m['X'] = 10; 16 | m['L'] = 50; 17 | m['C'] = 100; 18 | m['D'] = 500; 19 | m['M'] = 1000; 20 | 21 | int ans = 0; 22 | 23 | for (int i = 0; i < s.length(); i++) 24 | { 25 | // TODO: 26 | } 27 | 28 | cout << s << " = " << ans << endl; 29 | 30 | return ans; 31 | } 32 | 33 | int main() 34 | { 35 | RomanToInt("II"); 36 | 37 | RomanToInt("III"); 38 | 39 | RomanToInt("XII"); 40 | 41 | RomanToInt("XXVII"); 42 | 43 | RomanToInt("IV"); 44 | 45 | RomanToInt("IX"); 46 | 47 | RomanToInt("XL"); 48 | 49 | RomanToInt("XC"); 50 | 51 | RomanToInt("CD"); 52 | 53 | RomanToInt("CM"); 54 | 55 | RomanToInt("LVIII"); 56 | 57 | RomanToInt("MCMXCIV"); 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /VSCode/Ex0905_SymbolGraph/Ex0905_SymbolGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Vertex 8 | { 9 | Vertex(string k, int i) 10 | { 11 | key = k; 12 | index = i; 13 | } 14 | 15 | string key = ""; 16 | int index = -1; // 이 Vertex의 포인터가 저장된 vertices 배열의 인덱스 17 | bool visited = false; 18 | 19 | vector out_neighbors; 20 | }; 21 | 22 | class SymbolGraph 23 | { 24 | public: 25 | SymbolGraph(vector keys) 26 | { 27 | table.clear(); 28 | vertices.clear(); 29 | vertices.reserve(keys.size()); 30 | 31 | // TODO: vertices와 table 초기화 32 | 33 | // 확인용 34 | for (auto v : vertices) 35 | cout << v->key << " " << v->index << endl; 36 | for (auto i : table) 37 | cout << i.first << " " << i.second << endl; 38 | } 39 | 40 | ~SymbolGraph() 41 | { 42 | for (auto* v : vertices) 43 | delete v; 44 | } 45 | 46 | void AddDiEdge(string kv, string kw) 47 | { 48 | // TODO: table 이용 49 | } 50 | 51 | void AddDiEdge(int v, int w) // 단방향 간선 52 | { 53 | vertices[v]->out_neighbors.push_back(vertices[w]); 54 | } 55 | 56 | void DFS(string k) 57 | { 58 | // TODO: table 이용 59 | } 60 | 61 | void DFS(int source) 62 | { 63 | for (auto* v : this->vertices) 64 | v->visited = false; 65 | DFS(vertices[source]); 66 | cout << endl; 67 | } 68 | 69 | void DFS(Vertex* source) 70 | { 71 | source->visited = true; 72 | 73 | // Preorder 74 | // cout << source->key << " "; 75 | 76 | for (auto* w : source->out_neighbors) 77 | if (!w->visited) 78 | DFS(w); 79 | 80 | // Postorder 81 | cout << source->key << " "; 82 | } 83 | 84 | private: 85 | vector vertices; 86 | 87 | unordered_map table; // key -> index 88 | }; 89 | 90 | int main() 91 | { 92 | SymbolGraph g({ "A", "B", "C", "D", "E", "F", "G", "H", "I" }); 93 | 94 | g.AddDiEdge("F", "B"); 95 | g.AddDiEdge("F", "G"); 96 | g.AddDiEdge("B", "A"); 97 | g.AddDiEdge("B", "D"); 98 | g.AddDiEdge("D", "C"); 99 | g.AddDiEdge("D", "E"); 100 | g.AddDiEdge("G", "I"); 101 | g.AddDiEdge("I", "H"); 102 | 103 | g.DFS("F"); 104 | 105 | return 0; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /VSCode/Ex0908_TracingDFS/Ex0908_TracingDFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // Vertex에는 용도에 따라서 int 외에 string 같은 다른 정보들도 저장할 수 있습니다. 8 | // 삽입/삭제가 많으면 list, 접근(읽기/쓰기)이 많으면 vector 권장 9 | 10 | struct Vertex 11 | { 12 | Vertex(int v) { value = v; } 13 | 14 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 15 | bool visited = false; 16 | 17 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 18 | }; 19 | 20 | class Graph 21 | { 22 | public: 23 | Graph(int num_vertices) 24 | { 25 | vertices.resize(num_vertices); 26 | for (int i = 0; i < num_vertices; i++) 27 | vertices[i] = new Vertex(i); 28 | } 29 | 30 | ~Graph() 31 | { 32 | for (auto* v : vertices) 33 | delete v; 34 | } 35 | 36 | void AddDiEdge(int v, int w) // 단방향 간선 37 | { 38 | vertices[v]->out_neighbors.push_back(vertices[w]); 39 | } 40 | 41 | void AddBiEdge(int v, int w) // 양방향 간선 42 | { 43 | vertices[v]->out_neighbors.push_back(vertices[w]); 44 | vertices[w]->out_neighbors.push_back(vertices[v]); 45 | } 46 | 47 | void DFS(int source) 48 | { 49 | for (auto* v : this->vertices) 50 | v->visited = false; 51 | 52 | current_time = 0; 53 | DFS(vertices[source], 0); 54 | } 55 | 56 | void DFS(Vertex* source, int level) 57 | { 58 | current_time += 1; 59 | cout << setw(2) << current_time << ": "; 60 | cout << string(2 * level, ' '); // 출력탭 61 | cout << "DFS(" << source->value << ")" << endl; 62 | 63 | source->visited = true; 64 | for (auto* w : source->out_neighbors) 65 | if (!w->visited) 66 | DFS(w, level + 1); 67 | 68 | current_time += 1; 69 | cout << setw(2) << current_time << ": "; 70 | cout << string(2 * level, ' '); // 출력탭 71 | cout << source->value << " done" << endl; 72 | } 73 | 74 | private: 75 | vector vertices; 76 | int current_time = 0; // 실행 순서 추적용 77 | 78 | void PrintPath(vector path) 79 | { 80 | for (auto& v : path) { 81 | cout << v->value; 82 | if (&v != &path.back()) 83 | cout << " -> "; 84 | } 85 | cout << endl; 86 | } 87 | }; 88 | 89 | int main() 90 | { 91 | // 한 경로 안에서 한 번 방문한 정점은 다시 방문하지 않는다. 92 | 93 | // 간단한 경우 94 | { 95 | // 0: 애피타이저 96 | // 1: 메인요리 97 | // 2: 디저트 98 | 99 | Graph g(3); 100 | g.AddDiEdge(0, 1); // 애피타이저 -> 메인요리 101 | g.AddDiEdge(1, 2); // 메인요리 -> 디저트 102 | g.AddDiEdge(0, 2); // 애피타이저 -> 디저트 103 | 104 | g.DFS(0); 105 | } 106 | 107 | // Sedgewick Algorithm 4.1 p.536 (조금 달라요) 108 | { 109 | Graph g(6); 110 | 111 | g.AddDiEdge(0, 2); 112 | g.AddDiEdge(2, 1); 113 | g.AddDiEdge(2, 3); 114 | g.AddDiEdge(3, 4); 115 | g.AddDiEdge(1, 5); 116 | g.AddDiEdge(2, 4); 117 | g.AddBiEdge(3, 5); // 주의: 양방향 간선 118 | 119 | g.DFS(2); 120 | } 121 | 122 | return 0; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /VSCode/Ex1001_ConnectedComponents/Ex1001_ConnectedComponents.cpp: -------------------------------------------------------------------------------- 1 |  2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Vertex 9 | { 10 | Vertex(int v) { value = v; } 11 | 12 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 13 | bool visited = false; 14 | 15 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 16 | }; 17 | 18 | class Graph 19 | { 20 | public: 21 | Graph(int num_vertices) 22 | { 23 | vertices.resize(num_vertices); 24 | for (int i = 0; i < num_vertices; i++) 25 | vertices[i] = new Vertex(i); 26 | } 27 | 28 | ~Graph() 29 | { 30 | for (auto* v : vertices) 31 | delete v; 32 | } 33 | 34 | //void AddDiEdge(int v, int w) // 단방향 간선 35 | //{ 36 | // vertices[v]->out_neighbors.push_back(vertices[w]); 37 | //} 38 | 39 | void AddBiEdge(int v, int w) // 양방향 간선 40 | { 41 | vertices[v]->out_neighbors.push_back(vertices[w]); 42 | vertices[w]->out_neighbors.push_back(vertices[v]); 43 | } 44 | 45 | void DFS(Vertex* v) 46 | { 47 | // TODO: 48 | } 49 | 50 | void ConnectedComponents() 51 | { 52 | count = 0; 53 | id.resize(vertices.size(), -1); 54 | 55 | // TODO: 56 | 57 | // 결과 정리 후 출력 58 | //vector> components(count); 59 | //for (int s = 0; s < vertices.size(); s++) 60 | // components[id[s]].push_back(s); 61 | //cout << count << " components" << endl; 62 | //for (int i = 0; i < components.size(); i++) 63 | //{ 64 | // cout << "Component " << i + 1 << ": "; 65 | // for (auto v : components[i]) 66 | // cout << v << " "; 67 | // cout << endl; 68 | //} 69 | } 70 | 71 | private: 72 | vector vertices; 73 | vector id; 74 | int count = 0; 75 | }; 76 | 77 | 78 | int main() 79 | { 80 | // Sedgewick p544 81 | // 무방향(양방향) 그래프 82 | vector> edges = { {0, 5}, {4, 3}, {0, 1}, 83 | {9, 12}, {6, 4}, {5, 4}, {0, 2}, {11, 12}, {9, 10}, 84 | {0, 6}, {7, 8}, {9, 11}, {5, 3} }; 85 | 86 | Graph g(13); 87 | 88 | for (vector& p : edges) 89 | g.AddBiEdge(p[0], p[1]); 90 | 91 | g.ConnectedComponents(); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /VSCode/Ex1002_StrongComponents(BruteForce)/Ex1002_StrongComponents(BruteForce).cpp: -------------------------------------------------------------------------------- 1 |  2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct Vertex 9 | { 10 | Vertex(int v) { value = v; } 11 | 12 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 13 | bool visited = false; 14 | 15 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 16 | vector in_neighbors; // 들어오는 방향의 이웃 vertex들에 대한 포인터 17 | }; 18 | 19 | class Graph 20 | { 21 | public: 22 | Graph(int num_vertices) 23 | { 24 | vertices.resize(num_vertices); 25 | for (int i = 0; i < num_vertices; i++) 26 | vertices[i] = new Vertex(i); 27 | } 28 | 29 | ~Graph() 30 | { 31 | for (auto* v : vertices) 32 | delete v; 33 | } 34 | 35 | void AddDiEdge(int v, int w) // 단방향 간선 36 | { 37 | vertices[v]->out_neighbors.push_back(vertices[w]); 38 | vertices[w]->in_neighbors.push_back(vertices[v]); 39 | } 40 | 41 | bool HasPath(int start, int target) 42 | { 43 | for (auto* v : vertices) 44 | v->visited = false; 45 | return HasPathHelper(vertices[start], vertices[target]); 46 | } 47 | 48 | void BruteForceStrongComponents() 49 | { 50 | int count = 0; 51 | vector id(vertices.size(), -1); 52 | 53 | // TODO: HasPath()를 이용해서 서로 강하게 연결된 요소들을 찾습니다. 54 | 55 | // 결과 정리 후 출력 56 | //vector> components(count); 57 | //for (int s = 0; s < vertices.size(); s++) 58 | // components[id[s]].push_back(s); 59 | //cout << count << " strong components" << endl; 60 | //for (int i = 0; i < components.size(); i++) 61 | //{ 62 | // cout << "Strong component " << i + 1 << ": "; 63 | // for (auto v : components[i]) 64 | // cout << v << " "; 65 | // cout << endl; 66 | //} 67 | } 68 | 69 | private: 70 | vector vertices; 71 | 72 | bool HasPathHelper(Vertex* v, Vertex* t) 73 | { 74 | // TODO: DFS 방식으로 v와 t가 만날 수 있는 지를 확인합니다. 75 | 76 | return false; 77 | } 78 | }; 79 | 80 | int main() 81 | { 82 | // Sedgewick p569 83 | // 방향(directed) 그래프 84 | vector> edges = { 85 | {4, 2}, {2, 3}, {3, 2}, {6, 0}, {0, 1}, {2, 0}, {11, 12}, {12, 9}, {9, 10}, 86 | {9, 11}, {7, 9}, {10, 12}, {11, 4}, {4, 3}, {3, 5}, {6, 8}, {8, 6}, {5, 4}, 87 | {0, 5}, {6, 4}, {6, 9}, {7, 6} }; 88 | 89 | Graph g(13); 90 | 91 | for (vector& p : edges) 92 | g.AddDiEdge(p[0], p[1]); 93 | 94 | g.BruteForceStrongComponents(); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /VSCode/Ex1101_PriorityQueue/Ex1101_PriorityQueue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | // C++ 우선순위큐 std::priority_queue 사용법 8 | 9 | // 기본 설정은 큰 값의 우선순위가 높은 max queue 10 | { 11 | priority_queue max_queue; // double값들을 저장하는 우선순위큐 12 | 13 | for (double v : vector{ 3.5, 2.4, 8.3, 9.9, 1.2, 3.9 }) 14 | max_queue.push(v); // 추가 15 | 16 | // 큰 값부터 출력됩니다. 17 | while (!max_queue.empty()) 18 | { 19 | cout << max_queue.top() << " "; 20 | max_queue.pop(); 21 | } 22 | cout << endl; 23 | } 24 | 25 | // 작은 값의 우선순위가 높은 min queue 26 | { 27 | priority_queue, greater> min_queue; 28 | 29 | // 위에서 double은 저장될 자료형 30 | // vector은 pq에서 내부적으로 사용할 컨테이너 31 | // greater는 우선순위를 결정할 때 사용할 비교 32 | // greater대신에 less을 사용하면 max queue 33 | // https://en.cppreference.com/w/cpp/container/priority_queue 34 | // 아래 예제코드에 min priority queue 부분 참고 35 | // std::greater makes the max priority queue act as a min priority queue 36 | 37 | for (auto v : vector{ 3.5, 2.4, 8.3, 9.9, 1.2, 3.9 }) 38 | min_queue.push(v); 39 | 40 | // 작은 값부터 출력 41 | while (!min_queue.empty()) 42 | { 43 | cout << min_queue.top() << " "; 44 | min_queue.pop(); 45 | } 46 | cout << endl; 47 | } 48 | 49 | // 우선순위큐에 std::pair 저장 50 | // double형 변수 하나와 int형 변수 하나를 묶어 놓은 쌍(pair) 51 | // 중복 저장 가능: {3.5, 1}이 여러 번 저장됩니다. 52 | { 53 | priority_queue, vector>, greater>> pq; 54 | 55 | for (pair v : vector>{ {3.5, 3}, {8.3, 1}, {3.5, 1}, {3.5, 2}, {2.4, 8}, {8.3, 5}, {3.5, 1}, {3.5, 1} }) 56 | pq.push(v); 57 | 58 | // pair에서 double값이 같으면 int값이 작은 쪽 먼저 출력 59 | while (!pq.empty()) 60 | { 61 | cout << "(" << pq.top().first << ", " << pq.top().second << ") "; 62 | // first: pair에서 첫 번째(여기서는 double형) 63 | // second: pair에서 두 번째(여기서는 int) 64 | 65 | pq.pop(); 66 | } 67 | cout << endl; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /VSCode/Ex1102_IndexMinPQ/Ex1102_IndexMinPQ.cpp: -------------------------------------------------------------------------------- 1 | #include "IndexMinPQ.h" 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | IndexMinPQ pq(10); 8 | 9 | for (pair p : vector>{ {3.5, 3}, {8.3, 1}, {1.5, 1}, {1.6, 3}, {0.5, 8}, {0.1, 5} }) 10 | { 11 | if (!pq.Contains(p.second)) pq.Insert(p.second, p.first); 12 | else pq.ChangeKey(p.second, p.first); 13 | 14 | pq.Print(); 15 | } 16 | 17 | while (!pq.Empty()) 18 | { 19 | cout << "(" << pq.MinKey() << ", " << pq.MinIndex() << ") "; 20 | 21 | pq.DelMin(); 22 | } 23 | cout << endl; 24 | } 25 | -------------------------------------------------------------------------------- /VSCode/Ex1201_Fibonacci/Ex1201_Fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int RecurFibonacci(int n) 7 | { 8 | cout << "RecurFibonacci(" << setw(2) << n << ")" << endl; 9 | 10 | if (n == 0) return 0; 11 | if (n == 1) return 1; 12 | 13 | return RecurFibonacci(n - 2) + RecurFibonacci(n - 1); 14 | } 15 | 16 | // 메모에 vector 대신에 unordered_map을 사용하는 경우도 있습니다. 17 | int MemoizedTopDownFibonacciHelper(int n, std::vector& memo) 18 | { 19 | // TODO: 20 | 21 | for (auto& t : memo) cout << setw(4) << t; cout << endl; 22 | 23 | return memo[n]; 24 | } 25 | 26 | int MemoizedTopDownFibonacci(int n) 27 | { 28 | vector memo(n + 1, -1); // -1로 초기화 29 | memo[0] = 0; 30 | memo[1] = 1; 31 | 32 | return MemoizedTopDownFibonacciHelper(n, memo); 33 | } 34 | 35 | int BottomUpFibonacciTabulation(int n) 36 | { 37 | if (n == 0) return 0; 38 | if (n == 1) return 1; 39 | 40 | vector table(n + 1, -1); 41 | table[0] = 0; 42 | table[1] = 1; 43 | 44 | // for ( TODO ) 45 | { 46 | // TODO: 47 | 48 | for (auto& t : table) cout << setw(4) << t; cout << endl; 49 | } 50 | 51 | return table[n]; // The N-th Fibonacci number 52 | } 53 | 54 | // 재미로 배열 없이 구현해보기 55 | int BottomUpFibonacci(int n) 56 | { 57 | if (n == 0 || n == 1) 58 | return n; 59 | 60 | int a = 0; 61 | int b = 1; 62 | 63 | // TODO: 64 | 65 | return b; // The N-th Fibonacci number 66 | } 67 | 68 | int main() 69 | { 70 | int n = 7; // 숫자가 크면 단순 재귀 버전은 많이 느립니다. 71 | 72 | cout << RecurFibonacci(n) << endl; 73 | 74 | cout << MemoizedTopDownFibonacci(n) << endl; 75 | 76 | cout << BottomUpFibonacciTabulation(n) << endl; 77 | 78 | cout << BottomUpFibonacci(n) << endl; 79 | 80 | return 0; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /VSCode/Ex1202_RodCutting/Ex1202_RodCutting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // CLRS 4판 14.1 Rod Cutting 8 | 9 | int RecurCutRod(const vector& prices, int length) 10 | { 11 | if (length == 0) 12 | return 0; // return length* prices[0]; 13 | 14 | int max_price = numeric_limits::min(); 15 | 16 | for (int i = 1; i <= length; i++) 17 | { 18 | // TODO: 19 | } 20 | 21 | return max_price; 22 | } 23 | 24 | int MemoizedCutRodHelper(const vector& prices, int length, vector& memo) 25 | { 26 | if (memo[length] >= 0) 27 | return memo[length]; 28 | 29 | // TODO: 30 | 31 | for (auto& t : memo) cout << setw(3) << t; cout << endl; 32 | 33 | return memo[length]; 34 | } 35 | 36 | int MemoizedCutRod(const vector& prices, int length) 37 | { 38 | vector memo(length + 1, -1); 39 | memo[0] = 0; 40 | 41 | return MemoizedCutRodHelper(prices, length, memo); 42 | } 43 | 44 | int BottomUpCutRod(const vector& prices, int length) 45 | { 46 | vector table(length + 1, -1); // 가격은 음수가 될 수 없으니까 디버깅 편의를 위해 -1로 초기화 47 | table[0] = 0; // length* prices[0]; 48 | 49 | for (int j = 1; j <= length; j++) 50 | { 51 | int max_price = numeric_limits::min(); 52 | 53 | // TODO: 54 | 55 | for (auto& t : table) cout << setw(3) << t; cout << endl; 56 | } 57 | 58 | return table[length]; 59 | } 60 | 61 | // 어떻게 자르는지까지 출력하는 버전 (실행 예시 참고) 62 | int ExtendedBottomUpCutRod(const vector& prices, int length) 63 | { 64 | vector table(length + 1, -1); // 가격은 음수가 될 수 없으니까 디버깅 편의를 위해 -1로 초기화 65 | table[0] = 0; // length* prices[0]; 66 | 67 | // TODO: 68 | 69 | return table[length]; 70 | } 71 | 72 | int main() 73 | { 74 | // Length: 0 1 2 3 4 5 6 7 8 9 10 75 | vector price_table = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 }; 76 | //vector price_table = { 0, 3, 5, 8, 9, 10, 17, 17, 20, 24, 30 }; 77 | 78 | // 주의: price_table은 문제에서 주어진 조건입니다. 메모가 아닙니다. 79 | 80 | cout << "Naive recursion" << endl; 81 | for (int length = 0; length < price_table.size(); length++) 82 | { 83 | int revenue = RecurCutRod(price_table, length); 84 | cout << "Optimal revenue for length " << length << ": " << revenue << endl; 85 | } 86 | cout << endl; 87 | 88 | cout << "TopDown with Memoization" << endl; 89 | cout << "Optimal revenue for length " << 10 << ": " << MemoizedCutRod(price_table, 10) << endl; 90 | cout << endl; 91 | 92 | cout << "BottomUpTabulation" << endl; 93 | cout << "Optimal revenue for length " << 10 << ": " << BottomUpCutRod(price_table, 10) << endl; 94 | cout << endl; 95 | 96 | for (int length = 0; length < price_table.size(); length++) 97 | { 98 | cout << "Length: " << length << endl; 99 | int revenue = ExtendedBottomUpCutRod(price_table, length); 100 | cout << "Optimal revenue: " << revenue << endl; 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /VSCode/Ex1203_BellmanFord/Ex1203_BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | void Print(vector& dist) 10 | { 11 | for (int i = 0; i < dist.size(); i++) 12 | cout << setw(6) << dist[i]; 13 | cout << endl; 14 | } 15 | 16 | void PrintPathHelper(vector& prev, int j) 17 | { 18 | // TODO: 19 | } 20 | 21 | void PrintPaths(vector& prev) 22 | { 23 | for (int j = 0; j < prev.size(); j++) 24 | { 25 | PrintPathHelper(prev, j); 26 | cout << endl; 27 | } 28 | } 29 | 30 | struct Edge 31 | { 32 | int v, w; 33 | double weight; 34 | }; 35 | 36 | int main() 37 | { 38 | constexpr double kInf = numeric_limits::infinity(); 39 | 40 | // CLRS p.621 (다익스트라 예제와 같음) 41 | //vector edges = { 42 | //{0, 1, 10.0}, 43 | //{0, 3, 5.0}, 44 | //{1, 2, 1.0}, 45 | //{1, 3, 2.0}, 46 | //{2, 4, 4.0}, 47 | //{3, 1, 3.0}, 48 | //{3, 2, 9.0}, 49 | //{3, 4, 2.0}, 50 | //{4, 0, 7.0}, 51 | //{4, 2, 6.0}, 52 | //}; 53 | //int V = 5; // number of vertices 54 | 55 | // 간선이 왼쪽에서 오른쪽 방향일 경우 56 | vector edges = { 57 | {0, 1, 1.0}, // A->B 1 58 | {1, 2, 5.0}, 59 | {1, 3, 4.0}, 60 | {2, 3, -3.0}, 61 | {3, 4, 1.0}, 62 | {4, 3, -100.0} // 음의 싸이클이 추가된 경우 63 | }; 64 | int V = 5; // number of vertices 65 | 66 | //std::reverse(edges.begin(), edges.end()); // 간선 순서 뒤집어서 해보기 67 | 68 | // 간선 순서는 CLRS p613 예시 순서 69 | //vector edges = { 70 | // {1, 2, 5.0}, 71 | // {1, 3, 8.0}, 72 | // {1, 4, -4.0}, 73 | // {2, 1, -2.0}, 74 | // {3, 2, -3.0}, 75 | // {3, 4, 9.0}, 76 | // {4, 2, 7.0}, 77 | // {4, 0, 2.0}, 78 | // {0, 1, 6.0}, 79 | // {0, 3, 7.0}, 80 | //}; 81 | //int V = 5; // number of vertices 82 | 83 | int E = int(edges.size()); // number of edges 84 | 85 | vector dist(V, kInf); 86 | vector prev(V, -1); 87 | 88 | int s = 0; // 시작 정점의 인덱스 89 | dist[s] = 0.0; 90 | 91 | Print(dist); 92 | 93 | for (int v = 1; v < V; v++) 94 | { 95 | for (auto e : edges) 96 | { 97 | // TODO: 98 | } 99 | 100 | Print(dist); 101 | } 102 | 103 | // 참고: infinity() 비교 연산 104 | // cout << bool(numeric_limits::infinity() + 100 > numeric_limits::infinity()) << endl; // 0 false 105 | // cout << bool(numeric_limits::infinity() + 100 < numeric_limits::infinity()) << endl; // 0 false 106 | // cout << bool(numeric_limits::infinity() + 100 == numeric_limits::infinity()) << endl; // 1 true 107 | // https://en.wikipedia.org/wiki/IEEE_754 부동소수점 표준에 따르면 수학적 정의와 동일하게 무한대 더하기 무한대는 무한대입니다. 108 | 109 | for (auto e : edges) 110 | { 111 | // if ( TODO ) 112 | { 113 | cout << "Negative cycle was found." << endl; 114 | return -1; 115 | } 116 | } 117 | 118 | cout << "Negative cycle was not found." << endl; 119 | 120 | PrintPaths(prev); 121 | 122 | return 0; 123 | } -------------------------------------------------------------------------------- /VSCode/Ex1204_Arbitrage/Ex1204_Arbitrage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | template 11 | void Print(vector& dist) 12 | { 13 | for (int i = 0; i < dist.size(); i++) 14 | cout << setw(10) << dist[i]; 15 | cout << endl; 16 | } 17 | 18 | struct Edge 19 | { 20 | int v, w; 21 | double weight; 22 | }; 23 | 24 | int main() 25 | { 26 | constexpr double kInf = numeric_limits::infinity(); 27 | 28 | // Sedgewick p. 679 29 | vector> rates = { 30 | /* USD EUR GBP CHF CAD */ 31 | /*USD*/ { 1.0, 0.741, 0.657, 1.061, 1.005}, 32 | /*EUR*/ {1.349, 1.0, 0.888, 1.433, 1.366}, 33 | /*GBP*/ {1.521, 1.126, 1.0, 1.614, 1.538}, 34 | /*CHF*/ {0.942, 0.698, 0.619, 1.0, 0.953}, 35 | /*CAD*/ {0.995, 0.732, 0.650, 1.049, 1.0} 36 | }; 37 | 38 | int V = 5; 39 | 40 | vector edges; 41 | for (int i = 0; i < V; i++) 42 | for (int j = 0; j < V; j++) 43 | { 44 | if (i != j) 45 | edges.push_back({ i, j, rates[i][j] }); 46 | } 47 | 48 | // reverse(edges.begin(), edges.end()); 49 | 50 | int E = int(edges.size()); // number of edges 51 | 52 | vector dist(V, -kInf); 53 | vector prev(V, -1); 54 | 55 | int s = 0; // 시작 정점의 인덱스 56 | dist[s] = 1.0; 57 | 58 | Print(dist); 59 | 60 | for (int v = 1; v < V; v++) 61 | { 62 | for (auto e : edges) 63 | { 64 | // TODO: 65 | } 66 | 67 | Print(dist); 68 | } 69 | 70 | for (auto e : edges) 71 | { 72 | if (dist[e.w] < dist[e.v] * e.weight) 73 | { 74 | cout << "Arbitrage opportunity was found." << endl; 75 | prev[e.w] = e.v; 76 | 77 | // TODO: 78 | 79 | exit(0); 80 | } 81 | } 82 | 83 | cout << "Arbitrage opportunity was not found." << endl; 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /VSCode/Ex1304_LargestIndependentSet/Ex1304_LargestIndependentSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | public: 10 | int value = 0; 11 | int memo = 0; // <- Memoization에 사용 12 | Node* left = nullptr; 13 | Node* right = nullptr; 14 | 15 | // 꼭 이진 트리가 아니라 싸이클이 없는 트리 구조면 다 가능합니다. 16 | }; 17 | 18 | int RecurLIS(Node* root) 19 | { 20 | if (root == nullptr) 21 | return 0; 22 | 23 | // Root 노드가 포함 되지 않는 경우: 자식들 포함 가능 24 | int case1 = RecurLIS(root->left) + RecurLIS(root->right); 25 | 26 | // Root 노드가 포함되는 경우는 하나 건너서 자식들의 자식들만 포함 가능합니다. 27 | int case2 = 1; 28 | if (root->left) 29 | case2 += RecurLIS(root->left->left) + RecurLIS(root->left->right); 30 | if (root->right) 31 | case2 += RecurLIS(root->right->left) + RecurLIS(root->right->right); 32 | 33 | // 두 가지 경우 중 큰 경우 반환 34 | return max(case1, case2); 35 | } 36 | 37 | int MemoLIS(Node* root) 38 | { 39 | // TODO: 40 | 41 | return 0; 42 | } 43 | 44 | Node* MakeNode(int data) 45 | { 46 | Node* temp = new Node(); 47 | temp->value = data; 48 | temp->left = temp->right = nullptr; 49 | return temp; 50 | } 51 | 52 | int main() 53 | { 54 | // 이진 트리 만들기 55 | Node* root = MakeNode(1); 56 | root->left = MakeNode(2); 57 | root->left->left = MakeNode(4); 58 | root->left->right = MakeNode(5); 59 | root->left->right->left = MakeNode(7); 60 | root->left->right->right = MakeNode(8); 61 | root->right = MakeNode(3); 62 | root->right->right = MakeNode(6); 63 | 64 | cout << RecurLIS(root) << endl; 65 | cout << MemoLIS(root) << endl; 66 | 67 | return 0; 68 | } 69 | 70 | // GeeksForGeeks 예제를 약간 변형하였습니다. 71 | // https://www.geeksforgeeks.org/largest-independent-set-problem-using-dynamic-programming/ 72 | -------------------------------------------------------------------------------- /VSCode/Ex1401_FractionalKnapsack/Ex1401_FractionalKnapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Item 8 | { 9 | double value; 10 | double weight; 11 | }; 12 | 13 | void Print(vector& items) 14 | { 15 | for (auto i : items) 16 | { 17 | // (가성비 = value/weight = ratio, value, weight) 18 | cout << "(" << i.value / i.weight << ", " << i.value << ", " << i.weight << ") "; 19 | } 20 | cout << endl; 21 | } 22 | 23 | bool Compare(struct Item a, struct Item b) 24 | { 25 | double ratio_a = a.value / a.weight; 26 | double ratio_b = b.value / b.weight; 27 | 28 | return ratio_a > ratio_b; // ratio가 큰 쪽이 앞으로 오도록 정렬 29 | } 30 | 31 | double FractionalKnapsack(vector items, double W) 32 | { 33 | sort(items.begin(), items.end(), Compare); // Compare() 함수를 이용해서 정렬 34 | 35 | cout << "W = " << W << endl; 36 | Print(items); 37 | 38 | double vsum = 0.0; 39 | 40 | for (auto& i : items) 41 | { 42 | // TODO: 43 | } 44 | 45 | return vsum; 46 | } 47 | 48 | int main() 49 | { 50 | double W = 6.0; 51 | 52 | vector items = { { 10, 1 }, { 28, 4 }, { 12, 2 }, { 12, 3 } }; 53 | 54 | cout << FractionalKnapsack(items, W) << endl; 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /VSCode/Ex1402_ActivitySelection/Ex1402_ActivitySelection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Activity 7 | { 8 | int start; 9 | int end; 10 | }; 11 | 12 | bool Compare(struct Activity a, struct Activity b) 13 | { 14 | // TODO: 15 | return false; 16 | } 17 | 18 | void Print(vector& activities) 19 | { 20 | if (activities.empty()) 21 | { 22 | cout << "Empty." << endl; 23 | return; 24 | } 25 | 26 | vector temp(activities.size() * 2); 27 | memcpy(&temp[0], &activities[0], sizeof(int) * temp.size()); 28 | int min_time = *std::min_element(temp.begin(), temp.end()); 29 | int max_time = *std::max_element(temp.begin(), temp.end()); 30 | 31 | for (int i = min_time; i <= max_time; i++) 32 | cout << i % 10; 33 | cout << endl; 34 | for (auto a : activities) 35 | { 36 | for (int i = min_time; i <= max_time; i++) 37 | cout << (a.start <= i && i <= a.end ? "#" : " "); 38 | cout << " (" << a.start << ", " << a.end << ")" << endl; 39 | } 40 | cout << endl; 41 | } 42 | 43 | vector GreedyActivitySelection(vector& activities) 44 | { 45 | sort(activities.begin(), activities.end(), Compare); 46 | 47 | Print(activities); 48 | 49 | vector schedule; 50 | 51 | // TODO: 52 | 53 | return schedule; 54 | } 55 | 56 | int main() 57 | { 58 | vector activities = 59 | { {5, 7}, {2, 5}, {6, 13}, {1, 8}, { 6, 9 }, {3, 8}, {9, 11}, {5, 12}, {8, 10}, {1, 4}, {3, 6}, {8, 14}, {13, 15} }; 60 | 61 | Print(activities); 62 | 63 | auto schedule = GreedyActivitySelection(activities); 64 | 65 | cout << schedule.size() << " activities selected." << endl; 66 | Print(schedule); 67 | 68 | return 0; 69 | } 70 | 71 | // CS161 예제에서는 끝나는 시간이 포함이고 CLRS p.422에서는 half-open이라서 끝나는 시간 미포함입니다. 72 | // 여기서는 CS161 방식이 더 직관적이라서 그대로 사용하였습니다. 예) {5, 12}이면 12도 활동 시간에 포함 -------------------------------------------------------------------------------- /VSCode/Ex1403_HuffmanCoding/Ex1403_HuffmanCoding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | string data; // char보다 디버깅 편리 10 | int freq; 11 | Node* left = nullptr; 12 | Node* right = nullptr; 13 | }; 14 | 15 | // std::priority_queue에서 사용할 MinHeapNode의 비교 16 | struct Compare 17 | { 18 | bool operator()(Node* l, Node* r) 19 | { 20 | // TODO: 21 | return false; 22 | } 23 | }; 24 | 25 | void PrintCodes(Node* root, string str) 26 | { 27 | if (!root) 28 | return; 29 | 30 | if (!root->left && !root->right) // left node이면 출력 31 | cout << root->data << ": " << str << "\n"; 32 | 33 | PrintCodes(root->left, str + "0"); 34 | PrintCodes(root->right, str + "1"); 35 | } 36 | 37 | void HuffmanCoding(vector data, vector freq) 38 | { 39 | // freq가 작을 수록 우선순위가 높은 힙 40 | // struct Compare에서 우선순위 비교 41 | priority_queue, Compare> heap; 42 | 43 | for (int i = 0; i < data.size(); ++i) 44 | heap.push(new Node{ string(1, data[i]), freq[i] }); 45 | 46 | /* 47 | while (heap.size() != 1) 48 | { 49 | Node* left, * right, * top; 50 | 51 | // TODO: 52 | 53 | cout << "(" << left->data << ", " << left->freq << ") + (" << right->data << ", " << right->freq << ") -> "; 54 | cout << "(" << top->data << ", " << top->freq << ")" << endl; 55 | } 56 | */ 57 | 58 | PrintCodes(heap.top(), ""); 59 | } 60 | 61 | int main() 62 | { 63 | vector data = { 'a', 'b', 'c', 'd', 'e', 'f' }; 64 | vector freq = { 45, 13, 12, 16, 9, 5 }; 65 | 66 | HuffmanCoding(data, freq); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /VSCode/Ex1501_PrimMST/Ex1501_PrimMST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../Ex1102_IndexMinPQ/IndexMinPQ.h" 5 | using namespace std; 6 | 7 | constexpr double kInf = numeric_limits::infinity(); 8 | 9 | struct DirectedEdge 10 | { 11 | int u; // 간선 시작(edge tail, 화살표 꼬리) 정점의 인덱스 12 | int v; // 간선 끝(edge head, 화살촉) 정점의 인덱스 13 | double weight; // edge weight (여기서는 u-v 이동 비용) 14 | }; 15 | 16 | class EdgeWeightedDigraph 17 | { 18 | public: 19 | vector> adj; 20 | 21 | EdgeWeightedDigraph(int num_vertices) 22 | { 23 | adj.resize(num_vertices); 24 | } 25 | 26 | void AddBiEdge(DirectedEdge e) // 양방향(무방향) 27 | { 28 | adj[e.u].push_back(e); 29 | adj[e.v].push_back({ e.v, e.u, e.weight }); 30 | } 31 | 32 | vector& Adj(int v) 33 | { 34 | return adj[v]; 35 | } 36 | 37 | void PrimMST() 38 | { 39 | int V = int(adj.size()); 40 | 41 | vector key(V, kInf); // dist in Sedgewick Algorithm 4.7, key in CLRS p. 596 42 | vector pre(V); // pi in CLRS 43 | 44 | double cost_sum = 0.0; 45 | 46 | key[0] = 0.0; 47 | pre[0] = -1; 48 | 49 | IndexMinPQ pq(V); 50 | 51 | // TODO: 우선순위큐에다가 일단 모든 정점의 인덱스를 넣는다. 52 | // 위에서 key[0] = 0.0 이기 때문에 0번이 가장 위로 온다. 53 | 54 | while (!pq.Empty()) 55 | { 56 | int u = pq.DelMin(); 57 | 58 | if (pre[u] >= 0) 59 | { 60 | cost_sum += key[u]; 61 | cout << pre[u] << " - " << u << " : " << key[u] << endl; 62 | } 63 | 64 | for (DirectedEdge& e : Adj(u)) 65 | { 66 | int v = e.v; 67 | double weight = e.weight; // u-v 간선 비용 68 | 69 | // if( TODO: v가 pq안에 아직 있는지 && u-v 비용이 더 적은지) 70 | //{ 71 | // pre[v] = u; 72 | // key[v] = weight; 73 | // pq.ChangeKey(v, weight); 74 | //} 75 | } 76 | } 77 | 78 | cout << cost_sum << endl; 79 | } 80 | }; 81 | 82 | int main() 83 | { 84 | vector edges = 85 | { 86 | { 0, 1, 4.0 }, 87 | { 0, 7, 9.0 }, 88 | { 1, 2, 8.0 }, 89 | { 1, 7, 11.0 }, 90 | { 2, 3, 7.0 }, 91 | { 2, 5, 4.0 }, 92 | { 2, 8, 2.0 }, 93 | { 3, 4, 9.0 }, 94 | { 3, 5, 14.0 }, 95 | { 4, 5, 10.0 }, 96 | { 5, 6, 2.0 }, 97 | { 6, 7, 1.0 }, 98 | { 6, 8, 6.0 }, 99 | { 7, 8, 7.0 }, 100 | }; 101 | 102 | EdgeWeightedDigraph g(9); 103 | 104 | for (auto e : edges) 105 | { 106 | g.AddBiEdge(e); 107 | } 108 | 109 | g.PrimMST(); 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /VSCode/Ex1502_UnionFind/Ex1502_UnionFind.cpp: -------------------------------------------------------------------------------- 1 | #include "UnionFind.h" 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | UnionFind uf(4); 8 | vector> tests = 9 | { 10 | {0, 1}, {1, 2}, {2, 3}, {3, 0} 11 | }; 12 | 13 | uf.Print(); 14 | 15 | for (auto t : tests) 16 | { 17 | int u = t.first; 18 | int v = t.second; 19 | bool connected = uf.Connected(u, v); // uf.Find(p) == uf.Find(q); 20 | 21 | cout << u << " " << v << " " << std::boolalpha << connected << endl; 22 | cout << "Union " << u << " " << v << endl; 23 | 24 | uf.Union(u, v); 25 | 26 | uf.Print(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /VSCode/Ex1502_UnionFind/UnionFind.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; // 편의용 8 | 9 | class UnionFind 10 | { 11 | public: 12 | vector group; 13 | int num_groups; 14 | 15 | UnionFind(int N) 16 | : group(N), num_groups(N) 17 | { 18 | for (int i = 0; i < group.size(); i++) 19 | group[i] = i; 20 | } 21 | 22 | int NumGroups() 23 | { 24 | return num_groups; 25 | } 26 | 27 | bool Connected(int p, int q) 28 | { 29 | return Find(p) == Find(q); 30 | } 31 | 32 | /* Quick-Find 방식: Union()에서 미리 정리하기 때문에 Find()는 빠름 */ 33 | int Find(int p) 34 | { 35 | return group[p]; 36 | } 37 | 38 | void Union(int p, int q) 39 | { 40 | int pid = Find(p); 41 | int qid = Find(q); 42 | 43 | if (pid == qid) return; 44 | 45 | for (int i = 0; i < group.size(); i++) 46 | { 47 | // TODO: 48 | } 49 | 50 | num_groups--; 51 | } 52 | 53 | /* Quick-Union 방식: Union()은 빠르고 Find()할 때 정리 */ 54 | /* 55 | int Find(int p) 56 | { 57 | while (p != group[p]) 58 | { 59 | // TODO: 60 | } 61 | 62 | return p; 63 | } 64 | 65 | void Union(int p, int q) 66 | { 67 | int i = Find(p); 68 | int j = Find(q); 69 | if (i == j) return; 70 | 71 | group[i] = j; 72 | 73 | num_groups--; 74 | } 75 | */ 76 | 77 | void Print() 78 | { 79 | cout << "Num groups = " << NumGroups() << endl; 80 | 81 | cout << "Index:"; 82 | for (int i = 0; i < group.size(); i++) 83 | cout << setw(3) << i; 84 | cout << endl; 85 | 86 | cout << "Group:"; 87 | for (auto i : group) 88 | cout << setw(3) << i; 89 | cout << endl; 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /VSCode/Ex1503_KruskalMST/Ex1503_KruskalMST.cpp: -------------------------------------------------------------------------------- 1 | #include "../Ex1502_UnionFind/UnionFind.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Edge 8 | { 9 | int u; // 한쪽 끝 10 | int v; // 다른쪽 끝 11 | double weight; 12 | 13 | // 정렬할 때 사용 14 | bool operator < (const Edge& other) const 15 | { 16 | return weight < other.weight; 17 | } 18 | }; 19 | 20 | void PrintEdges(vector& edges) 21 | { 22 | for (auto e : edges) 23 | cout << "(" << e.u << ", " << e.v << ", " << e.weight << ")" << endl; 24 | } 25 | 26 | int main() 27 | { 28 | // Kruskal 알고리듬에서는 간선만 사용하기 때문에 edges만 가지고 진행 29 | vector edges = 30 | { 31 | { 0, 1, 4.0 }, 32 | { 0, 7, 9.0 }, 33 | { 1, 2, 8.0 }, 34 | { 1, 7, 11.0 }, 35 | { 2, 3, 7.0 }, 36 | { 2, 5, 4.0 }, 37 | { 2, 8, 2.0 }, 38 | { 3, 4, 9.0 }, 39 | { 3, 5, 14.0 }, 40 | { 4, 5, 10.0 }, 41 | { 5, 6, 2.0 }, 42 | { 6, 7, 1.0 }, 43 | { 6, 8, 6.0 }, 44 | { 7, 8, 7.0 }, 45 | }; 46 | 47 | // 여기서는 간선의 weight가 정점 사이의 이동 비용을 의미합니다. 48 | sort(edges.begin(), edges.end()); // 간선의 weight 오름차순 49 | 50 | PrintEdges(edges); // 정렬 결과 확인 51 | 52 | double mst_wt = 0.0; 53 | 54 | UnionFind uf(9); 55 | 56 | for (auto& e : edges) 57 | { 58 | // TODO: 59 | 60 | mst_wt += e.weight; 61 | 62 | cout << e.u << " - " << e.v << " : " << e.weight << endl; 63 | } 64 | 65 | cout << mst_wt << endl; 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /VSCode/Ex1701_BipartiteGraph/Ex1701_BipartiteGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | void Print(vector& colors) 9 | { 10 | for (auto c : colors) 11 | cout << std::setw(3) << c; 12 | cout << endl; 13 | } 14 | 15 | bool IsBipartite(vector>& graph) 16 | { 17 | int V = int(graph.size()); 18 | vector colors(V, -1); 19 | 20 | colors[0] = 0; 21 | 22 | queue q; 23 | q.push(0); 24 | 25 | while (!q.empty()) 26 | { 27 | int u = q.front(); 28 | q.pop(); 29 | 30 | assert(graph[u][u] == 0); 31 | 32 | for (int v = 0; v < V; ++v) 33 | { 34 | Print(colors); 35 | 36 | if (graph[u][v] && colors[v] == -1) 37 | { 38 | colors[v] = 1 - colors[u]; // color는 0 또는 1, 이웃은 다른 색으로 설정 39 | q.push(v); 40 | } 41 | //else if ( TODO ) 42 | //{ 43 | // cout << u << " " << v << endl; 44 | // return false; 45 | //} 46 | } 47 | 48 | Print(colors); 49 | } 50 | 51 | return true; 52 | } 53 | 54 | int main() 55 | { 56 | { 57 | vector> graph = 58 | { 59 | {0, 1, 1}, 60 | {1, 0, 1}, 61 | {1, 1, 0} 62 | }; 63 | 64 | cout << std::boolalpha << IsBipartite(graph) << endl; 65 | } 66 | 67 | { 68 | vector> graph = 69 | { 70 | {0, 0, 1, 1}, 71 | {0, 0, 1, 0}, 72 | {1, 1, 0, 0}, 73 | {1, 0, 0, 0} 74 | }; 75 | 76 | cout << std::boolalpha << IsBipartite(graph) << endl; 77 | } 78 | 79 | { 80 | vector> graph = 81 | { 82 | {0, 1, 1, 1}, // <- 0-1 추가 83 | {1, 0, 1, 0}, 84 | {1, 1, 0, 0}, 85 | {1, 0, 0, 0} 86 | }; 87 | 88 | cout << std::boolalpha << IsBipartite(graph) << endl; 89 | } 90 | 91 | return 0; 92 | } 93 | 94 | // 참고자료 95 | // https://www.geeksforgeeks.org/bipartite-graph/ -------------------------------------------------------------------------------- /VSCode/Ex1702_GaleShapley/Ex1702_GaleShapley.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | struct Vertex 12 | { 13 | string name = ""; 14 | vector priority; // 선호도 우선순위 15 | int current = -1; // 현재 자신의 몇 "순위"와 연결되어 있는지 기록 16 | 17 | int Rank(string name) 18 | { 19 | for (int i = 0; i < priority.size(); i++) 20 | if (priority[i] == name) return i; 21 | 22 | assert(false); 23 | 24 | return -1; 25 | 26 | // Rank() 반환값이 작을 수록 우선순위가 높다 27 | // unordered_map<이름, 우선순위>를 만들어서 더 빠르게 확인 가능 28 | } 29 | 30 | string ConnectedName() 31 | { 32 | if (current == -1) return "NA"; 33 | else return priority[current]; 34 | } 35 | 36 | void Print() 37 | { 38 | cout << name << "("; 39 | for (auto& p : priority) 40 | cout << p; 41 | cout << ")"; 42 | } 43 | }; 44 | 45 | void Print(map& interns, unordered_map& teams) 46 | { 47 | for (auto& i : interns) 48 | { 49 | i.second.Print(); 50 | cout << " - "; 51 | if (i.second.current == -1) 52 | cout << "No Team"; 53 | else { 54 | teams[i.second.ConnectedName()].Print(); 55 | if (i.second.name != teams[i.second.ConnectedName()].ConnectedName()) 56 | cout << "*"; // 서로 연결이 아니라면 임시라는 의미로 * 추가 57 | } 58 | cout << endl; 59 | } 60 | } 61 | 62 | int main() 63 | { 64 | map interns; // 디버깅할때 순서대로 보기 위해 map 사용, unordered_map 사용 가능 65 | interns["A"] = Vertex{ "A", {"X", "Y", "Z"} }; 66 | interns["B"] = Vertex{ "B", {"Y", "X", "Z"} }; 67 | interns["C"] = Vertex{ "C", {"Y", "Z", "X"} }; 68 | 69 | unordered_map teams; 70 | teams["X"] = Vertex{ "X", {"B", "A", "C"} }; 71 | teams["Y"] = Vertex{ "Y", {"A", "B", "C"} }; 72 | teams["Z"] = Vertex{ "Z", {"B", "C", "A"} }; 73 | //teams["X"] = Vertex{ "X", {"B", "A", "C"} }; 74 | //teams["Y"] = Vertex{ "Y", {"A", "C", "B"} }; 75 | //teams["Z"] = Vertex{ "Z", {"B", "C", "A"} }; 76 | 77 | queue free_interns; 78 | for (auto& i : interns) 79 | free_interns.push(&i.second); // 모든 인턴을 free 큐에 넣기 80 | 81 | while (!free_interns.empty()) 82 | { 83 | Vertex* i = free_interns.front(); 84 | free_interns.pop(); 85 | 86 | cout << "Intern " << i->name << endl; 87 | 88 | // i->current += 1; 89 | 90 | // Vertex* t = &teams[i->ConnectedName()]; 91 | 92 | //if (t->current == -1) 93 | //{ 94 | // t->current = TODO; 95 | //} 96 | //else 97 | //{ 98 | // if ( TODO ) 99 | // { 100 | // free_interns.push(&interns[t->ConnectedName()]); 101 | // t->current = t->Rank(i->name); 102 | // } 103 | // else { 104 | // free_interns.push(i); 105 | // } 106 | //} 107 | 108 | Print(interns, teams); 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /VSCode/Ex1801_LongestPath/Ex1801_LongestPath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Vertex 7 | { 8 | Vertex(int v) { value = v; } 9 | 10 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 11 | bool visited = false; 12 | 13 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 14 | }; 15 | 16 | class Graph 17 | { 18 | public: 19 | Graph(int num_vertices) 20 | { 21 | vertices.resize(num_vertices); 22 | for (int i = 0; i < num_vertices; i++) 23 | vertices[i] = new Vertex(i); 24 | } 25 | 26 | ~Graph() 27 | { 28 | for (auto* v : vertices) 29 | delete v; 30 | } 31 | 32 | void AddDiEdge(int v, int w) // 단방향 간선 33 | { 34 | vertices[v]->out_neighbors.push_back(vertices[w]); 35 | } 36 | 37 | void AddBiEdge(int v, int w) // 양방향 간선 38 | { 39 | vertices[v]->out_neighbors.push_back(vertices[w]); 40 | vertices[w]->out_neighbors.push_back(vertices[v]); 41 | } 42 | 43 | void DFS(int source) 44 | { 45 | cout << "Depth-first Search: "; 46 | for (auto* v : this->vertices) 47 | v->visited = false; 48 | DFS(vertices[source]); 49 | cout << endl; 50 | } 51 | 52 | void DFS(Vertex* source) 53 | { 54 | cout << source->value << " "; 55 | source->visited = true; 56 | for (auto* w : source->out_neighbors) 57 | if (!w->visited) 58 | DFS(w); 59 | } 60 | 61 | void DepthFirstPath(int source, int sink) 62 | { 63 | cout << "Paths from " << vertices[source]->value << " to " << vertices[sink]->value << endl; 64 | 65 | longest_path.clear(); 66 | 67 | for (auto* v : this->vertices) 68 | v->visited = false; 69 | 70 | DepthFirstPathHelper(vertices[source], vertices[sink], vector()); 71 | 72 | cout << "Longest length : " << int(longest_path.size() - 1) << endl; 73 | cout << "Longest path : "; 74 | PrintPath(longest_path); 75 | } 76 | 77 | private: 78 | vector vertices; 79 | vector longest_path; 80 | 81 | void DepthFirstPathHelper(Vertex* source, Vertex* sink, vector path) 82 | { 83 | // TODO: 84 | } 85 | 86 | void PrintPath(vector path) 87 | { 88 | for (auto& v : path) { 89 | cout << v->value; 90 | if (&v != &path.back()) 91 | cout << " -> "; 92 | } 93 | cout << endl; 94 | } 95 | }; 96 | 97 | int main() 98 | { 99 | Graph g(6); 100 | 101 | // 주의: 양방향 간선 (undirected graph) 102 | g.AddBiEdge(0, 2); 103 | g.AddBiEdge(2, 1); 104 | g.AddBiEdge(2, 3); 105 | g.AddBiEdge(3, 4); 106 | g.AddBiEdge(1, 5); 107 | g.AddBiEdge(2, 4); 108 | g.AddBiEdge(3, 5); 109 | 110 | g.DepthFirstPath(0, 4); 111 | 112 | return 0; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /VSCode/Ex1802_TravellingSalesmanProblem/Ex1802_TravellingSalesmanProblem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct Edge 7 | { 8 | int u = 0; 9 | int v = 0; 10 | int weight = 0; 11 | }; 12 | 13 | struct Vertex 14 | { 15 | Vertex(int v) { value = v; } 16 | 17 | int value = -1;// 변수 이름은 value지만 실질적으로는 배열에 이 정점이 저장된 인덱스입니다. 18 | bool visited = false; 19 | 20 | vector out_neighbors; // 나가는 방향의 이웃 vertex들에 대한 포인터 21 | }; 22 | 23 | class Graph 24 | { 25 | public: 26 | Graph(int num_vertices) 27 | { 28 | vertices.resize(num_vertices); 29 | for (int i = 0; i < num_vertices; i++) 30 | vertices[i] = new Vertex(i); 31 | } 32 | 33 | ~Graph() 34 | { 35 | for (auto* v : vertices) 36 | delete v; 37 | } 38 | 39 | void AddDiEdge(int u, int v, int weight) // 단방향 간선 40 | { 41 | vertices[u]->out_neighbors.push_back(Edge{ u, v, weight }); 42 | } 43 | 44 | void AddBiEdge(int u, int v, int weight) // 양방향 간선 45 | { 46 | vertices[u]->out_neighbors.push_back(Edge{ u, v, weight }); 47 | vertices[v]->out_neighbors.push_back(Edge{ v, u, weight }); 48 | } 49 | 50 | void TravellingSalesman(int source) 51 | { 52 | cout << "Start : " << vertices[source]->value << endl; 53 | 54 | minimum_path.clear(); 55 | 56 | for (auto* v : this->vertices) 57 | v->visited = false; 58 | 59 | TravellingSalesmanHelper(vertices[source], vertices[source], vector(), 0); 60 | 61 | cout << "Minimum cost : " << min_wsum << endl; 62 | cout << "Minimum path : "; 63 | PrintPath(minimum_path); 64 | } 65 | 66 | private: 67 | vector vertices; 68 | vector minimum_path; 69 | int min_wsum = 1000000; // large number 70 | 71 | void TravellingSalesmanHelper(Vertex* source, Vertex* sink, vector path, int wsum) 72 | { 73 | // TODO: 74 | } 75 | 76 | void PrintPath(vector path) 77 | { 78 | for (auto& v : path) { 79 | cout << v->value; 80 | if (&v != &path.back()) 81 | cout << " -> "; 82 | } 83 | cout << endl; 84 | } 85 | }; 86 | 87 | int main() 88 | { 89 | Graph g(4); 90 | 91 | // 주의: 양방향 간선 (undirected graph) 92 | g.AddBiEdge(0, 1, 20); 93 | g.AddBiEdge(0, 2, 25); 94 | g.AddBiEdge(0, 3, 30); 95 | g.AddBiEdge(1, 2, 10); 96 | g.AddBiEdge(2, 3, 35); 97 | g.AddBiEdge(3, 1, 15); 98 | 99 | g.TravellingSalesman(0); 100 | 101 | return 0; 102 | } 103 | 104 | -------------------------------------------------------------------------------- /copy_files.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import chardet 4 | 5 | 6 | def get_immediate_subdirectories(dir_path): 7 | return [name for name in os.listdir(dir_path) 8 | if os.path.isdir(os.path.join(dir_path, name)) and name.startswith(("Ex", "shared"))] 9 | 10 | def find_cpp_h_files(dir_path): 11 | cpp_h_files = [] 12 | for root, dirs, files in os.walk(dir_path): 13 | for file in files: 14 | if file.endswith(('.cpp', '.h')): 15 | cpp_h_files.append(os.path.join(root, file)) 16 | return cpp_h_files 17 | 18 | def is_utf8_with_bom(file_path): 19 | with open(file_path, "rb") as f: 20 | encoding = chardet.detect(f.read()) 21 | print(encoding) 22 | return encoding["encoding"].lower() == "utf-8-sig" 23 | 24 | subdirs = get_immediate_subdirectories('.') 25 | print(subdirs) 26 | 27 | for sub in subdirs: 28 | 29 | print("VSCode/" + sub) 30 | 31 | if not os.path.isdir("VSCode/" + sub): 32 | os.makedirs("VSCode/" + sub) 33 | 34 | files = find_cpp_h_files(sub) 35 | for f in files: 36 | print(f + " to VSCode/" + f) 37 | # shutil.copy(f, "VSCode/" + f) 38 | 39 | if is_utf8_with_bom(f): 40 | shutil.copy(f, "VSCode/" + f) 41 | else: 42 | with open(f, 'r', encoding='cp949') as file: 43 | content = file.read() 44 | 45 | # 원본 파일도 인코딩 다시 46 | with open(f, 'w', encoding='utf-8-sig') as file: 47 | file.write(content) 48 | 49 | with open("VSCode/" + f, 'w', encoding='utf-8-sig') as file: 50 | file.write(content) 51 | 52 | 53 | 54 | --------------------------------------------------------------------------------