【问题标题】:How to know how many pattern segments are in the array?如何知道数组中有多少个模式段?
【发布时间】:2020-02-11 05:31:18
【问题描述】:

所以基本上我的问题是: 我收到一个整数数组和一个要查找的整数模式数组。 我需要返回第一个数组中有多少个模式段。

例如:

v=[5,  2,  2,  3,  4,  4,  4,  4,  1,  1, 2, 2] 
p=[2, 2]

这需要返回类似“v 中有 2 段 p”。

我已经尝试过了,但我认为这不是正确的方法:

int main()
{
   int v[] ={5,  2,  2,  3,  4,  4,  4,  4,  1,  1, 2, 2};
   int p[] ={2,2};
   int sizev, sizep;
   printf("%d", count_segments_repeated_ints(v,sizev,p,sizep));
   return 0;
}


int count_segments_repeated_ints(int v[], int sizev, int p[], int sizep){

    int i,j, ocr=0;
    //sizeof
    for(i=0; i < sizev; i++){
        for(j=0; j < sizep; j++){
            if(v[i]==p[j] && v[i+1]==p[j+1]){
                ocr++;
            }
        }
        return ocr;
    }
}

【问题讨论】:

  • {1, 2, 2, 2, 3} 中有多少个p
  • 使用int sizev = sizeof(v) / sizeof(v[0]);。最好使用类型size_t 而不是int,即size_t sizev = sizeof(v) / sizeof(v[0]);。对count_segments_repeated_ints 的参数使用相同的类型。
  • @pmg 如果我们认为 p 是一个静态数组并且始终保持这样,我认为答案将是 2。如果 p 是它的重新维度而不是特定于这两个数字,这取决于。
  • 我只是想确保v 的相同元素可以属于不同的段......问题也可以禁止这样做,并且您的示例不够具体。

标签: c arrays function definition sub-array


【解决方案1】:

有点不同的解决方案是只使用一个循环并检查是否相等并在数字匹配时增加j-indexer。如果j-indexer 变得大于或等于sizep,则存在匹配,因此增加ocr。否则重新从 0 开始。

int i, j = 0, ocr = 0;

if (sizep > sizev) return 0;

for (i = 0; i < sizev; i++)
{
  if (v[i] == p[j]) j++;
  else
  {
    if (j > 0) i--;
    j = 0;
  }

  if (j >= sizep)
  {
    ocr++;
    j = 0;
    // If overlapping segments are allowed uncomment the following line:
    // i -= sizep - 1;
  }
}

return ocr;

【讨论】:

    【解决方案2】:

    首先,你需要在sizev - sizep之前停止外循环,这样你就不能访问v数组之外。

    其次,您的内部循环为每个匹配的字符递增ocr。如果 all 的字符匹配,它应该只增加它。并且您只需要比较v[i+j]p[j]

    第三,return ocr; 不应该在循环内。

    int count_segments_repeated_ints(int v[], int sizev, int p[], int sizep){
    
        int i,j, ocr=0;
        for(i=0; i < sizev-sizep; i++){
            for(j=0; j < sizep; j++){
                int all_match = 1;
                if(v[i+j] != p[j]){
                    all_match = 0;
                    break;
                }
            }
            ocr += all_match;
        }
        return ocr;
    
    }
    

    【讨论】:

      【解决方案3】:

      对于程序中的初学者,变量sizevsizep 未初始化。

      一般sizep在函数内可以大于sizev甚至可以等于0

      由于封闭的 if 语句导致的循环

          for(j=0; j < sizep; j++){
              if(v[i]==p[j] && v[i+1]==p[j+1]){
                  ocr++;
              }
      

      调用未定义的行为,因为此表达式p[j+1] 中的索引值可以指向数组外部。此外,带有模式的数组可以包含更多的元素,而不仅仅是两个元素。

      该函数可以按照以下方式定义,如演示程序中所示。我重命名了函数,因为这个名称count_segments_repeated_ints 与分配不对应。

      #include <stdio.h>
      
      size_t count_sub_arrays( const int a1[], size_t n1, const int a2[], size_t n2 )
      {
          size_t count = 0;
      
          if ( !( n1 < n2 ) && n2 != 0 )
          {
              for ( size_t i = 0, n = n1 - n2; i <= n; )
              {
                  while ( i <= n && a1[i] != a2[0] ) ++i;
      
                  if ( !( n < i ) )
                  {
                      size_t j = 1;
      
                      while ( j < n2 && a1[i + j] == a2[j] ) j++;
      
                      if ( j == n2 )
                      {
                          ++count;
                          i += n2;
                      }
                      else
                      {
                          ++i;
                      }
                  }
              }
          }
      
          return count;
      }
      
      int main(void) 
      {
         int a1[] = { 5,  2,  2,  3,  4,  4,  4,  4,  1,  1, 2, 2 };
         int a2[] = { 2, 2 }; 
         const size_t N1 = sizeof( a1 ) / sizeof( *a1 );
         const size_t N2 = sizeof( a2 ) / sizeof( *a2 );
      
      
         printf( "%zu\n", count_sub_arrays( a1, N1, a2, N2 ) );
      
         return 0;
      }
      

      程序输出是

      2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-04
        • 1970-01-01
        • 2019-05-12
        • 2021-08-15
        • 2021-08-04
        • 1970-01-01
        • 2020-03-25
        相关资源
        最近更新 更多