std::vector 2次元配列の列方向初期長
- std::vectorを使用して2次元配列を宣言する際、列方向の初期長を指定する方法はありますか?
- 通常、列方向の初期長を指定しない場合、a.resize(N)を実行した後にfor (auto &n : a) n.reserve(10);を行いますが、これは時間がかかります。
- aの列方向の初期長を10と指定する方法で、a.resize(N)を実行した際に自動的にfor (auto &n : a) n.reserve(10);を行う方法を教えてください。
- ベストアンサー
std::vector 2次元配列の列方向初期長
std::vectorを使った2次元配列を std::vector< std::vector<int> > a; の様な方法で宣言できるところまでは分かったのですが、aの列の初期長を予め指定する方法はないでしょうか? 例えば、必要な列方向初期長が10であるとします。 行方向のデータ数Nが実行中に与えられる場合 a.resize(N); for (auto &n : a) n.reserve(10); で目的は達せられるのですが、Nが数千万のオーダーだど非常に時間がかかります。 仮にNが2000万個とすると、私のPCでa.resize(N)は約90ミリ秒で完了しますが、for (auto &n : a) n.reserve(10);には約10秒を必要とします。 そこで、aの列の初期長は10(reserve(10)の意味)であると言う何らかの指定を行って a.resize(N)を行った際に、自動的にfor (auto &n : a) n.reserve(10);を行ったのと同じ状態になっているという aの宣言方法があれば教えてください。 aの列方向の初期長(本例の場合は10)は与えますが、.push_back() により10個以上のデータを列方向に詰める場合も想定する為、完全固定長の std::array<> は使用できません。
- mpach
- お礼率100% (3/3)
- C・C++・C#
- 回答数3
- ありがとう数4
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
あ, 長さはそうなっちゃいますね. すみません. ただ, 速度についてはどうにもならないような気がします. 動的メモリ確保は結構重たい処理なので, 大量に実行するとどうしても時間がかかっちゃいます. #1 で 「速いか」といわれるとわからない と書いたのも, 「ど~書いても時間は同じくらいかかるんじゃないかなぁ」と思ったことが根底にあります. 「高速化したい」ということであれば, 作った「2次元配列」をどう使うかによるんだけど.... その「約10秒」が全体の実行時間に影響するようだと, データ構造から考え直さないといけないかもしれん.
その他の回答 (2)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
template<typename T, size_t R> struct reserve_vector : public vector<T> { reserve_vector() { reserve(R); } }; vector<reserve_vector<int,10>> a; ...なんてのはダメですか?
お礼
教えて頂いた方法を試してみましたが 今度は a.resize(N)で10秒消費してしまい 速度的には変わりませんでした。
- Tacosan
- ベストアンサー率23% (3656/15482)
resize で初期値を与えることはできるけど, 「速いか」といわれるとわからない.
お礼
a.resize(N); for (auto &n : a) n.resize(10); と指定しても、for (auto &n : a) n.resize(10); に10秒消費してしまいます。 またresize()で実体を割り当てしまうとpush_back()した際 11個目から追加動作してしまうので、内部にカウンターを定義して i=0, n[i++]=b; の様に管理しなければならなくなりますね。
関連するQ&A
- std::vectorのマージ
std::vectorで値が重複しないマージを行う一般的な方法はありますか? A = { 1, 2, 3, 4, 5 } B = { 4, 5, 6, 7, 8 } A + B = { 1, 2, 3, 4, 5, 6, 7, 8 } こういう感じにしたいのです。 今はforで回しているのですが、もっといい方法があるのではないかと思って。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- 2次元のvectorにオブジェクトのポインタを格納
VC++6.0です。 まず、ポインタでなく、int型の格納なら分かったんです。 ・・・ #include <vector> using namespace std; main(){ vector <vector<int > > a(10); ←←← for(int i=0;i<10;i++){ a[i].resize(10); } ・・・ for(int j=0;j<10;j++){ for(int i=0;i<10;i++){ a[i][j]=i+j; } } ・・・ } という感じで利用できることが。 しかし、やりたいのは、整数型でなく、 オブジェクトのポインタを格納したいんですが、 矢印部分を例えば、vector <vector<class *> > a(10); などどしてもエラーになってしまいます。 どのように実装したらよいのでしょうか?
- 締切済み
- C・C++・C#
- C言語の配列をC++のvectorに高速に変換したい
質問は表題のとおりです。 単純な方法では以下の通りになると思いますが、 (C言語文字列から string への変換のように) 一括変換の仕組みは vector にないのでしょうか? static const int n=5; int a[n]={0,1,2,3,4}; std::vector<int> v(n); std::vector<int>::iterator vit=v.begin(); for(int i=0; i<n; i++){ *vit++ = a[i]; } 上記の例では n=5 ですが、nがとても大きな場合に適用したいと考えています。 ちなみに、gcc 3.4.3 を使っています。
- ベストアンサー
- C・C++・C#
- C++ vectorに配列をプッシュしたい
C++のstd::vectorが格納する要素として配列を指定することはできますか vectorを使って2次元配列を表現したいときは,たとえば std::vecor<std::vector<int>> v; とすれば2次元配列が表現できますよね. 2次元配列の列方向の要素数が2で固定されていて,行方向の要素数が不確定のデータを扱いたいので,2次元配列を格納するvectorで扱えればなと思いました. (2個で1組のデータがたくさんあるということなので,vectorの2次元配列ではありません) std::vector<int[2]> v; int a[2]; a[1] = 1; a[0] = 2; v.push_back(a); という書き方ではコンパイルできなかったのですが,vectorに配列要素を格納させることはできないのでしょうか. あるいは,もし可能ならどのように書けばよいのでしょうか. 結局は1組のデータセットを構造体化してそれをvectorにプッシュするやり方に落ち着いたのですが,疑問に思ったままモヤモヤしているので質問させて頂きます. 「vector 配列」などのキーワードで検索してみましたが,vectorの動的配列としての紹介記事が多くヒットしてしまい,自分ではうまく情報を発見することはできませんでした. よろしくお願いします.
- ベストアンサー
- C・C++・C#
- STL vectorの初期化
STL vectorの初期化についてなんですが 以下のようなクラスのprivateなメンバ変数としてvectorを定義し それをメソッド内のループ処理にて初期化しながら使用したいのですが 初期化の仕方が分かりません。コンストラクタを呼べば初期化されるようですが 以下のようにヘッダとソース内で2度同じような宣言をしてしまっても問題ないのでしょうか? //=== test.h === class test { private : vector<int> array; public : int fnc(); }; //=== test.c === int fnc() { for (int i = 0; i < 10; i++) { //★ここで初期化したい vector<int> array; ←これで問題ないか? for (int j = 0; j < 10; j++) { array.push_back( md ); } } } C#などでは宣言とインスタンス生成を別に分けられたのですがC++も同様の事が出来るのでしょうか? 一応「array = new vector<int>;」といれて見たのですがエラーが出ました。
- 締切済み
- C・C++・C#
- 行ベクトルと列ベクトル
行ベクトルと列ベクトル 次の積を計算せよ。 ( 1 2) (3) 5 6 4 指針 行列の積ABの計算は、Aの行ベクトルとBの列ベクトルの積が基本となる。例えば ( 1 2) (3) 4 ( 5 6) (3)を計算し、これらの成分としておいたものが積になる。このとき、次のことがポイント。 4 (第●行目の行ベクトル)と(第■行目の列ベクトル)積を(●、■)とおく。 教えてほしいところ行ベクトルとは1×n行列のことをいい、m×1の行列を列ベクトルというんですよね。 よって、第●行目の行ベクトル)と(第■行目の列ベクトル)積を(●、■)とおく。 って、行列の中に行列が入ってみるたいで、おかしくないですか?? 実際、( 1 2) の行列の5 6の部分は行ベクトルであるとはいいませんよね?? 5 6
- ベストアンサー
- 数学・算数
- C++ 構造体型のvector配列でエラーがでます
構造体のvector配列を関数に渡しています。 以下のソースコードで、3点エラーがでます どのように変更すればよいですか? #include<stdio.h> #include<stdlib.h> #include<iostream> #include <vector> using namespace std; std::vector<int> v; typedef struct fukusosu{ int a; int b; }FUKUSOSU; int sort(vector<FUKUSOSU> v[], int N){ FUKUSOSU tmp; int j; for(int i = 0 ; i < N - 1 ; i++){ j = i ; for(int k = i + 1 ; k < N ; k++){ if(v[j].a > v[k].a){j = k;}//ここのaに対して、エラーがでます } tmp = v[j];//ここのイコールに対して、エラーがでます v[j] = v[i]; v[i] = tmp;//ここのイコールに対してエラーがでます } } int main(void){ int N; // 要素数 cin >> N; vector<FUKUSOSU> v(N); for(int i = 0; i < N; ++i){ cin >> v[i].a; cin >> v[i].b; } }
- ベストアンサー
- C・C++・C#
- 散乱後の光子の方向ベクトル
ある光子が一定の方向ベクトルnを持っているとして、 nx=X0 ny=Y0 nz=Z0 である時、この光子が一定の角度θ、φで散乱された時、散乱後の方向ベクトルaはどのように書くことができますか?
- 締切済み
- 物理学
- 多次元配列について質問
以下は、Javaの参考書に掲載されていたある問題です。 その問題文と解答ソースコードを記載しますので、以下の疑問点に答えていただければ幸いです。 また、僭越ながらお願いがあるのですが、このソースコードを一度実行してから私の質問を見たほうが、より私の疑問点が回答者様にわかると思うので、実行してくだされば幸いです。 問題文:次のA~Cの手順に従ってプログラムを作成しなさい。 A:5×4の2次元配列のint型配列pを作成します。つまり、pは5個の要素を持ち、各要素が「4つの要素を持つintの配列」であるような配列です。 B:次にpの全要素にMath.random()で得られる乱数値を代入しなさい。乱数値は0から10の範囲になるように10倍し、さらにintにキャストして配列の要素に代入しなさい。 C:pの全ての要素を例示のように表示しなさい。(※ここでいう「例示」とは、私がこの質問板にupした画像のこと)ただし、pの各要素を5×4の表と見た時、各列の(縦方向の並び)の合計を、その5×4の表と見た時、各列(縦方向の並び)の合計も例示のように表示しなさい。 ---解答ソースコード(クラス宣言は除きます)--- public static void main(String[]arg){ //A int[][]p=new int[5][4]; //B for(int i=0;i<p.length;i++){ for(int j=0;j<p[i].length;j++){ p[i][j]=(int)(Math.random()*10); } } for(int[]n:p){ for(int m:n){ System.out.print(m+"\t"); } System.out.println();//改行 } //C int[]sum=new int[p[0].length]; for(int[]n:p){ for(int j=0;j<n.length;j++){ sum[j]+=n[j]; } } System.out.println(); for(int m:sum){ System.out.print(m+"\t"); } } 疑問点:Cの手順の解答について疑問なのですが、以下のソースコードで何故各列の合計を求められるかわかりません。何故ですか?凄く頭が引きちぎれるほど考えたのですがわかりませんでした。 int[]sum=new int[p[0].length]; for(int[]n:p){ for(int j=0;j<n.length;j++){ sum[j]+=n[j]; } } だって、例えば拡張for文でpの0番目の要素を取り出して、さらにfor文でその0番目の要素の0番目、1番目、2番目、3番目をsumに累計するといったように、縦方向でなく「横方向」に合計するソースコードに僕は思えるんですよ。何故縦方向に合計できるんですか?たしかに実行すると縦方向に合計されてるので、縦方向に合計するものには間違いなのだけれど、、
- ベストアンサー
- Java
お礼
>動的メモリ確保は結構重たい処理 相当に重い処理だったのですね。 future & async() や Concurrency::parallel_for_each() などでマルチスレッド化してもOSの動的メモリ確保受付窓口が1つしか無いためか、オーバーヘッドが発生して倍の20秒程度かかってしまいました。 vectorを使った、この方法での速度アップはあきらめることにします。 おつき合いありがとうございました。