问题是std::sort
不稳定 - 这意味着当您按长度排序时,按名称排序排序。
该容易方式做到这一点,是扭转你的一对。 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
环内(这是从来没有使用外),并取得了最后的循环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
相比,它的优点是它将默认使用引用,因此不会复制字符串。比自己做这件事的好处是,它是巨大更容易得到正确(并且它也更容易阅读)。
请注意,您可以通过手工编写一个仿函数替换拉姆达
[](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{});
'的std :: tie'或'的std :: make_pair(lhs.length()的std :: CREF(左))'可以避免复制'STD: :string' – Jarod42
@ Jarod42:哦!我不知道std:tie做到了。 Editted。谢谢。 (它现在消除了对这种情况进行手写比较的唯一可能的原因)。 –
@ Jarod42:哦!感谢那。 –