如何从2个输入文件中按升序将整数排序到新文件中?

时间:2017-09-09 20:36:20

标签: c io

我试图创建一个从两个文件中获取整数输入的程序。我有两个整数升序的文件,输出文件应该将这两个文件合并为一个文件,保持升序。

{{1}}

它几乎已经完成但是当其中一个文件的数字小于/大于另一个文件中的前一行(例如30> 43)时会出现问题。如何解决此问题,以便输出完全排序?

5 个答案:

答案 0 :(得分:3)

您正在从每个文件中读取一个数字,当您必须从同一个文件中取两个连续数字时,这个数字会失败。

相反,您应该从文件#1和#2中读取数字,并继续从文件中读取哪个数字较小,直到它比从另一个文件读取的最后一个数字大。

答案 1 :(得分:3)

您的代码有两个问题 - 首先,您假设两个文件具有相同数量的条目,其次,您假设输出中的数字将成对出现在第一个文件/第二个文件中,反之亦然。

您可以通过一次读取一个数字来解决此问题。设置一个标志以指示您从一侧或另一侧有一个数字,从缺少的一侧读取数字,并在输出中写入一个数字。然后标记您从中获取下一个读数的一侧,并重复该过程。

主循环看起来像这样:

int have1 = 0, have2 = 0;
for ( ; ; ) {
    int temp1, temp2;
    have1 = have1 || 1==fscanf(inputFile1, "%d", &temp1);
    have2 = have2 || 1==fscanf(inputFile2, "%d", &temp2);
    // We ran out of numbers in both files - exit
    if (!have1 && !have2) {
        break;
    }
    if (!have2 || (have1 && temp1 < temp2)) {
        fprintf(outputFile, "%d\n", temp1);
        have1 = 0;
    } else if (!have1 || (have2 && temp2 < temp1)) {
        fprintf(outputFile, "%d\n", temp2);
        have2 = 0;
    } else {
        fprintf(outputFile, "%d\n", temp1);
        have1 = 0;
        fprintf(outputFile, "%d\n", temp2);
        have2 = 0;        
    }
}

答案 2 :(得分:3)

考虑一个实际案例,你有两列数字按升序排列,你想按升序读出它们。您最有可能在每列上保留一根手指,指向该列中的下一个值。你选择较小的,大声朗读,并将手指向下移动。这是您的代码应该实现的算法。

让我们看看伪代码中的算法。

首先,我们需要从两个文件中读取第一个值。可能会发生其中一个源文件为空,在这种情况下我们只需要输出另一个文件的内容:

Read value1 from the first file.
If we cannot, then:
    Loop:
        Read value2 from the second file.
        If we cannot: Return.
        Output value2
    End loop
End if

Read value2 from the second file.
If we cannot, then:
    Loop:
        Output value1
        Read value1 from the first file.
        If we cannot: Return.
    End loop
End if

它负责初始条件,现在我们从第一个文件中获得value1,从第二个文件中获得value2,并且可以进入我们的主循环。

在每次迭代中,我们输出较小的值,并从该源文件中读取下一个数字 - 就像我们在我们朗读的列中向下移动手指一样。

同样,如果我们用完了数据,我们会输出另一个文件的内容。

请注意,我选择了一个逻辑,其中所有相等的值首先从第一个文件输出(即,如果两个列具有相等的值,我们首先读取(所有相等的值)第一列,并从之后的第二栏)。这应该是stable sort

Loop:

    If value1 <= value2, then:
        Output value1
        Read value1 from the first file.
        If we cannot, then:
            Loop:
                Output value2
                Read value2 from the second file.
                If we cannot: Return.
            End loop
        End if
    Else:
        Output value2
        Read value2 from the second file.
        If we cannot, then:
            Loop:
                Output value1
                Read value1 from the second file.
                If we cannot: Return.
            End loop
        End if
    End if
End loop

在C中,这应该非常简单地作为一个函数实现;也许void interleave_ints(FILE *in1, FILE *in2, FILE *out)

请注意,上面的所有循环都是无限的(即while (1) { ... }do { ... } while(1);for (;;) { ... }),在函数中,您可以使用return;返回来电者。

答案 3 :(得分:1)

您无需每次都阅读它们。如果其中一个文件中的当前值为3,6,8...,另一个为7,9,10...。您需要跳过从第二个文件中读取下一个值,因为您将丢失7。 您需要运行循环以读取第一个文件中小于7的所有值,然后才读取第二个文件中的下一个值。

int last = 1; // Initializing last to 1 so that it is read in the 1st cycle
int in1, in2, temp1, temp2;

fscanf(inputFile2, "%d", &in2); //Initializing in2 for valid 1st comparison

while(1)
{

    if(last == 1 && fscanf(inputFile1, "%d", &temp1) == 1){
        in1 = temp1;
    } else last = 0;
    if(last == 2 && fscanf(inputFile2, "%d", &temp2) == 1){
        in2 = temp2;
    } else last = 0;

    if( last == 0 ) break; // Will be 0 only if both reads fail

    printf("temp1: %d\n", in1);
    printf("temp2: %d\n", in2);

    if (in1 < in2)
    {
        fprintf(outputFile, "%d\n", in1);
        last = 1;
    }
    else
    {
        fprintf(outputFile, "%d\n", in2);
        last = 2;
    }
}

答案 4 :(得分:0)

小巧,棘手的解决方案。告诉我,如果你有兴趣,我会添加评论。

#include <stdio.h>

int main() {
    FILE *file_1 = fopen("file_1.txt", "r");
    FILE *file_2 = fopen("file_2.txt", "r");

    int num;
    int tmp;
    int max = 0;
    int i = 0;

    FILE *stream[2] = {file_1, file_2};

    while(fscanf(stream[i], "%d", &num) == 1) {
        if(! max) {
            max = num;
            i = i ^ 1;
            continue;
        }   

        if(max < num) {
            i = i ^ 1;
            tmp = max;
            max = num;
            num = tmp;
        }   

        printf("%d\n", num);
    }   
    printf("%d\n", max);

    fclose(file_1);
    fclose(file_2);
    return 0;
}

<强>输入:

file_1.txt

5
10
30
50
345

file_2.txt

1
43
55
98
500

<强>输出:

1
5
10
30
43
50
55
98
345
500