交叉连接两个向量的元素以产生第三个向量
Posted
技术标签:
【中文标题】交叉连接两个向量的元素以产生第三个向量【英文标题】:Cross Concatenate Elements of 2 Vectors to Produce a Third 【发布时间】:2017-06-16 13:15:06 【问题描述】:我有 2 个向量,想将一个分布在另一个向量上以形成第三个向量,例如:
V1 = (a,b,c)
V2 = (d,e,f)
结果:
V3 = (ad,ae,af,bd,be,bf,...cf) 'nine total elements
我知道如何做到这一点的唯一方法是循环。我尝试了多种不同的方法,但找不到“一行代码”的解决方案,以避免循环。
如果我错过了,请指出。我可能没有找到正确的搜索参数。
如果不可能,请原谅我的痛苦,让我知道:,,,(。
如果有答案,请分享。
【问题讨论】:
请先选择一种特定的语言。ad
和其他人是两个实数的乘法、两个字符串的连接、连接成有序对还是其他什么?
考虑到V3
实际上是V1
和V2
的矩阵乘积(如果矩阵是逐行存储的)并假设元素是int
、float
,或double
,你可以看看Eigen library。对于 Intel 的 x86 架构,它使用(或至少可以使用)SSE instructions 来获得性能。它是在 C++ 中实现的,并且具有多种语言的绑定,其中包括 R 和 Python。
【参考方案1】:
您没有明确ab
的操作是什么意思。我在这里假设您想将两个实数相乘。
在 Python 中,您可以使用推导式。这里有完整的代码sn-p。
v1 = (2, 3, 5)
v2 = (7, 11, 13)
v3 = tuple(x * y for x in v1 for y in v2)
v3
的值是
(14, 22, 26, 21, 33, 39, 35, 55, 65)
如你所愿。如果你想要一个 Python 列表,代码看起来更简单:使用
v3 = [x * y for x in v1 for y in v2]
如何将操作更改为连接或其他任何所需的操作将是显而易见的。以下是字符串连接的示例代码:
v1 = ('a', 'b', 'c')
v2 = ('d', 'e', 'f')
v3 = tuple(x + y for x in v1 for y in v2)
导致
('ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf')
您也可以使用itertools
模块中的product()
(我在此答案的第一个版本中使用过),但上述方法似乎更容易。
【讨论】:
【参考方案2】:在 R 中:as.vector(sapply(V1, function(x) paste0(x, V2)))
【讨论】:
【参考方案3】:在 C++ 中:
std::vector<decltype(v1.front() * v2.front())> v3 v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2], v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2], v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2] ;
...不过,我通常会将其格式化为多行。
作为 MCVE:
#include <iostream>
#include <vector>
using namespace std;
template <typename ELEM>
ostream& operator << (ostream &out, const vector<ELEM> &vec)
const char *sep = " ";
for (const ELEM &elem : vec) out << sep << elem; sep = ", ";
return out << " ";
int main()
vector<double> v1 1.0, 2.0, 3.0 , v2 4.0, 5.0, 6.0 ;
// in one line:
vector<decltype(v1.front() * v2.front())> v3 v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2], v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2], v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2] ;
// output:
cout << v3 << endl;
// done
return 0;
输出:
4, 5, 6, 8, 10, 12, 12, 15, 18
(在ideone上测试。)
感谢 Rory Daulton 的启发。在 C++ 中,我也可以这样做:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string operator*(const string &str1, const string &str2)
return str1 + str2;
template <typename ELEM>
ostream& operator << (ostream &out, const vector<ELEM> &vec)
const char *sep = " ";
for (const ELEM &elem : vec) out << sep << elem; sep = ", ";
return out << " ";
int main()
vector<string> v1 "a", "b", "c" , v2 "d", "e", "f" ;
// in one line:
vector<decltype(v1.front() * v2.front())> v3 v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2], v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2], v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2] ;
// output:
cout << v3 << endl;
// done
return 0;
输出:
ad, ae, af, bd, be, bf, cd, ce, cf
经过一点改进,它甚至可以用于混合类型:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string operator*(const string &arg1, int arg2)
string ret; for (int i = 0; i < arg2; ++i) ret += arg1;
return ret;
template <typename ELEM>
ostream& operator << (ostream &out, const vector<ELEM> &vec)
const char *sep = " ";
for (const ELEM &elem : vec) out << sep << elem; sep = ", ";
return out << " ";
int main()
vector<string> v1 "a", "b", "c" ; vector<int> v2 1, 2, 3 ;
// in one line:
vector<decltype(v1.front() * v2.front())> v3 v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2], v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2], v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2] ;
// output:
cout << v3 << endl;
// done
return 0;
输出:
a, aa, aaa, b, bb, bbb, c, cc, ccc
【讨论】:
谢谢大家的回答。对于我的表述不够清晰,我深表歉意,但我应该更具体地说明这三个向量是需要串联的字符串。 各种语言的额外信息也会对我有用,所以时间和精力并没有完全浪费。 @Michaelk87 我不明白“没有完全浪费”。 Rory Daulton 的 Python 解决方案确实提到了字符串的连接以及我在 C++ 中的连接(第二个示例),即使您没有提到字符串连接实际上是预期的。 (我什至不会排除 R 中的解决方案,因为它可能取决于function(x)
它的实际作用,但这只是推测。)
不,我的意思是我实际上在阅读帖子之前就已经弄清楚了,所以我担心我会浪费你的时间来问一个我找到解决方案的问题。当我问我应该已经知道或能够推理出什么时,我讨厌。我才刚刚开始写东西,并且知道最终我会扩展到 python 之外的其他语言,所以我很欣赏超越 python 的答案。很抱歉造成混乱,感谢您的帮助。
也很抱歉,我没有提到我正在使用 Python 工作。我必须放慢脚步,更多地关注细节。哈哈。我似乎无法克服的性格缺陷。以上是关于交叉连接两个向量的元素以产生第三个向量的主要内容,如果未能解决你的问题,请参考以下文章
如何在向量的两个连续元素之间产生差异,如果差异小于 10,则删除以两个零结尾的一个