将 2 个排序数组合并到向量 c++ 中

Merge 2 sorted arrays into vector c++

本文关键字:向量 c++ 合并 数组 排序      更新时间:2024-05-09

嗨,我正在尝试将 2 个排序数组合并到一个向量中。

以下是我的代码。我相信我使用的是正确的算法,但是,当我打印出矢量时,它只打印 1,2。

有人可以看看我的代码吗?

#include <iostream>
#include <vector>
using namespace std;
vector<int> merge(int arr1[],int arr2[])
{
int arr1size = sizeof(arr1) / sizeof(arr1[0]);
int arr2size = sizeof(arr2) / sizeof(arr2[0]);
vector<int> arr3;
int i = 0, j = 0;
while(i<arr1size && j<arr2size)
{
if(arr1[i] <= arr2[j])
{
arr3.push_back(arr1[i]);
i++;
}
else
{
arr3.push_back(arr2[j]);
j++;
}
}
while(i<arr1size)
{
arr3.push_back(arr1[i]);
i++;
}
while(j<arr2size)
{
arr3.push_back(arr2[j]);
j++;
}
return arr3;
}
int main()
{
int arr1[] = {1, 3, 5, 7};
int arr2[] = {2, 4, 6, 8};
vector<int> arr3;
arr3 = merge(arr1,arr2);
for(int i=0;i<arr3.size();i++)
{
cout << arr3[i] << endl;
}
return 0;
}
int arr1size = sizeof(arr1) / sizeof(arr1[0]);

你忘记了一个极其重要的事实。也就是说,作为函数参数的数组只是一个指针(与其他上下文不同)。以下声明是相同的(它们重新声明相同的函数)。

void f(int a[]);
void f(int a[10]);
void f(int* a);

恐怕,如果你坚持使用普通数组,你将不得不传递它们的大小。

void f(int a[], int n);

请注意,如果通过引用传递数组,则不会丢失大小信息,但会将自己限制为数组类型的l值(即,不能传递动态分配的数组或常规数组的切片)

template <int N>
void f(int (&a)[N]);

或者,您可以使用std::array<T, N>std::vector<T>,具体取决于要求。

具有数组类型的函数参数由编译器调整为指向数组元素类型的指针。那就是这个函数声明

vector<int> merge(int arr1[],int arr2[]);

由编译器调整为声明

vector<int> merge(int *arr1, int *arr2);

另一方面,用作函数参数的数组被隐式转换为指向其第一个元素的指针。那就是这个函数调用

merge(arr1,arr2)

等效于以下函数调用

merge( &arr1[0], &arr2[0] )

因此在函数中这些声明

int arr1size = sizeof(arr1) / sizeof(arr1[0]);
int arr2size = sizeof(arr2) / sizeof(arr2[0]);

反过来相当于

int arr1size = sizeof( int * ) / sizeof( int );
int arr2size = sizeof( int * ) / sizeof( int );

并根据类型int *int对象的大小,初始化表达式被计算为21。也就是说,它们不会产生用作函数参数的数组中的元素数量。

此外,您应该使用类型size_t而不是类型int,因为运算符 sizeof 返回类型为size_t的值。

此外,函数参数应具有限定符const因为数组在函数内不会更改。

您需要显式传递每个数组中的元素数。

所以函数声明将看起来像

std::vector<int> merge( const int arr1[], size_t n1, const int arr2[], size_t n2 );

请注意,在没有最初为添加元素保留足够空间的情况下使用向量是低效的。

通常,应使用函数merge的限定名称。

该函数可以如下所示,如下面的演示程序所示

#include <iostream>
#include <vector>
#include <algorithm>
std::vector<int> merge( const int arr1[], size_t n1, const int arr2[], size_t n2 )
{
std::vector<int> arr3;
arr3.reserve( n1 + n2 );

size_t i = 0, j = 0;

while ( i < n1 && j < n2 )
{
if( arr2[j] < arr1[i] )
{
arr3.push_back( arr2[j] );
j++;
}
else
{
arr3.push_back( arr1[i] );
i++;
}
}

while ( i < n1 )
{
arr3.push_back( arr1[i] );
i++;
}

while ( j < n2 )
{
arr3.push_back( arr2[j] );
j++;
}

return arr3;
}
int main()
{
int arr1[] = {1, 3, 5, 7};
int arr2[] = {2, 4, 6, 8};
const size_t N1 = sizeof( arr1 ) / sizeof( *arr1 );
const size_t N2 = sizeof( arr2 ) / sizeof( *arr2 );

std::vector<int> arr3 = ::merge( arr1, N1, arr2, N2 );

for ( const auto &item : arr3 )
{
std::cout << item << std::endl;
}

return 0;
}

程序输出为

1
2
3
4
5
6
7
8

已经有标准算法std::merge您可以使用它来代替用户定义的函数。

这是一个演示程序。

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
int arr1[] = {1, 3, 5, 7};
int arr2[] = {2, 4, 6, 8};
const size_t N1 = sizeof( arr1 ) / sizeof( *arr1 );
const size_t N2 = sizeof( arr2 ) / sizeof( *arr2 );

std::vector<int> arr3;
arr3.reserve( N1 + N2 );

std::merge( arr1, arr1 + N1, arr2, arr2 + N2, std::back_inserter( arr3 ) );

for ( const auto &item : arr3 )
{
std::cout << item << std::endl;
}

return 0;
}

程序输出与上图相同。

1
2
3
4
5
6
7
8

标准算法也可以按以下方式调用

std::merge( std::begin( arr1 ), std::end( arr1 ), 
std::begin( arr2 ), std::end( arr2 ), 
std::back_inserter( arr3 ) );