I was trying out something simple like this:
我尝试了一些简单的方法:
template<class T>
array insertionSort(array<T> arr) {
for (int index = 1; index < arr.size(); index++) {
for (int insertion = index; insertion > 0 && array[insertion - 1] > array[insertion]; insertion--) {
std::swap(array[insertion - 1], array[insertion]);
}
}
return arr;
}
void main() {
array<int, 10> mine = { 1, 0, 2, 9, 3, 8, 4, 7, 5, 6 };
array result = insertionSort<int>(mine);
cin.get();
}
It seems as though array requires two type parameters (the type
as well as the size
), so how do I pass it to and from a function without knowing the size up front?
看起来似乎数组需要两个类型参数(类型和大小),那么如何在不事先知道大小的情况下将它传递给函数或从函数传递给函数?
3 个解决方案
#1
20
In general, you don't really want to pass containers around! The same algorithm which works for std::array<T, N>
also works for other data structures, e.g., std::vector<T>
or std::deque<T>
. The C++ approach in that case is to pass iterator and to [slightly] adjust the algorithm:
一般来说,你并不是真的想把容器传过来!同样适用于std::array
template<typename BidrectionalIterator>
void insertionSort(BidirectionalIterator begin, BidirectionalIterator end) {
for (BidirectionalIterator it(begin); it != end; ++it) {
for (BidirectionalIterator insertion(it), tmp(insertion);
begin != insertion && *--tmp > *insertion; --insertion) {
std::swap(*tmp, *insertion);
}
}
}
(I didn't verify that the algorithm actually works but you get the idea).
(我没有验证这个算法是否有效,但你懂的)。
Note that the algorithm deliberately sorts the sequence in-place! If you want to create a sorted copy, create the copy and sort that: this way you have the choice to do it in-place or not rather than being forced to use an approach which may require excessive memory (OK, when the sequence is large you surely don't want to use this algorithm but that's a separate question).
注意,算法故意对序列进行就地排序!如果你想创建一个排序复制、创建复制和那种:这种方式你可以选择就地与否,而不是*使用一个方法可能需要过度的内存(当序列是大你肯定不想使用这个算法,但这是一个单独的问题)。
#2
10
It works the same way as passing the object without knowing the type up front. You use a template parameter:
它的工作方式与在不事先知道类型的情况下传递对象相同。使用模板参数:
template<class T, size_t arrSize>
std::array<T, arrSize> insertionSort(std::array<T, arrSize> arr) {
for (int index = 1; index < arrSize; index++) {
for (int insertion = index; insertion > 0 && array[insertion - 1] > array[insertion]; insertion--) {
std::swap(array[insertion - 1], array[insertion]);
}
}
return arr;
}
#3
3
IMO, you should just pass the size as a template parameter and use it in the loop instead of arr.size():
在我看来,您应该将size作为模板参数传递给循环,而不是arr.size():
template<class T, size_t size>
array<T, size> insertionSort(array<T> arr) {
for (int index = 1; index < size; index++) {
for (int insertion = index; insertion > 0 && array[insertion - 1] > array[insertion]; insertion--) {
std::swap(array[insertion - 1], array[insertion]);
}
}
return arr;
}
void main() {
array<int, 10> mine; mine.fill(0);
array<int, mine.size()> result = insertionSort<int, mine.size()>(mine);
cin.get();
}
#1
20
In general, you don't really want to pass containers around! The same algorithm which works for std::array<T, N>
also works for other data structures, e.g., std::vector<T>
or std::deque<T>
. The C++ approach in that case is to pass iterator and to [slightly] adjust the algorithm:
一般来说,你并不是真的想把容器传过来!同样适用于std::array
template<typename BidrectionalIterator>
void insertionSort(BidirectionalIterator begin, BidirectionalIterator end) {
for (BidirectionalIterator it(begin); it != end; ++it) {
for (BidirectionalIterator insertion(it), tmp(insertion);
begin != insertion && *--tmp > *insertion; --insertion) {
std::swap(*tmp, *insertion);
}
}
}
(I didn't verify that the algorithm actually works but you get the idea).
(我没有验证这个算法是否有效,但你懂的)。
Note that the algorithm deliberately sorts the sequence in-place! If you want to create a sorted copy, create the copy and sort that: this way you have the choice to do it in-place or not rather than being forced to use an approach which may require excessive memory (OK, when the sequence is large you surely don't want to use this algorithm but that's a separate question).
注意,算法故意对序列进行就地排序!如果你想创建一个排序复制、创建复制和那种:这种方式你可以选择就地与否,而不是*使用一个方法可能需要过度的内存(当序列是大你肯定不想使用这个算法,但这是一个单独的问题)。
#2
10
It works the same way as passing the object without knowing the type up front. You use a template parameter:
它的工作方式与在不事先知道类型的情况下传递对象相同。使用模板参数:
template<class T, size_t arrSize>
std::array<T, arrSize> insertionSort(std::array<T, arrSize> arr) {
for (int index = 1; index < arrSize; index++) {
for (int insertion = index; insertion > 0 && array[insertion - 1] > array[insertion]; insertion--) {
std::swap(array[insertion - 1], array[insertion]);
}
}
return arr;
}
#3
3
IMO, you should just pass the size as a template parameter and use it in the loop instead of arr.size():
在我看来,您应该将size作为模板参数传递给循环,而不是arr.size():
template<class T, size_t size>
array<T, size> insertionSort(array<T> arr) {
for (int index = 1; index < size; index++) {
for (int insertion = index; insertion > 0 && array[insertion - 1] > array[insertion]; insertion--) {
std::swap(array[insertion - 1], array[insertion]);
}
}
return arr;
}
void main() {
array<int, 10> mine; mine.fill(0);
array<int, mine.size()> result = insertionSort<int, mine.size()>(mine);
cin.get();
}