【问题标题】:sorting alphanumeric string using vector使用向量对字母数字字符串进行排序
【发布时间】:2014-10-13 23:23:21
【问题描述】:

我有一个包含字母数字字符串的向量,我想根据数值对向量进行排序。

例如,如果我的向量包含这些值:

name0 name20 name15 name3 name10,我的排序向量应该是这样的:

name0 name3 name10 name15 namw20.

任何人都可以请帮助如何做到这一点..?这是我的完整代码:

#include<vector>

#include<string>
#include <cstdlib>

#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
        vector<string> temp;
        temp.push_back("name0");
        temp.push_back("name20");
        temp.push_back("name15");
        temp.push_back("name3");
        temp.push_back("name10");

        sort(temp.begin(), temp.end());


        for (vector<string>::size_type i = 0; i!= temp.size(); i++)
                cout << temp[i] << endl;


return 0;
}

【问题讨论】:

  • 您需要根据字符串和数字将字符串拆分为标记,然后一次进行一个标记的字典比较。

标签: c++ vector


【解决方案1】:

假设 C++11,您可以使用 lambda 和 std::stoi 将字符串的有效部分转换为数字。

sort(temp.begin(), temp.end(), [] (const std::string& a, const std::string& b) { 
    std::string cmp_a { a.begin() + 4, a.end() };
    std::string cmp_b { b.begin() + 4, b.end() };
    return std::stoi(cmp_a) < std::stoi(cmp_b);
});

当然,std::stoi 会在转换失败时抛出,因此请确保您传递给它的字符串仅包含数字。


在C++03中,可以使用Boost.Lexical_Cast:

int convert(const std::string& s, std::size_t pos)
{
    return boost::lexical_cast<int>(s.data() + pos, 
        std::distance(s.begin() + pos, s.end()));
}

bool predicate(const std::string& a, const std::string& b)
{
    return convert(a, 4) < convert(b, 4);
}

如评论中所述,4 是第一个数字出现的硬编码位置。如果不同,可以使用find_first_of

const std::string numbers = "0123456789";

bool predicate(const std::string& a, const std::string& b)
{
    std::size_t a_start = a.find_first_of(numbers);
    std::size_t b_start = b.find_first_of(numbers);
    return convert(a, a_start) < convert(b, b_start);
}

Charles Salvia 已经写了一个更好的答案(不依赖于 Boost 或 C++11)。如另一条评论所述,他链接到实现natural sorting order 的页面。

【讨论】:

  • 感谢 remyabel。你能描述一下你为什么在这里使用 + 4:std::string cmp_a { a.begin() + 4, a.end() };
  • @user3527124 “名称”中有 4 个字符。如果这可能会有所不同,您将需要搜索第一个数字字符。
  • 我想我回答了我自己的问题..?这是因为 name0、name20 等吗? a.begin + 4 将指向字符串“name”之后的第一个数值。正确..?
猜你喜欢
  • 1970-01-01
  • 2013-06-05
  • 2021-09-19
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 2021-02-21
相关资源
最近更新 更多