Advertisement
Bibodui

гпт

Jun 8th, 2023
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.93 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <string>
  6.  
  7. // Функция для разделения исходного файла на временные файлы
  8. void splitFile(const std::string& inputFilename, const std::string& tempPrefix, int chunkSize) {
  9. // Открываем исходный файл для чтения
  10. std::ifstream inputFile(inputFilename);
  11. // Вектор для хранения временного чанка данных
  12. std::vector<std::string> chunk(chunkSize);
  13.  
  14. int fileIndex = 0;
  15. // Читаем исходный файл и разделяем его на временные файлы
  16. while (!inputFile.eof()) {
  17. // Читаем chunkSize строк во временный чанк
  18. for (int i = 0; i < chunkSize && !inputFile.eof(); ++i) {
  19. std::getline(inputFile, chunk[i]);
  20. }
  21.  
  22. // Если были прочитаны строки, выполняем сортировку и записываем во временный файл
  23. if (!chunk.empty()) {
  24. // Сортируем строки во временном чанке
  25. std::sort(chunk.begin(), chunk.end());
  26.  
  27. // Генерируем имя временного файла
  28. std::string tempFilename = tempPrefix + std::to_string(fileIndex++) + ".txt";
  29. // Открываем временный файл для записи
  30. std::ofstream tempFile(tempFilename);
  31. // Записываем отсортированные строки во временный файл
  32. for (const std::string& line : chunk) {
  33. tempFile << line << std::endl;
  34. }
  35. }
  36. }
  37.  
  38. // Закрываем исходный файл
  39. inputFile.close();
  40. }
  41.  
  42. // Функция для выполнения слияния файлов
  43. void mergeFiles(const std::string& outputFilename, const std::string& tempPrefix, int fileCount, int chunkSize) {
  44. // Открываем выходной файл для записи
  45. std::ofstream outputFile(outputFilename);
  46. // Вектор для хранения временных файлов
  47. std::vector<std::ifstream> tempFiles(fileCount);
  48.  
  49. // Вектор для хранения текущих строк из каждого временного файла
  50. std::vector<std::string> currentLines(fileCount);
  51. // Вектор для отслеживания пустых файлов
  52. std::vector<bool> isFileEmpty(fileCount);
  53.  
  54. // Открываем временные файлы и считываем первую строку из каждого файла
  55. for (int i = 0; i < fileCount; ++i) {
  56. // Генерируем имя временного файла
  57. std::string tempFilename = tempPrefix + std::to_string(i) + ".txt";
  58. // Открываем временный файл для чтения
  59. tempFiles[i].open(tempFilename);
  60.  
  61. // Изначально считаем файлы не пустыми
  62. isFileEmpty[i] = false;
  63.  
  64. // Считываем первую строку из файла
  65. if (!std::getline(tempFiles[i], currentLines[i])) {
  66. // Если файл закончился, помечаем его как пустой
  67. isFileEmpty[i] = true;
  68. }
  69. }
  70.  
  71. // Выполняем слияние файлов
  72. while (true) {
  73. // Находим индекс файла с минимальным значением
  74. int minValueIndex = -1;
  75. for (int i = 0; i < fileCount; ++i) {
  76. // Если файл не пустой
  77. if (!isFileEmpty[i]) {
  78. // Если это первый не пустой файл или его строка меньше текущей минимальной строки
  79. if (minValueIndex == -1 || currentLines[i] < currentLines[minValueIndex]) {
  80. // Обновляем индекс минимальной строки
  81. minValueIndex = i;
  82. }
  83. }
  84. }
  85.  
  86. // Если все файлы пусты, завершаем слияние
  87. if (minValueIndex == -1) {
  88. break;
  89. }
  90.  
  91. // Записываем минимальную строку в выходной файл
  92. outputFile << currentLines[minValueIndex] << std::endl;
  93.  
  94. // Считываем следующую строку из выбранного файла
  95. if (!std::getline(tempFiles[minValueIndex], currentLines[minValueIndex])) {
  96. // Если файл закончился, помечаем его как пустой
  97. isFileEmpty[minValueIndex] = true;
  98. }
  99. }
  100.  
  101. // Закрываем все временные файлы
  102. for (int i = 0; i < fileCount; ++i) {
  103. tempFiles[i].close();
  104.  
  105. // Удаляем временные файлы
  106. std::string tempFilename = tempPrefix + std::to_string(i) + ".txt";
  107. std::remove(tempFilename.c_str());
  108. }
  109.  
  110. // Закрываем выходной файл
  111. outputFile.close();
  112. }
  113.  
  114. // Функция для выполнения внешней сортировки методом естественного слияния
  115. void externalSort(const std::string& inputFilename, const std::string& outputFilename, int chunkSize) {
  116. // Префикс для временных файлов
  117. std::string tempPrefix = "temp_chunk_";
  118. int fileCount = 0;
  119.  
  120. // Разделяем исходный файл на временные файлы с заданным размером
  121. splitFile(inputFilename, tempPrefix, chunkSize);
  122.  
  123. // Определяем количество созданных временных файлов
  124. std::ifstream inputFile(inputFilename);
  125. std::string line;
  126. while (std::getline(inputFile, line)) {
  127. ++fileCount;
  128. }
  129. inputFile.close();
  130.  
  131. // Выполняем слияние файлов
  132. mergeFiles(outputFilename, tempPrefix, fileCount, chunkSize);
  133. }
  134.  
  135. int main() {
  136. // Имя входного и выходного файлов
  137. std::string inputFilename = "input.txt";
  138. std::string outputFilename = "output.txt";
  139. // Размер временных чанков
  140. int chunkSize = 10000;
  141.  
  142. // Генерируем случайный файл для сортировки
  143. std::ofstream inputFile(inputFilename);
  144. srand(time(nullptr));
  145. for (int i = 0; i < 100000; ++i) {
  146. int value = rand() % 1000000;
  147. inputFile << value << std::endl;
  148. }
  149. inputFile.close();
  150.  
  151. // Выполняем внешнюю сортировку
  152. externalSort(inputFilename, outputFilename, chunkSize);
  153.  
  154. std::cout << "External sort completed." << std::endl;
  155.  
  156. return 0;
  157. }
  158.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement