模板函数以查找C++中的子数组

template function to find subarray in C++

本文关键字:数组 C++ 查找 函数      更新时间:2023-10-16
#include <iostream>
#include <string>
using namespace std;
template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
{
    int i,j;
    bool found;
    int k;
    T& s=a,l=b;
    int s_len = (a_len < b_len) ? a_len : b_len; // find the small array length
    if (s_len == a_len) // check to set pointers to small and long array
    {
        s = a;
        l = b;
    }
    else
    {
        s = b;
        l = a;
    }

    for (i = 0; i <= a_len-s_len; i++) //loop on long array
    {
        found = true;
        k=i;
        for (j=0; j<s_len; j++) // loop on sub array
        {
            if (s[j] != l[i])
            {
                found = false;
                break;
            }
            k++;
        }
    }
    if (found)
      return i;
    else
      return -1;
}

/******* main program to test templates ****/
int main()
{
    int array[5] = {9,4,6,2,1};
    int alen = 5;
    int sub_arr[3] = {6,2,1};
    int slen = 3;
    int index= 0;
    index = IsSubArr(array,alen,sub_arr,slen);
    cout << "nn Place of sub array in long array: " << index;
    cout << endl;
    return 0;
}

对于此行代码:

index = IsSubArr(array,alen,sub_arr,slen);

我收到错误:

Error   1   error C2782: 'int IsSubArr(T &,int,T &,int)' : template parameter 'T' is ambiguous  

请帮助解决此问题?

由于array[a]array[b]其中a != b是两种不同的类型,因此您需要 2 种类型模板参数。
解决方法是使用指针。

+ template <class T> int IsSubArr(T* a, int a_len, T* b, int b_len)
+ T* s = a; T*l = b;

您将第一个和第三个参数定义为引用

template <class T> int IsSubArr(T& a, int a_len, T& b, int b_len)
                                ^^^^             ^^^^

并将两个不同类型的数组作为这些参数的参数传递

int array[5] = {9,4,6,2,1};
int sub_arr[3] = {6,2,1};
//...
index = IsSubArr(array,alen,sub_arr,slen);
                 ^^^^^      ^^^^^^^   

第一个参数的类型为 int[5],第三个参数的类型为 int[3]

因此,编译器无法推断引用的类型 T。

如果你打算在函数中使用数组,那么你可以像

template <class T, size_t N1, size_t N2> 
int IsSubArr( T ( &a )[N1], T ( &b )[N2] );

或者您可以使用指针而不是对数组的引用

template <class T> int IsSubArr( T *a, size_t a_len, T *b, size_t b_len );

考虑到函数中的此声明

T& s=a,l=b;

也是错的。它等效于以下声明

T& s=a;
T l=b;
这是第一个声明声明对数组

的引用,而第二个声明声明一个数组并尝试用另一个数组初始化它。但是,数组没有复制构造函数,编译器将再发出一个错误。并且您不能重新分配引用。

您应该知道,在标头<algorithm>中声明了标准算法std::search可以完成您想要使用函数执行的工作。

这是因为arraysub_arr是两种不同的类型。 array 属于 int[5] 型,而sub_arr属于 int[3] 型。数组维度是类型的一部分。

要么

将函数更改为使用两个不同的模板参数,每个数组一个,要么使用指针(例如 T* (


还有一个错误,如果你继续使用数组和两个不同的模板参数,你将继续遇到,那就是你不能改变引用。一旦你分配给函数中的变量sl,就不能让它们引用其他任何东西。sl变量的后一种赋值将失败,因为在那里您尝试将数组相互赋值,而您无法这样做,您只能复制数组。

如果您改用指针,那么这不会有问题。