合并 2 个文件并对其进行排序

Posted

技术标签:

【中文标题】合并 2 个文件并对其进行排序【英文标题】:Merge 2 files and sort them 【发布时间】:2013-12-18 18:03:41 【问题描述】:

我有 2 个 txt 文件,其中的数字 > 0,我必须对它们进行组合和排序。也不能有 2 个相同的值。

这里是文件的值。 文件1:

1
2
3
4
5
6
7

文件2:

1
3
6
8
10

输出应如下所示:

1
2
3
4
5
6
7
8
10

我目前的代码:

#include <stdio.h>
#include <stdlib.h>

int main()

    FILE *fr1,*fr2;
    int fst, snd, p[256], i=0, n=0;
    bool f1=true,f2=true;

    fr1 = fopen("txt/cisla.txt","r");
    fr2 = fopen("txt/cisla2.txt","r");

    while(feof(fr1) == 0 && feof(fr2) == 0)
    

        if (f1) fscanf(fr1, "%d", &fst);
        if (f2) fscanf(fr2, "%d", &snd);

        printf("%d - %d\n", fst, snd);

        if (fst == snd) 
        
            f1 = true;
            f2 = true;
            p[i] = fst;
           else if (fst > snd)
        
            p[i] = snd;
            f1 = false; 
            f2 = true;
           else
        
            f2 = false;
            f1 = true;
            p[i] = fst;
        

        i++;

    

    fclose(fr1);
    fclose(fr2);

    printf("\n\n\n");

    for(int j = 0; j < i; j++)
    
            printf("%d\n", p[j]);
    

    return 0;


这样的结果是:

1 - 1
2 - 3
3 - 3
4 - 6
5 - 6
6 - 6
7 - 8


1
2
3
4
5
6
7

底部是数组。在顶部,我正在编写读取的值。问题是它似乎停在第一个文件的末尾,但我希望它继续第二个文件,即使第一个文件在末尾​​p>

【问题讨论】:

您的文件已排序,对吧? system("cat file1 file2 &gt; sort"); ? 【参考方案1】:

问题是它似乎停在第一个文件的末尾

那是因为您告诉它这样做 - 您拥有的继续条件是 feofs 都返回零:

while(feof(fr1) == 0 && feof(fr2) == 0) 
    ...

我希望它继续第二个,即使第一个在末尾​​p>

在第一个循环之后再添加两个循环,用较大的元素写出文件的“尾部”:

while(feof(fr1) == 0 && feof(fr2) == 0) 
    ... // Do the merge

while(feof(fr1) == 0) 
    ... // Read from fr1, and write to the output

while(feof(fr2) == 0) 
    ... // Read from fr2, and write to the output

【讨论】:

如果我将其更改为 OR,它会崩溃,如果我进行 2 个不同的循环,我该如何比较变量? @DeiForm 这两个“尾”循环出现在“合并循环”之后。我编辑了答案来说明。 好吧我还是不明白,第一个会和我现在做的一样,然后我应该在第二个循环中做什么? @DeiForm Loop #1 执行您已经执行的操作。循环 #2 从 fr1 读取,并将循环 #1 之后剩余的内容写入输出。循环 #3 从 fr2 读取,并将循环 #1 之后剩余的内容写入输出。请注意,只有两个添加的循环 #2 和 #3 中的一个会执行,因此它将是循环 #1+#2、循环 #1+#3 或只是循环 #1,但不会全部三个。 @DeiForm 另请注意,循环 #2 和 #3 可能需要跳过一些条目。您需要存储写入输出的最后一个值,并确保不会再次写入。您还必须在循环 #1 中处理它。【参考方案2】:

您的 while 循环说要在两个文件都没有结束时继续;我想你希望它继续下去,只要 EITHER 没有结束。当然,你最好不要尝试从结尾处读到的那个...

【讨论】:

能否请您更具体一些,从这里我想我应该将while循环从AND更改为OR,但是我怎么不能从已经在末尾的文件中读取? 在循环内部,您可以在读取文件之前检查文件的 eof。【参考方案3】:

这个小小的改进可能会有所帮助。

while(feof(fr1) == 0 || feof(fr2) == 0)

这是因为您想要循环或读取直到两个文件都没有被完全读取。

顺便说一句,你为什么不能使用一些通用容器..

【讨论】:

这会让它崩溃,循环永远不会结束 它在哪里崩溃了? 一直写到 7 - 8 点【参考方案4】:

您的问题被标记为 C++,但显示的代码看起来不像。它看起来更像 C

如果您避免重新发明***并使用 C++ 标准库,那么完成您想要做的事情会容易得多。

这是一个使用std::vector 和标准库的简单示例:

// Open file streams for reading.
std::ifstream fr1"file1.txt";
std::ifstream fr2"file2.txt";

// Read number tokens into a std::vector from both files.
std::vector<int> vstd::istream_iterator<int>fr1, std::istream_iterator<int>;
v.insert(std::begin(v), std::istream_iterator<int>fr2, std::istream_iterator<int>);

// Sort the vector.
std::sort(std::begin(v), std::end(v));

// Remove consecutive duplicates (move them to back of vector).
auto end = std::unique(std::begin(v), std::end(v));

// Remove duplicate elements.
if (end != std::end(v)) 
    v.erase(end, std::end(v));


// Output vector.
for (int i : v) 
    std::cout << i << std::endl;

Look at this live example

【讨论】:

以上是关于合并 2 个文件并对其进行排序的主要内容,如果未能解决你的问题,请参考以下文章

MFC对话框连接一个数据库.mdb文件并对其读写。

分治法合并排序

在 PHP 中的 while() 中合并数组

ruby sizes:计算当前文件夹的所有文件大小并对其进行排序

合并K个排序链表

合并排序——二路合并排序