【问题标题】:c++ get vector by indices of vector by std::transformc++ 通过 std::transform 的向量索引获取向量
【发布时间】:2019-11-22 09:51:24
【问题描述】:

有两个向量: Indices 向量保存着我们想从 dataHolder 中获取的索引

std::vector<int> indices{ 2, 3, 7 };

dataHolder 向量保存数据项。可以是任意大小

std::vector<std::wstring> dataHolder{ L"10 kz", L" 20 khz", L"100 khz", L"1 hz", L"5 hz" };

从dataHolder向量中获取结果向量

Example : resultvector{L"100 khz", L"1 hz"}

这样的算法用2个循环写是没问题的。

有没有使用 std::transform 的解决方案?

它可能关注的对象:

当前的实现

#include "pch.h"
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> indices{ 2, 3, 7 };
    std::vector<std::wstring> dataHolder{ L"10 kz", L" 20 khz", L"100 khz", L"1 hz", L"5 hz" };

    std::vector<std::wstring> result;
    for (int index = 0; index < dataHolder.size(); index++)
    {
        if (std::any_of(indices.begin(), indices.end(), [&](int dataVal) { return index == dataVal; }))
            result.push_back(dataHolder.at(index));
    }
}

我认为这具有二次复杂性。所以我正在寻找关于 std::transform 的建议。如果有帮助!

【问题讨论】:

  • 如何获得resultvector?其中的两个元素是如何从dataHolder中挑选出来的,indices起到什么作用?你目前的算法是什么?
  • 目前我用简单的 for 循环遍历 dataHolder 项目,然后用另一个内部循环在索引向量中找到索引。这就是为什么我提到这可以用 2 循环来完成。 resultvector 是预期的输出向量。
  • 你能给我们看看吗?请创建您当前算法的minimal reproducible example,显示的resultvector 是如何填充的。 indices 中有三个值,这如何转换为resultvector 中的两个值? “索引”7 如何适合您的五元素 dataHolder 向量?
  • 实际问题是什么?为什么你需要使用std::transform?这两个循环有什么问题?而且,你的算法实际上是做什么的?起初我认为它采用第一个向量中的索引并在这些索引处提取第二个向量的条目。但这显然只需要一个循环,并且与您的示例不匹配(索引向量有三个条目,结果向量有两个)。您确实应该向我们展示代码,然后谈谈为什么该代码不够用(例如“时间复杂度太高”)。
  • @Someprogrammerdude 请查看当前实现的编辑。我认为这很简单。

标签: c++


【解决方案1】:

据我所知,您需要做的就是遍历indices 向量并将dataHolder 向量中的相应元素添加到result

类似

std::vector<int> indices{ 2, 3, 7 };
std::vector<std::wstring> dataHolder{ L"10 kz", L" 20 khz", L"100 khz", L"1 hz", L"5 hz" };

std::vector<std::wstring> result;
result.reserve(indices.size());  // Pre-allocate memory

for (auto index : indices)
{
    if (index >= 0 && index < dataHolder.size())
        result.push_back(dataHolder[index]);
}

不需要std::transform 或循环嵌套。并且索引有效性检查解决了indices向量中的无效索引7的问题。

【讨论】:

  • 你为什么要分配内存?如果我们不这样做不是更好吗?全部容量可能仍未使用。
  • @sohel14_cse_ju indices 向量中存在无效索引的概率是否高于有效索引?即使有,是否值得在循环内可能重新分配的性能损失?您似乎对性能和效率感兴趣,那么为什么不通过交换一些内存来使其尽可能高效呢?考虑到即使在相当古老的计算机上,result 中的数千个“浪费”元素也有足够的内存,因此交易可能是值得的。由你决定。
【解决方案2】:

可以使用std::transform 完成,但它必须返回一个值。

在我的示例中,您必须在转换后删除所有空字符串,因为如果索引超出范围,我会返回一个空字符串:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

using namespace std;

int main() 
{
    std::vector<int> indices{ 2, 3, 7 };
    std::vector<std::wstring> dataHolder{ L"10 kz", L" 20 khz", L"100 khz", L"1 hz", L"5 hz" };

    std::vector<std::wstring> result;

    std::transform(indices.begin(), indices.end(), std::back_inserter(result),&dataHolder](const auto& index) {
        if (index < dataHolder.size())
            return dataHolder.at(index);

        return std::wstring{};
    });

    result.erase(std::remove_if(result.begin(), result.end(), [](const auto& result){
            return result.empty();
        }), result.end());

    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-03-01
    • 2013-02-07
    • 2010-10-14
    • 1970-01-01
    • 2013-02-01
    • 2023-01-02
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多