13

私は C++ を初めて使用し、std::vector代わりにを使用するように絶えず言われていますnew[]

ベクトルのサイズを知っていて、ランダムに(順次ではなく)割り当てたい場所で、この機能を実現しようとしています。

ただし、これを実行すると、プログラムはエラー出力なしで終了するため、困惑しています。

vector<string> v1;
v1.resize(2);
v1.insert(v1.begin() + 1, "world");
v1.insert(v1.begin() + 0, "world");

cout << v1.at(1) << endl;
4

5 に答える 5

19

あきらめないでください、それよりも簡単です

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";

cout << v1[1] << endl;

vector::insertこれは、ベクターにアイテムを追加する場合に使用します。既に存在するアイテムを置き換える場合ではなく、vector::insertベクターのサイズを変更します。

于 2012-11-13T19:08:46.320 に答える
12

まず、サイズを変更して2つの空の文字列を作成します。

{"", ""}

次に、"world"begin() + 1または2番目の要素を挿入します。

{"", "world", ""}

次に、"world"begin()または最初の要素を挿入します。

{"world", "", "world, ""}

次に、で2番目の要素にアクセスしv1.at(1)、空の文字列を取得します。

std::vector::insertおそらく、既存の要素の間に新しい要素を挿入するのは望ましくありません。配列の場合と同じように、これを実行しますoperator[]

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";
cout << v1.at(1) << endl;
于 2012-11-13T19:10:54.150 に答える
10

ランダムに割り当てる

単にインデックスを使用します(明らかに、それが < であることを検証しますsize

v1[index] = value;

ランダムに挿入するには (そのインデックス < を検証しますsize)

v1.insert(v1.begin() + index, value);

最後に挿入/追加するには(インデックスは必要ありません。値はベクトルの最後に挿入されます)

v1.push_back(value);

多くの値を挿入する予定がある場合は、reserve()すべてのアイテムを格納するのに十分なメモリを割り当てることができるように、ベクトルを呼び出すことを検討してください。そうしないと、データを挿入すると、ベクトルが大きくなるにつれて多くの再割り当てが発生する可能性があります

于 2012-11-13T19:15:44.320 に答える
6

あなたのプログラムは正しく動作しています。エラーはコードのロジックにあります。

Insert は、インデックス 1 に格納されている文字列を変更しません。文字列を位置 1 に配置し、1 の後のすべてのインデックスを右に移動します。

最初の挿入を開始 2 番目の挿入
("","") -> ("", "世界, "") -> ("世界","","世界","")

したがって、 v1.at(1) を印刷すると、空の文字列が印刷されます。

この問題を解決するには、次を使用します。

v1.at(1)="world"
v1.at(0)="world"

- また -

v1[1] ="world"
v1[0] ="world"

2 つのソリューションは同等ですが、2 番目のソリューションは境界チェックを行いません。1 つ目は、範囲外のエラーが発生した場合にエラーをスローします。範囲外にインデックスを作成しないことを保証できる限り、これは重要ではありません。

于 2012-11-13T19:20:44.647 に答える
2

operator[]多くの人が述べているように、ベクトルのサイズを変更したり、他の値で埋めたりした場合は、古い値を再割り当てするために使用できます。配列のサイズが常に固定されている場合はstd::array、 を使用できます。これにより、パフォーマンスが向上しますが、配列のサイズを変更したり、実行時にそのサイズを決定したりする機能が犠牲になります。

std::array<std::string,2> a1;
a1[0] = "world";
a1[1] = "world2";
std::cout<<a1.at(1)<<std::endl; //outputs world2

サイズは静的でなければならないため、次のようなことはできないことに注意してください。

int numStrings;
std::cin>>numStrings;
std::array<std::string,numStrings> a2; //ERROR

std::array残念ながら、初期化リストを使用する以外に、デフォルトのコンストラクターなしで を初期化する方法はないと思います。

struct T
{
   T(std::string s):str(s){} //no default constructor
   std::string str;
}
std::array<T,2> a3 = {T(""), ""}; //you can use a conversion constructor implicitly

かなりの数のオブジェクトを含む配列が必要な場合、これは明らかに実用的ではありません。

于 2012-11-14T02:24:14.663 に答える