【问题标题】:How to use memchr with 2 dimensional array?如何将 memchr 与二维数组一起使用?
【发布时间】:2017-08-22 11:13:51
【问题描述】:

我正在使用 Visual Studio 2008。

在 C++ 中,我可以使用 memchr 搜索一维数组中的元素。

char* pStart, char* pEnd;
 //find first available register
 char *pCur,*p1;
  pCur=p1=pStart;
 while(pCur<pEnd)
  {
    //find 0
    p1 = (char*)memchr(pCur,0x0,pEnd-pCur);
    pCur=p1;
  }

我有二维数组,例如整数数组[200][2].

如何使用 memchr 查找此数组中的所有 0 元素?

【问题讨论】:

  • 首先,memchr 中的chr 代表字符。您不能使用它来搜索 int 值。
  • 至于你的问题,为什么不简单地循环外部数组并检查一个或两个内部数组值是否为零?可以使用一些standard C++ algorithm function 来简化。
  • 它到底是什么语言?问题清楚地说明了 C++,但错误的标签已被删除
  • 你应该使用bsearch 而不是memchr

标签: c algorithm multidimensional-array find


【解决方案1】:

您根本不能在ints 的数组上使用memchr(),因为它们每个都大于一个字节。

此外,这听起来像是一个老式的 C 问题;在 C++ 中,您可能应该考虑使用一些更高级的容器类型。

对于 C 答案,您可能只需要遍历数组并进行搜索,这是最直接的方法。

【讨论】:

    【解决方案2】:

    函数memchr(从其名称而来)在字符数组中搜索字符。您不能使用它来查找int 类型的对象,因为该函数不处理此类对象。

    你应该自己写一个合适的函数。

    例如,它可以如下面的演示程序所示如下所示

    #include <stdio.h>
    
    int * find( const int *a, size_t n, int value )
    {
        const int *first = a;
    
        while ( first != a + n && *first != value ) ++ first;
    
        return first == a + n ? NULL : ( int * )first;
    }
    
    int main(void) 
    {
        int a[4][2] =
        {
            { 1, 2 },
            { 3, 0 },
            { 4, 5 },
            { 0, 6 }
        };
        const size_t M = sizeof( a ) / sizeof( *a );
        const size_t N = sizeof( *a ) / sizeof( **a );
    
        int value = 0;
        int *p = ( int * )a;
    
        for ( ; ( p = find( p, M * N - ( p - ( int * )a ), value ) ) != NULL; ++p )
        {
            size_t m = ( p - ( int * )a ) / N;
            size_t n = ( p - ( int * )a ) % N;
    
            printf( "a[%zu][%zu] is equal to %d\n", m, n, value );
        }
    
        return 0;
    }
    

    程序输出是

    a[1][1] is equal to 0
    a[3][0] is equal to 0
    

    使用此函数,您可以在任何多维整数数组中找到任何值。

    该函数只是将多维数组解释为一维数组并返回指向搜索元素的指针。您可以使用此指针计算此元素的“坐标”,并了解数组的维度,如演示程序中二维数组所示。

    通过类比标准 C 函数bsearch,您可以编写一个通用搜索函数来处理任何整数类型的数组。

    例如

    #include <stdio.h>
    #include <string.h>
    
    void * find( const void *value, const void *base, size_t nmemb, size_t size )
    {
        const unsigned char *first = base;
    
        while ( first != ( const unsigned char * )base + nmemb * size && 
                memcmp( first, value, size ) != 0 ) first += size;
    
        return first == ( const unsigned char * )base + nmemb * size ? NULL : ( void * )first;
    }
    
    int main(void) 
    {
        int a[4][2] =
        {
            { 1, 2 },
            { 3, 0 },
            { 4, 5 },
            { 0, 6 }
        };
        const size_t M = sizeof( a ) / sizeof( *a );
        const size_t N = sizeof( *a ) / sizeof( **a );
    
        int value = 0;
    
        for ( int *p = ( int * )a; ( p = find( &value, p, M * N - ( p - ( int * )a ), sizeof( int ) ) ) != NULL; ++p )
        {
            size_t m = ( p - ( int * )a ) / N;
            size_t n = ( p - ( int * )a ) % N;
    
            printf( "a[%zu][%zu] is equal to %d\n", m, n, value );
        }
    
        return 0;
    }
    

    程序输出同上图

    a[1][1] is equal to 0
    a[3][0] is equal to 0
    

    在 C++ 中,您可以使用相同的方法将多维数组重新解释为一维数组,并应用标头 &lt;algorithm&gt; 中声明的标准算法 std::find

    【讨论】:

      【解决方案3】:

      数组是一块连续的内存,它有多少维并不重要。

      2D 示例

      更通用的一个:

      void *mymemobj(void *haystack, void *needle, size_t objectsize, size_t elements)
      {
          size_t cursor = 0;
          while (cursor < elements)
          {
              if (!memcmp(haystack, needle, objectsize)) return haystack;
              haystack = ((uint8_t *)haystack + objectsize);
              cursor++;
          }
          return NULL;
      }
      
      char *findInTwoDimentionalArray(void *array, void *needle, size_t objectsize, size_t rows, size_t columns, int *x, int *y)
      {
          int result = 0;
          void *tmp = my_memobj(array, needle, objectsize, rows * columns);
      
          if (tmp == NULL)
          {
              *x = -1;
              *y = -1;
              result = -1;
          }
          else
          {
              size_t pos = ((uint8_t *)tmp - (uint8_t *)array) / objectsize;
              *x = pos % columns;
              *y = pos / columns;
          }
          return tmp;
      }
      

      或者只是字符

      char *findInTwoDimentionalArray(char *array, int val, int rows, int columns, int *x, int *y)
      {
          char *tmp = memchr(array, value, rows * columns);
      
          if (tmp == NULL)
          {
              *x = -1;
              *y = -1;
          }
          else 
          { 
              size_t pos = tmp - array;
              *x = pos % columns;
              *y = pos / columns;
          }
          return tmp;
      }
      
      
      void printAll(int val)
      {
          char array[20][50];
      
          char *tmp = &array[0][0];
          int x, y;
      
          while (tmp < (&array[0][0] + 20 * 50) && (tmp = findInTwoDimentionalArray(tmp, val, 20, 50, &x, &y)) != NULL)
          {
              printf("value %d was found at x = %d and y = %d\n", val, x, y);
              tmp++;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-03-24
        • 2012-02-21
        • 2016-04-11
        • 1970-01-01
        • 2015-07-30
        • 2020-10-24
        • 2011-05-06
        • 1970-01-01
        • 2014-03-06
        相关资源
        最近更新 更多