Задать вопрос
amtkel
@amtkel

Как правильно объеденить файлы при внешней сортировке?

Пытаюсь решить задачу о сортировке миллиона 32 битных int'ов с ограничением по оперативной памяти (habrahabr.ru/post/65503/) В качестве языка реализации использую C++.
С первой частью алгоритма проблем не возникло: считываем кусок данных из входного файла, сортируем и записываем во временный файл.
А вот со второй частью у меня проблемы. Вот кусок кода, который отвечает за чтение временных файлов в буфер и их слияние:
bool NumbersProcessor::readSortFile(ifstream &file, vector<int> &data) {
    int tmp;
    for (int i = 0; (i < bufferSize && file >> tmp); i++)
        data.push_back(tmp);

    return file.good();
}

void NumbersProcessor::mergeFiles(int numFiles) {
    ifstream inputFile1, inputFile2;
    	ofstream temp;
    string fileName1, fileName2;
	
    int i = 0;
    int k = 0;
    int max  = numFiles - 1;
	
    bool file1Good, file2Good;
    vector<int> data1;
    vector<int> data2;
    
    while(max >= 2) {
        fileName1 = "tempfile_"; fileName1 += to_string(i);
        fileName2 = "tempfile_"; fileName2 += to_string(i+1);

        try {
            inputFile1.open(fileName1);
            inputFile2.open(fileName2);
        } catch(int e) {
            cout << "Could not open the open the files!\nError " << e;
        }

        file1Good = true;
        file2Good = true;
        while(file1Good || file2Good) {
            if(data1.size() == 0)
                file1Good = readSortFile(inputFile1, data1);
            if(data2.size() == 0)
                file2Good = readSortFile(inputFile2, data2);

            temp.open("temp", ios::app);
            std::merge(data1.begin(),
                       data1.end(),
                       data2.begin(),
                       data2.end(),
                       std::ostream_iterator<int>(temp, "\n"));
					   
            temp.close();
            data1.clear();
            data2.clear();
        }

        inputFile1.close();
        inputFile2.close();

        remove(fileName1.c_str());
        remove(fileName2.c_str());

        fileName1 = "tempfile_"; fileName1 += to_string(k);
        rename("temp", fileName1.c_str());

        i = i + 2;
        k++;
        if (i >= max) {
            max = max / 2 + max % 2;
            i = 0;
            k = 0;
        }
    }
    cout << endl;
}


Слияние файлов работает, но не совсем корректно. Если взять последовательность из десяти чисел 7 2 6 5 9 7 8 1 4 3 и размер буффера равный двум числам, то на выходе получим: 1 2 3 4 5 7 6 7 8 9
Аналогичная ситуация наблюдается и для более длинных последовательностей: в начале и конце последовательности числа стоят в правильном порядке, но ближе к середине результат неправильный. Что я делаю не так?
  • Вопрос задан
  • 200 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
@mamkaololosha
> int max = = numFiles - 1;;
это чё за хрень?
Пошаговая отладка в вижлстудии уже не можно?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы