C ++,读取和保存大量数字

时间:2013-12-27 13:49:43

标签: c++ arrays numbers save

我必须解决问题,我需要你的帮助,所以提前谢谢。如你所见,标题几乎说明了一切。有一个文件“domes.in”(这是一个文本文件),它包含10.000.000对整数From(1 - 100.000),因此在第一部分中,我必须在不到1秒的时间内保存所有这些数字

首先,我尝试创建一个20.000.000个地方的int数组,这样我就可以逐个保存数字。数组的大小太大,程序没有响应。

在你阅读代码之前,先阅读任务,但请回答我的问题,不要发布任何代码,因为这是一个在线竞赛的问题,我想自己写。

#include <fstream>
using namespace std;

int main()
{
    int n, m, a, b;        //N(Value)    M(Pairs)
    int t = 0;
    int r = 0;
    int j;

    ifstream infile("domes.in");
    infile >> n >> m;     //N = 100.000    M = 10.000.000
    int domes[m*2];

    for (j=0; j<m; j++)      //For 1 to 10.000.000
    {
        infile >> a >> b;    //Save 10.000.000 Integers
        domes[t++] = a;
        domes[t++] = b;
    }
    for (j=1; j<=n; j++)          //For J = 1 - 100.000
    {
        int i=0;
        for (int k=0; k<t; k++)   //If the point J is appeared 
            if (domes[k] == j)    //+1 Link
                i++;

        if (i == 1)               //If Links < 2  (of number J)
            r++;                  //+1 Point is connected with less than 2 points
    }                             //Else move on to ++J
    infile.close();

    ofstream outfile("domes.out");
    outfile << r;
    return 0;
}

现在它似乎可以工作,但程序再次没有响应(在运行时,引发错误,表示程序停止运行。代码中还有任何其他构建错误或错误)。

我做错了什么?

TextFile: 100000 10000000

2344 3444

3345 4564

5566 9455 //随机整数高达100.000

// ..........

//编辑:我从代码中删除了结构“DOMES”,因为它是同样的东西

任务:我会用自己的话解释它,因为它很复杂。在地图上是100.000点。这些点是连接的(有10.000.000个链接)。我必须找到只有一个连接的点(每个Point至少有一个连接)。

例如:

5 4(N = 5,M = 4)N(最大值)M(对)

1 2

2 3

4 5

3 4

有2个点具有单个连接:1和5(1与2连接)和(5与4连接)。其余的点至少连接两次:

2:1-2,2-3

3:2-3,3-4

4:4-3,4-5

3 个答案:

答案 0 :(得分:1)

第一个问题是算法的成本所在,这很可能与读取输入无关。如果我理解你的算法,你正在读取所有数字(节点id)到内存,然后你迭代链接,你选择一个节点,并尝试找到是否有更多链接包含该节点。该算法是O(N ^ 2),对于大量的算法来说,它会变成大量的操作。

如果你需要知道的是有多少节点有一个连接,你需要在内存中维护的每个节点一个条目(100k)。每个节点需要保留多少信息?很少,例如,仅检测哪些节点具有单个连接,您可以存储节点被看到的次数(0 - >从未见过)。一次读一行,增加两个节点的计数(成本:O(N),N是链接数)。在该过程结束时,扫描条目并打印出计数为1的条目(成本:O(M),其中M是节点数)。算法的总成本在节点数+边数之和是线性的,在节点数上有线性空间要求。

将其与原始方法进行比较:空间400k对160M;操作10M对10 ^ 14。

在大多数编程竞赛中,目标不是削减运营成本,而是提高解决方案的渐近复杂度。似乎适用于小输入的天真解决方案不适用于大型输入。对于10号问题,O(N ^ 2)基本上是100次运算......几乎是一个常数因子!但随着问题的增加,尺寸100变为10k,尺寸1000则为1M ......

答案 1 :(得分:1)

对于大数据的I / O,C ++流比它们的C亲属慢。我相信你可以加快fopen()fwrite() <cstdio>的写作速度。通过这样做,您可以一次性编写整个数组,并且可能不会出现崩溃问题。

答案 2 :(得分:0)

不确定这是否对在线比赛有用。但是,为了快速访问文件,我会尝试内存映射文件。 (如果您的平台支持POSIX,请使用mmap(),或者在Windows上支持CreateFileMapping和MapViewOfFile)基本上,您可以像写入内存一样写入文件。