【问题标题】:std::search to find a rightmost subsequencestd::search 找到最右边的子序列
【发布时间】:2021-03-25 23:28:50
【问题描述】:

我试图在std::searchstd::make_reverse_iterator 的范围内找到最右边的子序列。

然而,返回的迭代器总是指向一个范围的开始。我做错了什么?

TEST(basic_test, find_from_right)
{
    std::vector<uint8_t> array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::array<uint8_t, 2> subSeq{3, 4};

    auto found = std::search(std::make_reverse_iterator(array.cend()),
                             std::make_reverse_iterator(array.cbegin()),
                             subSeq.cbegin(),
                             subSeq.cend());
// makes no difference
//                             std::make_reverse_iterator(subSeq.cend()),
//                             std::make_reverse_iterator(subSeq.cbegin()));


    auto distance = std::distance(found.base(), array.cbegin());

    EXPECT_EQ(distance, 3);
}

输出:

Failure
Expected equality of these values:
  distance
    Which is: 0
  3

我有一个带有 2 个模板 RandomIterators 的函数,所以我必须调用 std::make_reverse_iterator。这些容器只是为了重现问题和编译示例。

【问题讨论】:

  • 您正在向后搜索,因此您的向量中不存在序列 3、4。如果您搜索 4、3,它应该可以工作。
  • @john 那么当我使用反向迭代器搜索子序列时未注释的代码呢?它仍然没有找到任何东西。
  • 试过调试了吗?你的发现在哪里?
  • 如果您使用反向迭代器,但希望偏移到搜索到的子序列的开头,那么您需要考虑子序列长度。 Example here。公平警告:在进行最终计算之前,请确保确实找到了您的子序列。
  • @john 好吧,如果我搜索{4, 3} 的子序列,它确实会找到指向第四个元素的reverse_iterator。我觉得可以算是一个答案

标签: c++ algorithm c++11 c++14


【解决方案1】:

我认为这可以解决你的问题(如果你对 C++17 没问题的话):

来自https://en.cppreference.com/w/cpp/algorithm/find_end

#include <algorithm>
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v{1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
    std::vector<int>::iterator result;
 
    std::vector<int> t1{1, 2, 3};
 
    result = std::find_end(v.begin(), v.end(), t1.begin(), t1.end());
    if (result == v.end()) {
        std::cout << "sequence not found\n";
    } else {
        std::cout << "last occurrence is at: "
                  << std::distance(v.begin(), result) << "\n";
    }
 
    std::vector<int> t2{4, 5, 6};
    result = std::find_end(v.begin(), v.end(), t2.begin(), t2.end());
    if (result == v.end()) {
        std::cout << "sequence not found\n";
    } else {
        std::cout << "last occurrence is at: " 
                  << std::distance(v.begin(), result) << "\n";
    }
}

所以在你的情况下:

    auto result = std::find_end(array.begin(), array.end(), subSeq.begin(), subSeq.end());
    if (result == array.end()) {
        std::cout << "sequence not found\n";
    } else {
        std::cout << "last occurrence is at: "
                  << std::distance(array.begin(), result) << "\n";
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 2020-04-14
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多