
コンテナの内容を変えた後に内容を変える前のiteratorを使用することはできないと聞きました。ので、連続して何らかのコンテナ内のデータを変更しつつ、探索する場合にも、iteratorは最初から探索を始めないといけないと思っています。
例えば以下のように
#include <stdio.h>
#include <list>
struct data
{
int value;
data(int value)
{this->value = value;}
};
typedef std::list<data> DataList;
typedef std::list<data>::iterator DataIterator;
bool EraseValue(DataList*dataList, int value)
{
DataIterator iterator= dataList->begin();
while(iterator != dataList->end())
{
if(iterator->value == value)
{
dataList->erase(iterator);
return true;
}
iterator++;
}
return false;
}
int main()
{
//データを入れる
DataList dataList;
for(int i=0;i<10; i++)
dataList.push_back(data(i));
//指定のデータを探し、消す
int Value[] = {4,5,7};
EraseValue(&dataList, Value[0]);
EraseValue(&dataList, Value[1]);
EraseValue(&dataList, Value[2]);
//結果表示
DataIterator iterator = dataList.begin();
while(iterator != dataList.end())
{
printf("%d\n",iterator->value);
iterator++;
}
return 0;
}
ここで、新しい値の探索を始めるたびに、最初から探索をはじめる部分が無駄であると思っています。探索するデータは、上の例のように、必ず前回探したものの後にあることはわかっているとして、これより効率のよい方法はないでしょうか?自分の中での理想は、削除したiteratorの直前に使った(削除されていない)iteratorの位置から探索を始めるのがいい思っているのですが、これはどうやらできないこと(やってはいけないこと?)の様です。
コンテナをstd::listに限定した場合でも構いません。
ご教授よろしくお願いします。
No.2ベストアンサー
- 回答日時:
ここに要素の削除によるイテレーターの無効化について情報が乗っています。
std::listに限って言えば要素が削除された場合、無効になるイテレーターは削除対象の要素を示していたイテレーターのみです。
> 必ず前回探したものの後にあることはわかっている
場合ならば以下のようにしても良いと思います。
bool EraseValue(DataList*dataList, int* value, size_t erasenum)
{
DataIterator iterator= dataList->begin();
while(iterator != dataList->end() && erasenum > 0)
{
if(iterator->value == value)
{
DataIterator tmp = iterator; // 削除対象を見つけたのでイテレーターを保存
++iterator; // 次のイテレーターに移動
dataList->erase(tmp); // 削除。この時点でtmpは無効だが、iteratorは利用可能
++value; // 次の削除対象に移す
--erasenum; // 削除数を減らす
}
else
{
iterator++;
}
}
return false;
}
迅速な返答ありがとうございます。
疑問が完全に氷解しました。ありがとうございます。
自分の環境では、直前のものを使うのに成功していたのですが、"たまたま"かどうか裏が取れなかったので、使用していませんでした。
No.1
- 回答日時:
コンテナから任意の要素を消したいという話なら、
remove_ifを使えばいいと思うのですが何か問題があるのでしょうか?
STL Algorithm詳解 - 置き換え、削除
http://www.wakhok.ac.jp/~sumi/stl/manual/remove. …
返答ありがとうございます。
当方、まだまだ未熟で、STLのalgorithmなどは、一度も使ったことがありません。こんな便利なことができるのですね。
是非試してみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Java どんな時にIteratorを使うと便利なのですか 2 2022/12/07 05:30
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Java どうしてListオブジェクトをIteratorに変換するのですか 1 2022/12/03 17:45
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) VBAで日付入力しているのですが 4 2023/03/02 11:25
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- Visual Basic(VBA) 検索のユーザーフォームの表示について 1 2023/03/27 23:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
JSONで文字列が長い時
-
Excel VBAで行追加後の...
-
CGIやPHPで外部ファイルの内容...
-
フォームからの値
-
linq で 楽天ウェブサービスのX...
-
プログラムの作り方。アイディ...
-
ブルダウンで1項目を選択したの...
-
途中まで出来ているのですが‥(D...
-
CGIでのページ指定~その(2)
-
VB2010 のユーザコントロールの...
-
このCGIサブルーチンを解説して...
-
【VB2005】メソッドに渡したデ...
-
フォーム入力(CGIでデータ取得)...
-
LISPで連想配列の操作?
-
FLASHとCGIでのデータの受け渡...
-
perlでtelnetクライアント
-
C言語:単語カウント
-
【プルダウンで選んでGOボタン...
-
Pythonのプログラミングの質問...
-
Perlの書き方について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
JSONで文字列が長い時
-
メモリをアドレスを直接指定し...
-
リロード後にプルダウンの選択...
-
map(STL)でinsertを行いたいで...
-
CGIでのページ指定~その(2)
-
CGI(Perl)で、Net::FTPを使いたい
-
linq で 楽天ウェブサービスのX...
-
ラズパイで感圧センサーを動か...
-
gpioを使ってSPIをシミュレーシ...
-
アンケートフォームのvalueの値...
-
iteratorの再利用について
-
Perlでアルファベットを数...
-
途中まで出来ているのですが‥(D...
-
VB2010 のユーザコントロールの...
-
半角スペースが有効にならない。
-
Application.ScreenUpdating = ...
-
formで特定のinputを送信しない...
-
セレクトメニューで2つの項目...
-
<SELECT>タグの折り返し
-
16進の10進変換について
おすすめ情報