向量数组,计算点积
Posted
技术标签:
【中文标题】向量数组,计算点积【英文标题】:Vector arrays, calculation dot product 【发布时间】:2017-09-18 14:56:45 【问题描述】:我正在尝试编写计算两个给定向量的点积的 C++ 程序。在向量 a 和 b 中,只有非零元素将存储到结构数组中。每次我得到不相关的结果。正确的结果是 50。我认为我无法将向量正确读取到结构数组中。请指教。提前谢谢你
#include <iostream>
#include <vector>
using namespace std;
const int n=10; /* vector size limit */
struct element
int x; /* original index of non-zero array element */
int val ; /* integer non-zero value at index x */
;
element row[n];
element col[n];
int i;
vector<int> a=0,0,7,0,5,0,0,8,0,4,-1;
vector<int> b=0,0,0,5,6,0,0,0,0,5,-1;
void generate_row_and_col()
for (i=0; i<=n; i++)
if(a[i]=!0)
row[i].x=i;
row[i].val=a[i];
for (i=0; i<=n; i++)
if(b[i]!=0)
col[i].x=i;
col[i].val=b[i];
int dotproduct()
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].x!=-1 && col[j].x!=-1)
if(row[i].x == col[j].x)
product=product+row[i].val*col[j].val;
i++;
j++;
else if(row[i].x<col[j].x)
i++;
else
j++;
return product;
int main()
generate_row_and_col() ;
int r;
r=dotproduct();
cout<<"result="<<r<<endl;
return 0;
【问题讨论】:
你的结果应该是 51 而不是 50for (i=0; i<=n; i++)
在 C++ 数组索引中从 0...n-1 开始,其中 n = 数组长度。
5*6+4*5+-1*-1 = 51
演示coliru.stacked-crooked.com/view?id=e39d16816d6b7410
我可以看到一个错误 if(a[i]=!0) 那是什么
【参考方案1】:
标准库有std::inner_product
用于正是这个目的。使用它可以将您的代码简化为以下内容:
#include <numeric>
#include <iostream>
#include <vector>
int main()
std::vector<int> a = 0,0,7,0,5,0,0,8,0,4 ;
std::vector<int> b = 0,0,0,5,6,0,0,0,0,5 ;
std::cout << std::inner_product(a.begin(), a.end(), b.begin(), 0);
【讨论】:
【参考方案2】:使用= !0
是一个错误。那应该是!= 0
。
我仍在猜测目标,但也许另一个清理过的版本会有所帮助:
Live On Coliru
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using Ints = vector<int>;
using Vec = map<int, int>;
Vec row, col;
Vec to_sparse_vec(Ints const& a)
Vec v;
for (size_t i = 0; i < a.size(); ++i)
if (a[i] != 0) v[i] = a[i];
return v;
int dotproduct(Vec row, Vec col)
size_t n = max(row.rbegin()->first, col.rbegin()->first);
int product = 0;
for (size_t i = 0; i <= n; ++i)
if (row[i] && col[i])
product += row[i] * col[i];
return product;
int main()
auto row = to_sparse_vec( 0, 0, 7, 0, 5, 0, 0, 8, 0, 4 );
auto col = to_sparse_vec( 0, 0, 0, 5, 6, 0, 0, 0, 0, 5 );
cout << "result=" << dotproduct(row, col) << endl;
这假定Vec
表示旨在作为“稀疏向量”。
结果是 50
(删除了 -1
元素)
【讨论】:
完美答案..如果仍然找到标志-1的OP可以使用coliru.stacked-crooked.com/view?id=2586943d91c247af并回答50 简化示例代码以提高可读性,删除 -1 元素 /cc @HariomSingh 地图的使用const
- 并且由于基于节点的容器std::map
而不会浪费空间【参考方案3】:
你可以简化你的代码
#include <iostream>
#include <vector>
using namespace std;
template<class InputIt1, class InputIt2, class T>
T dot_product(InputIt1 first1, InputIt1 last1,
InputIt2 first2, T value)
while ((first1 != last1)&&(*first1!=-1) && (*first2 !=-1))
value = value + *first1 * *first2;
++first1;
++first2;
return value;
const int n=10; /* vector size limit */
struct element
int x; /* original index of non-zero array element */
int val ; /* integer non-zero value at index x */
;
element row[n];
element col[n];
int i;
vector<int> a=0,0,7,0,5,0,0,8,0,4,-1;
vector<int> b=0,0,0,5,6,0,0,0,0,5,-1;
int main()
int r;
r=dot_product(a.begin(), a.end(), b.begin(), 0);
cout<<"result="<<r<<endl;
return 0;
输出
50
Demo
【讨论】:
那是不正确的结果。进一步简化:coliru.stacked-crooked.com/a/bc586f3a890ceab0 正确打印 51 @sehe 完美只添加了一个。他只想要正值,因此可以为负添加条件标志 我不确定我明白了,但无论如何。我希望OP实现他的目标 @sehe 我第一次看到库 valarray ..那是什么? 我个人不知道,因为我不知道你打算做什么。generate_row_and_col
的所有混乱,单独的 i++
和 j++
- 这对我来说都是魔法。规则一:代码是为人类设计的。意图表达优先于其他任何事情。【参考方案4】:
我已经对代码进行了一些更改,现在可以正常工作了。但是,在 generate_row_and_col 函数上初始化 row 和 col 数组时,我只用非零元素初始化索引,其余的没有初始化。这不会导致该程序出现任何错误,但就良好的编程习惯而言,那些值为 0 的索引不会被初始化,数组看起来像 (garbage,garbage,7,garbage,5,garbage,garbage.... )。我们可以只限制 generate_row_and_col 函数,所以我们只能存储非零值索引。 谢谢你
#include <iostream>
#include <vector>
using namespace std;
const int n=11; /* vector size */
struct element
int index; /* original index of non-zero array element */
int value ; /* integer non-zero value at index x */
;
element row[n];
element col[n];
vector<int> a=0,0,7,0,5,0,0,8,0,4,-1;
vector<int> b=0,0,0,5,6,0,0,0,0,5,-1;
void generate_row_and_col()
for (int i=0; i<n; i++)
if(a[i]!=0)
row[i].index=i;
row[i].value=a[i];
for (int j=0; j<n; j++)
if(b[j]!=0)
col[j].index=j;
col[j].value=b[j];
int dotproduct()
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].value!=-1 && col[j].value!=-1)
if(row[i].index == col[j].index)
product=product+row[i].value*col[j].value;
i++;
j++;
else if(row[i].index<col[j].index)
i++;
else
j++;
return product;
int main()
generate_row_and_col() ;
int r;
r=dotproduct();
cout<<"Dot Product = "<<r<<endl;
return 0;
【讨论】:
以上是关于向量数组,计算点积的主要内容,如果未能解决你的问题,请参考以下文章