C++快速排序,有 2 个要求
C++ quicksort with 2 requirements
我的目标是根据两个标准对单词列表进行排序:
- 主要标准是增加字长,
- 次要标准是字母顺序
例如:
{red,a,three,b,four,aeoli}
应排序为:
{a,b,red,four,aeoli,three}.
我有两个单独的快速排序:一个是关于长度的,另一个是按字母顺序的。
我只是好奇如何将这两者合并? 我遇到的主要问题是我不知道如何在考虑长度并浏览整个列表的同时按字母顺序排序。
任何建议都值得赞赏,以下代码是我的主要代码和快速排序功能:
Vector<String> words;
String word;
ifstream inFile;
inFile.open("practice.txt");
while(!inFile.eof()){
getLine(inFile,word);
words.push_back(word);
}
inFile.close();
String pivot = "qog";
if(words[2] < pivot)
cout << "Bigger" << endl;
words.quicksort(2,words.length()-2);
words.quicksort2(2,words.length()-2);
长度的快速排序
template <typename T>
void Vector<T>::quicksort(int left, int right)
{
int i = left;
int j = right;
String pivot = data[(left+right)/2];
if(i <= j)
{
while(data[i].getLength() < pivot.getLength())
i++;
while(pivot.getLength() < data[j].getLength())
j--;
}
if(i <= j)
{
String temp = data[i];
data[i] = data[j];
data[j] = temp;
i++;
j--;
}
if(left < j)
quicksort(left,j);
if(i < right)
quicksort(i,right);
}
和字母的那个
template <typename T>
void Vector<T>::quicksort2(int left, int right)
{
int i = left;
int j = right;
String pivot = data[(left+right)/2];
if(i <= j)
{
while(data[i] < pivot)
i++;
while(pivot < data[j])
j--;
}
if(i <= j)
{
String temp = data[i];
data[i] = data[j];
data[j] = temp;
i++;
j--;
}
if(left < j)
quicksort2(left,j);
if(i < right)
quicksort2(i,right);
}
注意:这是用我自己的自定义 Vector 和 String 类完成的,两个版本都能完美运行,所以我的主要问题是排序本身的逻辑——如何让它们一起运行。
此外,我只能使用iostream,fstream和cstring,以及我自己实现的任何其他内容。
提前谢谢。
只需使用std
从合理的实现向后工作,重新实现(削减)您使用的东西的版本。
sort(vec.begin(), vec.end(), [](auto & lhs, auto & rhs){ return tie(lhs.size(), lhs) < tie(rhs.size(), rhs); });
然后我们需要实现tuple
、sort
和tie
struct tuple
{
const int & first;
const String & second;
};
bool operator<(const tuple & lhs, const tuple & rhs)
{
if (lhs.first < rhs.first) return true;
if (rhs.first < lhs.first) return false;
return lhs.second < rhs.second;
}
tuple tie(const int & first, const String & second)
{
return { first, second };
}
然后,我们可以调整您的Vector::quicksort
实施
template <typename Iter, typename Comp>
void quicksort(Iter left, Iter right, Comp comp)
{
auto distance = (right - left) / 2
Iter l = left;
Iter pivot = left + distance;
Iter r = right;
if(l <= r)
{
for(;comp(*l, *pivot); ++l);
for(;comp(*pivot, *r); --j);
}
if(i <= j)
{
String temp = *i;
*i = *j;
*j = temp;
++i;
--j;
}
if(left < j)
quicksort(left, j, comp);
if(i < right)
quicksort(i, right, comp);
}
或者我们可以改为查看此问答,并实现partition
、find_if_not
等
template<class FwdIt, class Compare = std::less<>> void quick_sort(FwdIt first, FwdIt last, Compare cmp = Compare{}) { auto const N = distance(first, last); if (N <= 1) return; auto const pivot = *next(first, N / 2); auto const middle1 = partition(first, last, [=](auto const& elem){ return cmp(elem, pivot); }); auto const middle2 = partition(middle1, last, [=](auto const& elem){ return !cmp(pivot, elem); }); quick_sort(first, middle1, cmp); // assert(std::is_sorted(first, middle1, cmp)); quick_sort(middle2, last, cmp); // assert(std::is_sorted(middle2, last, cmp)); } template<class ForwardIt, class UnaryPredicate> ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPredicate p) { first = find_if_not(first, last, p); if (first == last) return first; for (ForwardIt i = next(first); i != last; ++i) { if (p(*i)) { iter_swap(i, first); ++first; } } return first; } template<class InputIt, class UnaryPredicate> constexpr InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q) { for (; first != last; ++first) { if (!q(*first)) { return first; } } return last; } template<class InputIt> void iter_swap(InputIt a, InputIt b) { using value_type = typename InputIt::value_type; value_type temp = static_cast<value_type&&>(*a); // aka std::move *a = static_cast<value_type&&>(*b); *b = static_cast<value_type&&>(temp); } template<class T> void iter_swap<T*>(T * a, T * b) { T temp = static_cast<T&&>(*a); // aka std::move *a = static_cast<T&&>(*b); *b = static_cast<T&&>(temp); } template<class InputIt> InputIt next(InputIt it, int distance) { return it + distance; }
我想最终,你会希望它按单词的最小值排序。 短单词的"价值"比长单词少,因为字母的重量小于单词,我会按每个单词的总ASCII值对其进行排序。 在这种情况下,您不需要使用 2 个排序和合并,计算每个对象的 ascii 值并按它排序。
如果必须将两种算法链接在一起,对于学校作业或其他什么,则需要实现稳定分区(或使用 std::stable_partition)。
编辑 - 阅读您的"注释"后,我应该提到安抚老师的另一种方法是实现第三个版本的快速排序,该版本在谓词中使用这两个条件。请参阅下面的shorter_less
。更好的是,将谓词作为函数指针传递到单个统一的快速排序中,就像 std::sort 和 std::stable_sort 那样。 即...
这是一次性完成所有操作的C++方法...
#include <string>
#include <algorithm>
#include <vector>
using std::string;
static bool shorter_less( const string& L, const string &R) {
if (L.length() == R.length()) return L<R;
else return L.length() < R.length();
}
int main() {
using str_vec = std::vector<string>;
str_vec vec{ "xxzy" , "Alphonse", "Betty", "pea", "nuts", "z" };
std::sort(vec.begin(), vec.end(), shorter_less);
}
- 如何修复我的快速排序实现?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在 MIPS 中快速排序
- 不正确的比较和交换计数器输出用于快速排序功能
- 使用 std::vector C++快速排序,EXC_BAD_ACCESS代码 2
- 使用快速排序对 C++ 中的可视化工具错误进行排序
- 快速排序 - 三个中位数枢轴选择 - 某些元素顺序不正确
- 并行快速排序分区中的隔离错误
- 实现 3 路分区以实现快速排序
- 为什么这个快速排序实现给出了一个奇怪的输出
- 我的快速排序在对预排序的项目进行排序时失败,如何改进?
- 快速排序不适用于大型数组
- 快速排序;分段错误,但找不到位置?
- 快速排序函数在快速排序算法中如何工作?
- 3路随机快速排序分区功能
- 在最坏的情况下试验快速排序.它运行良好,但在最坏的情况下发生未知错误.我想
- 当给出预先排序的输入时,为什么我的快速排序实现很慢
- 我想要一个改变数组快速排序的2个数字的函数
- C++一个具有 2 个参数(___ _____,整数长度)的函数中的快速排序
- 迭代快速排序方法的分区算法问题