vectorのerase

解決


駆け出し  2009-06-22 03:34:07  No: 70400

string型配列のvectorと宣言し
std::vector<std::string> rdata[30];

で、このvectorのn番目の要素を、削除したいのですが、以下のコードではどこが
まずいでしょうか。

void Foo::remove( int n )
{
  std::vector<std::string>::iterator itr = rdata[30].begin();
  itr += n;

  for(int i=0; i<30; i++)
  {
    m_rdata[i].erase( itr );
  }
}


tetrapod  2009-06-22 04:09:06  No: 70401

突っ込みどころだらけなんだが・・・

vector 自体が30個あるの?それとも
要素数30個の vector が1個あるの?まずはそこから。


駆け出し  2009-06-22 06:39:06  No: 70402

要素数30個のvectorを宣言し
これにpush_backしています。


επιστημη  URL  2009-06-22 07:55:23  No: 70403

> std::vector<std::string> rdata[30];

これだと vector が 30個ありますよ。


tetrapod  2009-06-22 18:16:15  No: 70404

ますます突っ込みどころが増えている気のせいがするが・・・

vector<string> v; と書いたら、どう解釈されるかはわかる?
・ v という vector が1個
・デフォルト初期化される(要素数0個)
int i; と書いたのと同じ。

vector<string> a[30]; であれば
・ a という「 vector の配列」が作られ、その配列の要素数は30
  つまり30個の vector が作られる
・それぞれの vector はいずれもデフォルト初期化される (要素数0)
int x[30]; と同じ。

30個の要素を持つ vector 1つを作りたいのであれば記述方式が違う。
答え書いちゃうのは簡単だけどまずは調べて味噌。

次に vector は要素数可変な配列ということを忘れちゃいけない。
push_back は要素を1個追加する、ということだ。
既に30個の要素がある vector に push_back すると要素数は31になる。
初期化時点で要素数0個の vector を作ったとしても、その必要があれば
push_back を繰り返して好きな要素数にできる。
逆に初期化時点で30個の要素数を確保しておき、それを増減させたくないのであれば
push_back を使うのでなく v[0]=string("abc"); のほうが適切。
# ないしは個数可変機能が無い boost::array を使う

んで本題のn個目の要素を削除したい、って案件に対しては erase 1回でいい。
どこを(=n番目)削除するか、その iterator を決めるのには std::advance を使う。
これもまた今ここで答え書いちゃうのは簡単だけど、もうちょっと考えて味噌。

要素数30個の vector から1個要素を削除すると、要素数29個になるぞ。
それが望みの動作なのかどうか、要検討


駆け出し  2009-06-24 00:58:57  No: 70405

すいません。
vectorが30個でした。
rdata[i].pushu_back(xxx);
とやってます。
rdata.push_backが出来る?なんて、頭になかったもんで適当に答えてしまいました。

rdata[i]のiは状況によって増減します。
で、rdata[i][j]のもj変化します。
この配列のjがn番目のものをすべて削除したいんですが。
と言う事で、最初のコードを試してみたんですが、
この場合だと、std::advanceを使うんでしょうか?

勉強してみます。


tetrapod  2009-06-24 01:50:32  No: 70406

> vectorが30個でした。
ぎゃっふん。

テキトーに問うとテキトーな答えしか返らない/返しようがないのはおk?
プログラムなんて1文字違っても動かないんだしさぁ・・・もっと慎重に返事してよ。

rdata[*][n] を削除したい、ということなら
iterator は各 vector に対して1つづつ別に計算する必要があるわけで
for (i=0; i<30; ++i) {
  std::vector<std::string>::iterator p(rdata[i].begin());
  std::advance(p, n); // p+=n; と実質同じだがこれなら list に対しても通用する
  rdata[i].remove(p);
}
// エラーチェック類は省略 たとえば n>=size だったらとか・・・


επιστημη  URL  2009-06-24 02:26:35  No: 70407

ご参考:

> for (i=0; i<30; ++i) {
>   std::vector<std::string>::iterator p(rdata[i].begin());
>   std::advance(p, n); // p+=n; と実質同じだがこれなら list に対しても通用する
>   rdata[i].erase(p);
> }

vector以外に通用しなくていいならコレ↓で十分。

for (i=0; i<30; ++i) {
  rdata[i].erase(rdata[i].begin()+n);
}


駆け出し  2009-06-24 02:56:20  No: 70408

すいません、X適当に  ○単純に
そうか、個別のvectorなので、iteratorも別なんですね。
わかりました。

rdata[i].erase(rdata[i].begin()+n);
このような、書き方もできるんですね。

ありがとう、ございまいした。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加