如何递归比较向量?

时间:2014-10-14 05:12:09

标签: c++ loops recursion

我试图编写一个递归检查给定向量A是否在向量B中的任何连续块中的函数。例如,如果A={5,6,7}B={1,2,3,4,5,6,7},它应该返回true 。如果B = {1,2,3,4,5,7,6},则应返回false。目前,我的代码一直在输出true,因为我认为我的逻辑是正确的。我还没能修改它以产生任何结果。任何帮助将不胜感激!

bool r_app(vector<int>& a1, vector<int> b1, size_t k)
{
    k=0;

    if (a1.size() == 0) {
        cout << "true";
        return true;;
    }

    for (int i=0;i<a1.size();i++){
        for(int j=0;j<b1.size();j++){  
            if (a1.at(i)==b1.at(j)) {
                cout << "true" << endl;
                return true;
            }   
        }
        cout << "false" << endl;
        return false;    

        return r_app(a1,b1,k+1);   
    }
}

编辑:所以这就是我从Smac89获得的,我添加了cout行,这样当我在main中调用该函数时,它输出true或false。该函数当前为每个真正的输入输出true,但不输出false ..我不知道为什么。

bool r_app(std::vector<int>& a1, std::vector<int> &b1, std::size_t start)
{
    std::size_t savedPos = start + 1, k = 0;

    for (; k < a1.size() && start < b1.size() && a1[k] == b1[start]; 
         k++, start++)
    {
            if (k != 0 && a1[0] == b1[start])
                savedPos = start;
    }
    if (k == a1.size())
        cout << "true" << endl;
        return true;
    if (start < b1.size())
        return r_app(a1, b1, savedPos);

    cout << "false" << endl;  
    return false;
}

4 个答案:

答案 0 :(得分:1)

template <typename T>
bool r_app(std::vector<T>& a1, std::vector<T> &b1, std::size_t start) {
    std::size_t savedPos = start + 1, k = 0;

    for (; k < a1.size() && start < b1.size() && a1[k] == b1[start]; 
         k++, start++)
    {
            if (k != 0 && a1[0] == b1[start])
                savedPos = start;
    }
    if (k == a1.size())
        return true;
    if (start < b1.size())
        return r_app(a1, b1, savedPos);

    return false;
}

template <typename T>
bool r_app(std::vector<T>& a1, std::vector<T>& b1) {
    return r_app(a1, b1, 0);
}

实施例: http://rextester.com/COR69755

编辑: V2 现在更有效的搜索 - 开始搜索上次搜索结束的位置或搜索字符串开头的字符

您还可以通过查看savedPos - 1

打印出第一场比赛的位置

答案 1 :(得分:1)

如果你想以递归的方式做所有事情,你需要 1 两个递归函数。

测试是否在特定点发现序列,以及使用其他函数测试每个点的相等性。这是一个简单的模板实现,可以使用任何允许迭代的STL容器,以及非STL序列(例如原始数组):

template <typename NeedleIterator, typename HaystackIterator = NeedleIterator>
bool recursive_sequence_equals(
    NeedleIterator needle_begin,
    NeedleIterator needle_end,
    HaystackIterator haystack_begin,
    HaystackIterator haystack_end)
{
    // The sequences are equal because we reached the end of the needle.
    if (needle_begin == needle_end) {
        return true;
    }

    // If we reached the end of the haystack, or the current elements are not equal
    // then the sequences are not equal here.
    if (haystack_begin == haystack_end || *needle_begin != *haystack_begin) {
        return false;
    }

    // We are not at the end of the haystack nor the needle, and the elements were
    // equal.  Move on to the next element.
    return recursive_sequence_equals(
        ++needle_begin, needle_end,
        ++haystack_begin, haystack_end);
}

template <typename NeedleIterator, typename HaystackIterator = NeedleIterator>
HaystackIterator recursive_sequence_find(
    NeedleIterator needle_begin,
    NeedleIterator needle_end,
    HaystackIterator haystack_begin,
    HaystackIterator haystack_end)
{
    // We reached the end with no match.
    if (haystack_begin == haystack_end) {
        return haystack_begin;
    }

    // If the sequences are equal at this point, return the haystack iterator.
    if (recursive_sequence_equals(needle_begin, needle_end,
                                  haystack_begin, haystack_end)) {
        return haystack_begin;
    }

    // Check the next position in the haystack.
    return recursive_sequence_find(
        needle_begin, needle_end,
        ++haystack_begin, haystack_end);
}

像这样使用:

std::vector<int> a = { 5, 6, 7 };
std::vector<int> b = { 1, 2, 3, 4, 5, 6, 7 };

auto found = recursive_sequence_find(
    a.begin(), a.end(),
    b.begin(), b.end());

if (found != b.end()) {
    // There was a match, found is an iterator to the beginning of the match in b.
} else {
    // No match.  (Or both containers were empty!)
}

Demo


1 从技术上讲,如果使用一些额外的参数来表示您是否处于相等测试中,则可以使用一个函数执行此操作。然而,这给逻辑增加了许多额外的复杂性,没有增益。使用两个不同的递归函数实现它更容易,更直接。

答案 2 :(得分:0)

#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
bool r_app(vector<int> a, vector<int> b, int starta, int startb)
{
    if(a.size() == 0) return 0;
    if(starta == 0) {
        int i=0;
        while(1) {
            while(a[0] != b[i] && i < b.size())
                i++;
            if(i >= b.size()) return 0;
            if(r_app(a, b, starta+1, i+1) == 1)
                return 1;
            else i++;
        }
    }
    else {
        if(starta == a.size())
            return 1;
        else if(startb == b.size())
            return 0;
        else if(a[starta] == b[startb])
            return r_app(a, b, starta+1, startb+1);
        else
            return 0;
    }   
}
int main() {
    vector<int> a;
    vector<int> b;
    b.push_back(1);
    b.push_back(2);
    b.push_back(3);
    b.push_back(4);
    b.push_back(5);
    a.push_back(3);
    a.push_back(4);
    cout << r_app(a,b,0,0);
    return 0;
}

如果不使用递归会更容易。此外,KMP算法将为您提供更多优化的解决方案。

答案 3 :(得分:0)

我的尝试,使用iterator

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

template<typename Iter>
bool r_app(Iter first_a, Iter last_a, Iter first_b, Iter last_b)
{
    if(first_a == last_a)   //trivial case
        return true;

    auto found = std::find(first_b, last_b, *first_a);
    if(found == last_b)
        return false;
    else
        return r_app(++first_a, last_a, found, last_b);   //recursion
}

int main()
{
    std::vector<int> a{5,6,7};
    std::vector<int> b{1,2,3,4,5,6,7};
    std::cout << r_app(a.begin(),a.end(),b.begin(),b.end());

    return 0;
}