繁体   English   中英

使用指针合并两个排序的 arrays 时出现问题

[英]Problem in merging two sorted arrays using pointers

我正在尝试使用指针合并两个已排序的 arrays。 第三个循环将食物处理到第一个 arr[5],然后显示垃圾值。 是排序技术错误还是我使用的指针不正确?

#include<iostream>
using namespace std;


int main() {
    int arr1[] = { 1,3,4,6 };
    int arr2[] = { 2,3,4,5 };
    int n1 = 4;
    int n2 = 4;
    int arr3[10];
    int* endptr = &arr1[0];
    int* endptr2 = &arr2[0];
    int* endptr3 = arr3;
    int k = 0;

   
    while (endptr < &arr1[n1-1] &&endptr2  < &arr2[n2-1]) {
        if (endptr[0] < endptr2[0]) {
            endptr3[k++] = endptr[0];
            endptr++;
        }
            
        else {
            endptr3[k++] = endptr2[0];
            endptr2++;
        }
    }
    while (endptr < &arr1[n1 - 1]) {
        endptr3[k++] = endptr[0];
        endptr++;
    }

    while (endptr2 < &arr2[n2 - 1]) {
        endptr3[k++] = endptr[0];
        endptr2++;
    }
    cout << arr3[5];
}

我得到了前 6 个元素的结果,然后得到了垃圾值。

您使用指针的方式会对您的思维过程产生负面影响。

让我们将其抽象为 function 以帮助使其更清洁:

void merge(
  int * first1, int * last1,  // elements of array1
  int * first2, int * last2,  // elements of array2
  int * dest )                // where to put sorted data

这是 C++ 算法使用的“迭代器”习语。 first指向第一个元素。 last指向最后一个元素的后一位。 (并且我们假设dest指向足够的空间来包含结果。)所以:

int array1[] = { 1,3,4,6 };
int array2[] = { 2,3,4,5,7 };
int array3[9];  // enough room for array1+array2

merge( 
  array1, array1+4,  // first array has 4 elements
  array2, array2+5,  // second array has 5 elements
  array3 );          // destination array has 4+5=9 elements

C++ 实际上给了我们几个函数来获取第一个和最后一个指向你所拥有的任何底层序列容器的指针:

merge(
  std::begin(array1), std::end(array1),
  std::begin(array2), std::end(array2),
  std::begin(array3) );

现在我们可以重新考虑我们的合并算法。

void merge(...)
{
  // while both array1 and array2 have elements:
  while ((first1 != last1) and (first2 != last2))
  {
    if (*first2 < *first1)
      *dest++ = *first2++;
    else
      *dest++ = *first1++;
  }

  // if array1 has any leftover elements:
  while (first1 != last1)
    *dest++ = *first1++;

  // if array2 has any leftover elements:
  while (first2 != last2)
    *dest++ = *first2++;
}

特别注意:

  • 通过直接比较第firstlast指针,我们可以很容易地检查一个数组是否有元素。 first == last时,没有元素,因为last是源数组末尾之后的一个。
  • 比较很简单。 我们可以将其写成if (first2[0] < first1[0])但这不如仅使用*运算符那么惯用。
  • 复制一个值就像在赋值的两边取消引用和递增一样简单。
  • 合并的三个循环都处理一个简单的“还有元素吗?” 查看。

另请注意我们如何将测试条件保持为严格小于比较。 这对泛型编程有影响(例如,以非递增顺序合并排序),但我今天将保留它......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM