我这样做是因为我学习编程的网站,我根本无法解决这个问题。
#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排序的答案。 任何人都可以帮助我吗?
答案 0 :(得分:5)
问题是std::sort
不稳定 - 这意味着当您按长度排序时,会按名称销毁排序。
easy 这样做的方法是扭转你的对。 std::pair
有一个operator <
,用于比较first
个值,如果它们相同,则会比较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{});
答案 1 :(得分:3)
您不需要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
答案 2 :(得分:0)
我建议pidgeonhole排序,然后是每种pidgenhole。
初始步骤仅为O(N + n),然后在O(p log p)中对每个pidgeonhole进行排序,因为每个p&lt; = 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;
}
}