配列 文字列 重複 削除

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tarou

配列 文字列 重複 削除

#1

投稿記事 by tarou » 7年前

失礼します。
現在配列に格納された文字列から同じ文字列があった場合削除するという処理をしたいのですが上手くいきません
mallocは要素数をカウントできないと聞きどのようにすべての配列から比較すればいいのかわかりません
strs[0]にaaa strs[1]にbbbと以降も要素が入っているとして       
例 処理前 aaa,bbb,ccc,ddd,ccc

この配列のそれぞれを比べて
処理後 aaa,bbb,ccc,ddd

このようにしていきたいです。
何かサンプルコードなどがあればいただきたいです。
今現在こちらのstrsに要素が入っています。

説明の仕方が下手だと思いますが何卒宜しくお願い致します。

コード:

int text_count = 0;
	char **strs;
	strs = (char **)malloc(sizeof(char) * 1000);

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 配列 文字列 重複 削除

#2

投稿記事 by みけCAT » 7年前

tarou さんが書きました:現在配列に格納された文字列から同じ文字列があった場合削除するという処理をしたいのですが上手くいきません
まず、配列に文字列を格納するコードは書けますか?
書ける場合、それを提示していただけるとそれをベースにして目標の処理を書きやすいので、提示していただきたいです。
tarou さんが書きました:mallocは要素数をカウントできないと聞きどのようにすべての配列から比較すればいいのかわかりません
適当な変数に要素数を保存しておき、それを用いてループなどで処理すればいいでしょう。
tarou さんが書きました:今現在こちらのstrsに要素が入っています。
tarou さんが書きました:

コード:

int text_count = 0;
	char **strs;
	strs = (char **)malloc(sizeof(char) * 1000);
この確保の仕方は良くないですね。
先頭要素へのポインタがchar**で示される配列の要素はchar*であり、charではありません。
また、sizeof(char)は1と定義されているので、要素の型とも関係ないのに掛ける意味は無いでしょう。
オフトピック
ヘッダをインクルードせずにmalloc関数を使いたいが、ヘッダをインクルードしないのでsize_tと書くとエラーになる。
そこで、sizeof(char)を用いてsize_t型の値を作る。
…みたいな特殊な用途なら掛ける意味はあるかもしれません。
従って、例えば250要素確保したいとすると、
C言語なら、mallocの戻り値のキャストは不要であり、するべきではないので

コード:

strs = malloc(sizeof(char*) * 250);
C++なら、そもそもmallocなんか使わずに

コード:

strs = new char*[250];
とするといいでしょう。
もしくは、C++ならstd::vectorとstd::stringを利用するほうがいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tarou

Re: 配列 文字列 重複 削除

#3

投稿記事 by tarou » 7年前

>>配列に文字列を格納するコードは書けますか?
書ける場合、それを提示していただけるとそれをベースにして目標の処理を書きやすいので、提示していただきたいです。

えと、例みたいなものですか?
これでいいかわかりませんが、、、、
今試しに作成してみました。

コード:

char *strings[] = { "ABC", "DEF", "GHI" };
printf("%s\n", strings[0]);
printf("%s\n", strings[2]); 
>>今現在こちらのstrsに要素が入っています。
こういった形でしょうか?

コード:

int text_count = 0;
char **strs;
strs = malloc(sizeof(char*) * 250);
これを別のfor文の中で

コード:

strs[text_count] = key_buf2;
++text_count;
と、key_buf2に格納されている文字列をstrsに格納していっています。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 配列 文字列 重複 削除

#4

投稿記事 by みけCAT » 7年前

key_buf2にmallocで確保したバッファのポインタが入っていると仮定すると、こんな感じでしょうか?
計算量は文字列の数をN、文字列の長さをMとしてO(MN^2)です。

コード:

int new_text_count = 0; /* 重複削除後の文字列の数 */
int i, j;
for (i = 0; i < text_count; i++) {
    int is_new = 1;
    for (j = 0; j < new_text_count; j++) {
        if (strcmp(strs[i], strs[j]) == 0) {
            /* 既に同じ文字列がある */
            is_new = 0;
            break;
        }
    }
    if (is_new) {
        /* 同じ文字列が無かったので、結果データに加える */
        strs[new_text_count] = strs[i];
        ++new_text_count;
    } else {
        /* 同じ文字列があったので、消す */
        free(strs[i]);
    }
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tarou

Re: 配列 文字列 重複 削除

#5

投稿記事 by tarou » 7年前

ありがとうございます。無事実装できました。ありがとうございます。

box
記事: 2002
登録日時: 13年前

Re: 配列 文字列 重複 削除

#6

投稿記事 by box » 7年前

みけCAT さんが書きました: また、sizeof(char)は1と定義されているので、要素の型とも関係ないのに掛ける意味は無いでしょう。
自分は、大いに意味があると思います。間違いなく1個1バイトの領域を必要な個数だけ動的確保している、ということを示す、という点において。

コード:

    size = 256;
    p = (char *) malloc(sizeof(char) * size);
こういう書き方をごく普通にしてました。以前Cでシステムを開発してたとき。
ま、宗教論争になりそうなのであまり深入りするのはやめときましょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 配列 文字列 重複 削除

#7

投稿記事 by みけCAT » 7年前

box さんが書きました:
みけCAT さんが書きました: また、sizeof(char)は1と定義されているので、要素の型とも関係ないのに掛ける意味は無いでしょう。
自分は、大いに意味があると思います。間違いなく1個1バイトの領域を必要な個数だけ動的確保している、ということを示す、という点において。
1個1バイトのオブジェクトの配列を確保する場面においては、たしかに可読性の面でいいでしょう。
ただし、char型の配列の場合はsizeof(char)、unsigned char型の配列の場合はsizeof(unsigned char)のように、
「1個1バイトの領域を確保している」ことを示すより、確保したい配列の要素の型を具体的に示したほうが読みやすい気がします。

また、今回の場合はポインタの配列の確保であり、ポインタは多くの環境では1バイトではないので、
逆にcharの配列を確保しているという誤解を与えて有害であるように思えます。
box さんが書きました:

コード:

    size = 256;
    p = (char *) malloc(sizeof(char) * size);
こういう書き方をごく普通にしてました。

コード:

size = 1024;
p = (int *) malloc(sizeof(char) * size);
のような書き方もしていましたか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る