【问题标题】:Sorting with low memory size以低内存大小排序
【发布时间】:2019-04-24 09:58:00
【问题描述】:

用 2G RAM 对 1GB 大小(每个单词 255 个字符)的字典进行排序的最佳方法是什么? 我已经尝试过快速排序,但没有得到可接受的结果。 这是快速排序代码:

#include <iostream>
#include <fstream>
#include <cstring>

#define MAXL 4000000
using namespace std;
void swap(char *&ch1,char *&ch2)
{
    char *temp = ch1;
    ch1 = ch2;
    ch2 = temp;
}

int partition (char **arr, int low, int high)
{
    string pivot = arr[high];    // pivot
    int i = (low - 1);  // Index of smaller element

    for (int j = low; j <= high- 1; j++)
    {
        // If current element is smaller than or
        // equal to pivot
        if (arr[j] <= pivot)
        {
            i++;    // increment index of smaller element
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[high]);
    return (i + 1);
}

void quickSort(char **arr, int low, int high)
{
    if (low < high)
    {
        int pi = partition(arr, low, high);

        // Separately sort elements before
        // partition and after partition
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}


int main()
{
    fstream file("input.txt",ios::in|ios::out|ios::app);
    fstream o("output.txt",ios::out);

    char **arr = new char*[MAXL];
    for(int i=0;i<MAXL;i++)
        arr[i] = new char[255];

    long long i=0;
    while(file)
    {
//words are sepearated by spcae
        file.getline(arr[i],256,' ');
        i++;
    }

    file.close();
    quickSort(arr, 0, i-2);

    for(long long j=0;j<i-1;j++)
    {
        o << arr[j] << "\n";
    }
}

对上述列表进行排序需要 10 多分钟,但不应超过 20 秒。 (MAXL是1G文件的字数,输入的字存储在一个文本文件中)

【问题讨论】:

  • 快速排序出了什么问题?
  • 任何像样的排序算法都是就地的,这意味着 1GB 就足够了。开销将是微不足道的。
  • @YvesDaoust ANY 不错的排序算法?对于大型数据集来说,最好的往往是基于合并排序,这不是就地的。
  • @YvesDaoust 您忽略的一点是,虽然不适合某些用途,但它是一种不合适的排序算法。另一个例子是 Timsort,它不仅不错,而且对真实世界的数据非常好,它击败了其他所有东西,成为 Python、Java 和许多其他语言的默认值。同样,不是就地算法。 (部分原因是它可以使用归并排序作为后备。)
  • 关键是你不能只去一个标准库,采用推荐的算法,并假设它已经到位。因为很有可能不是。

标签: algorithm performance sorting time quicksort


【解决方案1】:

如果你不能把它全部放在内存中,基于文件的合并排序会很好用。

【讨论】:

  • 1GB 的数据怎么会装不下 2GB 的内存呢?
  • @YvesDaoust 因为原始数据的内存表示存在开销。例如,如果您使用 Python,则每个 stackoverflow.com/questions/18596342/… 每个字符串都有 37 个字节的开销。所以一个 1 GB 的单词文件实际上需要几个 GB 才能加载到内存中。
  • @btilly:问题是 1 GB 大小。我从字面上理解。
  • 它适合内存
【解决方案2】:

就地算法是您的解决方案。查找更多here

作为另一个例子,许多排序算法将数组重新排列为原地排序,包括冒泡排序、梳状排序、选择排序、插入排序、堆排序和 Shell 排序。这些算法只需要几个指针,所以它们的空间复杂度是 O(log n)。

【讨论】:

  • QuickSort 在正确实现时也需要O(log n)
  • @MBo 很好奇这里的log n 来自哪里。是对输入大小的描述吗?
  • @mrmcgreg 是的。 log(n) 是快速排序的堆栈大小。但是log(n) 提到的算法的空间是(太)基于 n 范围所需变量的位大小的正式定义。
  • 一些引用的算法需要 O(1) 空间。我不能坚持最后一句话。
  • 在这种情况下时间很重要
猜你喜欢
  • 1970-01-01
  • 2011-05-17
  • 2012-11-01
  • 2021-05-14
  • 1970-01-01
  • 2011-02-04
  • 2015-06-17
  • 1970-01-01
  • 2018-07-27
相关资源
最近更新 更多