指定値の排除


文字を検索して排除する

配列内の指定した値、あるいは文字の排除を試みましょう
これは、実用的プログラムの作成時によく出てくる課題ですね

基本的な構想として、配列を先頭から最後までループで検索し
ループ内部で選択によりチェックするというのがもっともオーソドックスですね
もし、排除したい文字が見つかれば、その要素を飛ばしてしまえばよいのです
#include <stdlib.h>

int delValue(char *ary , int value , int last_index) {
	int count , t_count = 0;
	char *tmp;
	if ((tmp = (char *)malloc(sizeof( char ) * last_index)) == NULL) return -1;

	for (count = 0 ; count < last_index ; count++) tmp[count] = 0;
	for (count = 0 ; count < last_index ; count++) {
		if (*(ary + count) == value) continue;
		*(tmp + t_count) = *(ary + count);
		t_count++;
	}
	for (count = 0 ; count < last_index ; count++) *(ary + count) = *(tmp + count);

	free(tmp);
	return 0;
}
引数では、第一引数に配列へのポインタ
第二引数に排除する値、第三引数に要素の最大値を指定します

このモジュールは、最初に指定された配列の最大要素と同じだけの配列を生成します
最初に、この配列の全要素を0に初期化します

次に、ループで渡された配列のポインタから、配列を調べます
指定した文字列が見つからない場合は、*(tmp + t_count) = *(ary + count); によってコピーされます
if (*(ary + count) == value) continue; 文では、指定文字が配列の現在地で一致したとき
ループの先頭に戻ってカウンターを一つ進めます
しかし、テンポラリ用の配列カウンタt_countはそのままなので
結果としてtmpに、指定値を排除した値が並びます

最後に、tmpの内容をまるまるaryにコピーします
排除したことによってできた後半の空白は全て0になっています

しかし、配列を二つ用意してそれをいれかえるという作業は非常に効率が悪い
そこで、検索する配列を左に詰めるという方法で値の排除を試みよう

検索する値が発見された場合は、呼び出す値だけを加算し
値が一致しなければ呼び出す値と格納する値を加算します
これらの値にしたがって、配列の添え字を指定すれば正確に結果が得られます

ただし、一度も排除するべき値が発見されていない場合は
配列を詰める必要はありません
char* delValue(char *ary , int value , int last_index) {
	int count , back = 0;

	for (count = 0 ; count < last_index ; count++) {
		if (*(ary + count) == value) continue;
		if (back != count) *(ary + back) = *(ary + count);
		back++;
	}
	return ary;
}
先のプログラムに比べ、かなり軽くなっていますね
この場合は、ポインタから間接参照で値を変更しますが
ついで(?)に、ポインタを戻り値としてい返しています
そのため、delValue("Kitty on your lap" , ' ' , INDEX) というような使い方も可能ですね

ただし、終端にヌル文字を追加するという作業はプログラマの責任になります
最後にヌル文字を追加するなどの工夫をするのもよいでしょう



前のページへ戻る次のページへ