确定一个数组是否包含在另一个数组中

时间:2011-09-20 10:22:54

标签: c++ arrays

如何确定另一个数组中是否包含一个数组(按元素排序)?我在MSVS 2010中编写了以下程序,但不太确定如何完成布尔函数,以确定是否有一个数组出现在另一个数组中

void isContained( int ar1[], int ar2[] );


int main( int argc, char** argv )
{
    ifstream fin1( "one.txt" );
    ifstream fin2( "two.txt" );

    int i, j, value1, value2;
    int arr1[ 10 ];
    int arr2[ 10 ];

    for ( i = 0 ; fin1 >> value1 ; i++ )
    {
        arr1[ i ] = value1;
    }

    for ( j = 0 ; fin2 >> value2 ; j++ )
    {
        arr2[ j ] = value2;
    }

    isContained( arr1, arr2 );

    system( "PAUSE" );
}


void isContained( int ar1[], int ar2[] )
{
    ???
}

6 个答案:

答案 0 :(得分:4)

你所追求的本质上是一个字符串搜索算法(除了在你的情况下你的“字符”是数组的整数元素)。

存在各种此类算法,请参阅Wikipedia

就你目前的代码而言:

  1. 您可能希望确保在两个for循环中没有超出数组的末尾。
  2. 您需要将两个数组的大小传递给isContained(其返回类型可能不应为void)。

答案 1 :(得分:2)

简单。假设您要检查ar2中是否包含ar1

一个例子:

Ar1: 1 2 3 4 5 6 7 8 9 10 5 2 8 2 4 2 4 6 2 9 1
Ar2: 2 4 6 2

我们还假设您拥有Ar1_lenAr2_len

中数组的长度

你必须经过Ar1,找到一个与Ar2的第一个元素相匹配的元素,然后从那里开始,尝试查看所有元素是否匹配。如果没有,请继续Ar1以查找与Ar2的第一个元素匹配的其他元素

所以基本上代码看起来像这样:

if (Ar2_len == 0)
    return true;
for (unsigned int i = 0; i < Ar1_len-(Ar2_len-1); ++i)
    if (Ar1[i] == Ar2[0])
    {
        bool matches = true;
        for (unsigned int j = 1; j < Ar2_len; ++j)
            if (Ar1[i+j] != Ar2[j])
            {
                matches = false;
                break;
            }
        if (matches)
            return true;
    }

请注意,i转到Ar1_len-(Ar2_len-1),因为如果你在Ar1末尾太远(剩下少于Ar2_len个元素),那么显然无法找到Ar2

第二点是,这不是最有效的方法。最有效的方法是从Ar2构建DFA并使用Ar1作为输入并跟踪它。如果它达到最终状态return true。这可能有点复杂,但如果您感兴趣,可以在字符串匹配中查找算法。

最后需要注意的是,此处提供的代码不适用于复制粘贴。它可能缺乏足够的错误检查,只是为了给你这个想法。

答案 2 :(得分:1)

您可以在包含数组中找到使mismatch返回包含数组末尾的位置:

using namespace std;

template<typename OutIt, typename SeqIt>
OutIt find_sequence( OutIt outer_begin   , OutIt outer_end, 
                     SeqIt sequence_begin, SeqIt sequence_end ){
   assert( 
        distance(outer_begin,outer_end) >= distance(sequence_begin,sequence_end);

   // limit the possible iterator positions:
   OutIt outer_limit = outer_begin;
   advance( outer_limit, distance(sequence_begin, sequence_end) );

   for( OutIt outer_it = outer_begin; outer_it != outer_limit; ++outer_it ) 
   {
     if( mismatch( sequence_begin, sequence_end, outer_it ).first==sequence_end) 
     {
          return outer_it;
     }
   }
   // none found...
   return outer_end;
}

并像这样使用它:

 int values[]  = { 1,2,3,4,5, 6 };

 int pattern[] = { 3,4,5 };

 int* pFound = find_sequence( values, end(values), pattern, end(pattern) );
 bool bFound = pFound != std::end(values);

答案 3 :(得分:0)

使用该功能的原型是不可能的。

当传递给函数时,数组会衰减为指针,因此该函数无法确定数组中有多少元素。

答案 4 :(得分:0)

您可以使用std::search中的<algorithm>模板搜索其他序列中的子序列。注意:我修改了函数签名以传递数组大小。

bool isContained(int ar1[], int size1, int ar2[], int size2)
{
    return std::search(ar1, ar1 + size1, ar2, ar2 + size2) != (ar1 + size1);
}

答案 5 :(得分:-1)

这与搜索字符串中的子字符串相同。我们在那里比较字符,这里我们将比较数字或数组元素。

寻求KMP 1算法来解决这些问题。

相关问题