2016-05-12 2 views
0

私のコードにバグがあり、エラーを認識できません。私は各変数の出力をステップごとに表示してデバッグしようとしましたが、エラーが見つかりません。ここで私が持っているものと私は何をしたいです:ベクトルとインデックスの内積にエラーがあります

私は行列Aがあります。

0000 
0101 
1010 
1111 

をそして、私は行列Bを持っている:

10000 
21000 
30100 
41100 
20010 
21010 
40110 
41110 
30001 
41001 
30101 
41101 
40011 
41011 
40111 
41111 

行列Bは、16行を持っており、 5 coloumns。行列Aは4行4列です。今度は、4行16列の行列Cを宣言します。

私がしたいのは、Bの各行の内積をAの対応する行で計算することです。対応するとは、Bの最初の列がAからの行を定義することを意味します。 B行列は実際には4次元ベクトルでもあり、最初の要素はAの行に対応しています。これはBの最初のcoloumnがAの行を選択するためのインデックスであると言うことができます。私のインデックスのために。

std::vector< std::vector<int> > C(4, std::vector<int>(16)); 
std::vector<int> index(4); 
std::vector<int> vectorA(4); 
std::vector<int> vectorB(4); 

for(int y = 0; y < 16; y++) 
{ 

    for(int i=0; i<4; ++i){ 
    vectorA[i] = A[ B[y][0]-1 ][i]; 
    } 

    for(int x = 1; x < 4; x++) 
    { 

     vectorB[x -1] = B[y][x]; 

    } 


C[ B[y][0] -1][index[ B[y][0] -1] ] = inner_product(vectorA.begin(), vectorA.end(), vectorB.begin(), 0); 

    index[B[y][0]-1] += 1; 
} 

これは私の行列Cをもたらす:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
2 2 3 1 2 1 2 2 3 0 0 0 0 0 0 0 

最初の2行が正しいが、3および4が偽である行ここに私のコードです。 正解は(多分3行目に発注し、4を除く)である必要があります:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 
4 3 3 2 3 2 3 2 2 0 0 0 0 0 0 0 

どこに問題がありますか? 、それは狂気私を駆動:(私はステップで各変数を示すしようとしたが、それが偽の理由を見つけることができません助けてください

感謝と挨拶

+0

ようこそスタックオーバーフロー!デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。詳しい読書:** [小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)** – NathanOliver

+0

私はたくさんのことを学ばなければならず、過ごすでしょうこれでより多くの時間。私はあなたが何を意味しているのか理解しています。私のコードで何が間違っているかもしれないかのヒントを教えてもらえますか? C++を知っている人にとって、これは簡単な初心者の質問でしょうか? –

+0

私はあなたのヒントを得ました:あなたのコードをより読みやすくするようにしてください。例えば、int indexFromB = B [y] [0]を書き、コメントを書くようにしてください。この混乱はすべて本当に読みにくいです。より具体的である - inner_product関数の結果は何ですか? – tty6

答えて

0

を私は他のコメントに同意する必要があります。。あなたのコードがありますコードのインデックスへのアクセスを単純化する必要があります。

まず最初に、Bの最初の列を0に変更します.C++のすべての要素はゼロベースです。あなたのコードでそれを減算して調整しないでください(これはあまり単純ではありませんが、あなたのコードでは症状になります)。

混乱のもう1つの原因は、AのインデックスとしてBの最初の列を使用することです。これは解決したい問題からの含意かもしれませんが、不明瞭になります.Bの最初の列はまったく異なる意味を持ちますオブジェクトがその意味で分離されるように、常にコーディングしてください。

私にとっては、最も混乱しやすいことは、あなたがしていることを実際には得られないということです。内製品ではドットプロダクトを意味します、そうですか?内積を計算する2組のベクトルがあります。これによりスカラーの集合、すなわち2D行列ではなく1次元ベクトルが得られるはずです。あなたはこのインデックスベクトルで特別なことを行い、結果は2Dマトリックスになります。しかし、あなたはそれの背後にある目的/システムについて説明していません。なぜスカラーだけでなく、インデックス用のベクトルが必要なのですか?

ベクターインデックスは、コードの中で最も醜い/複雑な部分です。あなたが何をしているかの手がかりを持たずに、私はまだすべての反復で完全なベクトルインデックスを印刷し、予想通りに変化しているかどうかを確認するときに何がうまくいかないのか推測しています。

0

私はOPの選択肢の背景にある根拠がわからないので、提供されるコードの設計については適切にコメントできませんが、私が理解できることは、入力例に間違いがあることです。提示さ

考えるAおよびB行列、Bに対応するAの下段の内積は常に0である。succesive行の

         B[1] { 2,  1, 0, 0, 0 }, 
row "2" or A[1] is { 0, 1, 0, 1 } <- B[4] { 2,  0, 0, 1, 0 }, 
            B[5] { 2,  1, 0, 1, 0 }, 

同じ。スワップされた場合にのみ、期待される出力が得られるので、私のコードで行った。

vectorAvectorBと対応するコピーループは本当に必要ありませんで、おそらく間違った出力の原因である:

for(int x = 1; x < 4; x++) 
{ //   ^^^^^ this should be <= to reach the last element 
    vectorB[x -1] = B[y][x]; 
} 

私のコード、更新された入力およびAの直接の使用とBであります:

#include <iostream> 
#include <vector> 
#include <numeric> 

using vec_t = std::vector<int>; // I assume a C++11 compliant compiler 
using mat_t = std::vector<vec_t>; 
using std::cout; 

int main() { 

    mat_t A{ 
     { 0, 0, 0, 0 }, 
     { 1, 0, 1, 0 }, // <-- those lines are swapped 
     { 0, 1, 0, 1 }, // <-- 
     { 1, 1, 1, 1 } 
    }; 
    mat_t B{ 
     { 1, 0, 0, 0, 0 }, 
     { 2, 1, 0, 0, 0 }, 
     { 3, 0, 1, 0, 0 }, 
     { 4, 1, 1, 0, 0 }, 
     { 2, 0, 0, 1, 0 }, 
     { 2, 1, 0, 1, 0 }, 
     { 4, 0, 1, 1, 0 }, 
     { 4, 1, 1, 1, 0 }, 
     { 3, 0, 0, 0, 1 }, 
     { 4, 1, 0, 0, 1 }, 
     { 3, 0, 1, 0, 1 }, 
     { 4, 1, 1, 0, 1 }, 
     { 4, 0, 0, 1, 1 }, 
     { 4, 1, 0, 1, 1 }, 
     { 4, 0, 1, 1, 1 }, 
     { 4, 1, 1, 1, 1 } 
    }; 

    mat_t C(4, vec_t(16)); 
    vec_t pos(4); 

    for (int i = 0; i < 16; ++i) 
    { 
     int row = B[i][0] - 1; 
     int col = pos[row]; 
     int prod = std::inner_product(A[row].begin(), A[row].end(), 
             ++(B[i].begin()), 0); 
     //       ^^^ skip the first element 
     C[row][col] = prod; 
     if (prod) 
      ++pos[row]; 
    } 

    for (auto & r : C) 
    { 
     for (int x : r) { 
      cout << ' ' << x; 
     } 
     cout << '\n'; 
    } 

    return 0; 
} 

出力は次のとおり

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 
2 2 3 2 3 2 3 3 4 0 0 0 0 0 0 0 

最後の行の順序が期待どおりかどうかわかりませんが、OPのコードのロジックを模倣しています。

関連する問題