如何根据长度然后字母顺序对数组字符串进行排序?
How do I sort string of arrays based on length THEN Alphabetic order?
我这样做是因为一个我学习编程的网站,我根本无法解决这个问题。
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main ()
{
int n;
string thename;
vector <pair<string,int>> name;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> thename;
name.push_back(make_pair(thename, thename.length()));
}
sort(name.begin(), name.end());
sort(name.begin(), name.end(),
[](const pair<string, int>& lhs, const pair<string, int>& rhs) {
return lhs.second < rhs.second; } );
for (int i = 0; i < n; i++)
{
cout << name[i].first<< endl;
}
}
我的前辈建议我不要使用 lambda 排序,因为我自己仍然不太了解它。但我仍然会接受任何 lambda 排序答案。 谁能帮我?
问题是std::sort
不稳定 - 这意味着当您按长度排序时,您会破坏按名称排序。
要做到这一点,最简单的方法是反转你的配对。std::pair
有一个比较first
值的operator <
,如果它们相同,则比较second
值。 所以你需要的是:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main ()
{
int n;
vector <pair<int,string>> name;
cin >> n;
for (int i = 0; i < n; i++)
{
string thename;
cin >> thename;
name.push_back(make_pair(thename.length(),thename));
}
sort(name.begin(), name.end());
for (const auto& n: name)
{
cout << n.second << endl;
}
}
请注意,我已经将thename
移动到循环内部(它从未在外部使用(,并将最终的 for 循环设置为foreach 循环(在可能的情况下应该是您喜欢的循环形式(。
但是,您不需要将长度存储在向量中。 您可以只存储名称,然后使用自定义比较器进行比较。
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main ()
{
int n;
vector<string> name;
cin >> n;
for (int i = 0; i < n; i++)
{
string thename;
cin >> thename;
name.push_back(thename);
}
sort(name.begin(), name.end(),
[](const string& lhs, const string& rhs)
{
return std::tie(lhs.length(),lhs) < std::tie(rhs.length(), rhs);
} );
for (const auto& n : name)
{
cout << n << endl;
}
}
请注意,我使用std::tie
来比较长度和字符串。 与std::make_pair
相比,它的优点是它将默认使用引用,因此不会复制字符串。 与自己动手相比,它的优势在于它更容易正确(也更容易阅读(。
请注意,您可以替换 lambda
[](const string& lhs, const string& rhs)
{
return std::tie(lhs.length(),lhs) < std::tie(rhs.length(), rhs);
}
通过手动编写的函子:
struct MyLessString
{
bool operator () (const string& lhs, const string& rhs) const
{
return std::tie(lhs.length(),lhs) < std::tie(rhs.length(), rhs);
}
};
并使用它:
sort(name.begin(), name.end(), MyLessString{});
你不需要vector<pair<int,string>
来存储你的字符串数组,你可以vector<string>
并编写一个适当的排序函数 这里举个例子:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
int main ()
{
int n;
std::string thename;
std::vector <std::string> name;
std::cin >> n;
for (int i = 0; i < n; i++)
{
std::cin >> thename;
name.push_back(thename);
}
sort(name.begin(), name.end(),
[](const std::string& lhs, const std::string& rhs) {
return lhs.size() == rhs.size() ?
lhs < rhs : lhs.size() < rhs.size(); } );
for (int i = 0; i < n; i++)
{
std::cout << name[i]<< std::endl;
}
}
输入:
4
Joe
Ann
Ralph
Andrew
输出:
Ann
Joe
Ralph
Andrew
我建议pidgeonhole排序,然后是每个pidgenhole的排序。
第一步只有 O(N+n(,然后对 O( p log p 中的每个鸽子洞进行排序,因为每个 p <= n,总排序时间应小于或等于 O(n log n(
警告未经测试的代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
constexpr const int MaxNameLength = 32; // arbitrary chosen length
int main () {
int n;
string thename;
vector <vector<string>> name;
int maxLen = MaxNameLength;
name.resize(MaxNameLength);
cin >> n;
for (int i = 0; i < n; i++) {
cin >> thename;
if (name.length() > maxLen) {
name.resize(thename.length());
maxLen = thename.length();
}
name[thename.length()].emplace_back(thename);
}
for (auto& len: name) {
sort(len.begin(), len.end());
}
for (int i = 0; i < n; i++) {
cout << name[i].first<< endl;
}
}
相关文章:
- 将C#字符串数组传递给C++
- 如何为 C 型字符串数组编写 getter 和 setter?
- 有没有办法使用 strcpy 将字符串数组复制到另一个字符串或其他数组中?
- 尝试将 c 字符串数组与分隔符连接起来
- 将字符串数组传递给接受常量字符**的函数
- 返回 C++ 中的字符串数组
- 如何从COM模块中的函数返回字符串数组?
- 无法将字符串数组声明为类成员而不是字符 (C++)
- 删除字符串数组
- 如何将字符串数组返回到 java JNI
- 将字符串数组作为函数参数传递
- C++将字符串数组的元素存储到变量中
- 循环访问还包含未使用元素的字符串数组
- 字符串数组上的 sizeof 运算符以 C++ 为单位给出不同的输出
- 乘以字符串/数组和全局数组
- 递归二进制搜索与字符串数组
- 如何初始化一个标准::字符串数组?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++字符串数组的动态向量
- 给定一个等长字符串数组