challenge ファイル内の重複行削除(後優先)

アレイのuniq」の応用編です。

入力されたテキストデータから重複する行をとりのぞいて、その結果を標準出力へ出力するプログラムを作成してください。

重複行の排除については、以下の仕様を満たしてください。

  1. 読み込み順序は変更しないこと
  2. 重複する行があった場合、以前のデータを削除すること (後に読み込んだ方が強い)
  3. ファイル全体を一度にメモリに読み込んで処理しないこと
  4. 比較は行全体で行うこと

#4.はおまけですがある/なしで作りが変わってくると思われるので追加しました。


この問題はraynstardさんにご投稿いただきました。ご協力ありがとうございます。 ところで、素朴な実装のしかたをするとメモリ容量の数倍のサイズのすべての行が異なっているファイルを読ませたときに大変なことが起こりそうな気がしますが、そういうシビアなお題設定ではないので素朴に解いてしまって構いません。シビアなのは続編にしたいと思います。

Posted feedbacks - C

Cでは1行読み込むといったことでさえ満足に行えないため、1行の文字数制限と、行数制限を無くする(もちろんメモリの許す限り)というところで素朴に書くというレベルを超えています。
そのかわり、行の削除は非常に素朴です。というか、疲れました。
こればかりは、他の言語に出番を許すしかないのでしょうか。C++でさえあれば・・・!
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCK_SIZE 1024

void read_line(char **out){
    int cnt = 1;
    *out = (char *)malloc(1);
    *out[0] = '\0';
    do{
        *out = (char *)realloc(*out, BLOCK_SIZE * cnt);
        fgets((*out) + strlen(*out), BLOCK_SIZE, stdin);
        cnt++;
    }while((*out)[strlen(*out)-1] != '\n' && !feof(stdin));
    *out = (char *)realloc(*out, strlen(*out) + 1);
}

int main(){
    int i;
    int size = 0;
    char **list = NULL;
    char *line;
    while(!feof(stdin)){
        read_line(&line);
        for(i=0; i<size; i++){
            if(list[i] != NULL && strcmp(line, list[i]) == 0){
                free(list[i]);
                list[i] = NULL;
            }
        }
        size++;
        list = (char **)realloc(list, sizeof(char *) * size);
        list[size - 1] = line;
    }
    for(i=0; i<size; i++){
        if(list[i])
            fputs(list[i], stdout);
        free(list[i]);
    }
    free(list);
    return 0;
}

Index

Feed

Other

Link

Pathtraq

loading...