【问题标题】: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实际上是V1V2的矩阵乘积(如果矩阵是逐行存储的)并假设元素是intfloat,或double,你可以看看Eigen library。对于 Intel 的 x86 架构,它使用(或至少可以使用)SSE instructions 来获得性能。它是在 C++ 中实现的,并且具有多种语言的绑定,其中包括 RPython

标签: python c++ r vector


【解决方案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 工作。我必须放慢脚步,更多地关注细节。哈哈。我似乎无法克服的性格缺陷。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多