逐字排序字符串

时间:2014-11-29 00:18:48

标签: c++ string

我最近在字符串上遇到了一个问题,突然间我想到了这个问题,我怎么能按照ascii值的递增顺序排列字符串的单词。

例如,有一个字符串:

ab nn ac mm

所以输出应为:

ab ac mm nn

实际上我想根据一个单词的每个字母的ascii值的总和来安排它们。

,如上例所示

ab has a sum of (97+98)=195
ac has a sum of (97+99)=196

依旧......

我想知道有没有高效方法,或者 STL 中有任何可以使用的功能吗?

使问题更加清晰如果字符串是 -

,这是第二个例子
acd abz

然后输出 -     acd abz 因为“acd”的每个字母的ascii的总和小于“abz”的字母的总和

acd sums to (97+99+100)=296
abz sums to (97+98+122)=317

4 个答案:

答案 0 :(得分:2)

对于自定义比较,此代码应该使用自定义比较函数对象(仿函数),即在这种情况下实现bool operator(x,y)以在std::sort中使用的对象:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

struct str_comp
{
    bool operator()(const std::string &lhs, const std::string &rhs) const
    {
        return std::accumulate(std::begin(lhs), std::end(lhs), 0) < 
               std::accumulate(std::begin(rhs), std::end(rhs), 0);
    }
};

int main()
{
    std::string input_str {"acd abz aaayyyyy zzzaaaaa"};
    std::stringstream ss {input_str};
    std::vector<std::string> v_str { std::istream_iterator<std::string>{ss}, {} };
    std::sort(std::begin(v_str), std::end(v_str), str_comp());
    for (const auto& elem : v_str)
        std::cout << elem << std::endl;
}

或者,像一个像老板一样的lambda函数:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    std::string input_str {"acd abz aaayyyyy zzzaaaaa"};
    std::stringstream ss {input_str};
    std::vector<std::string> v_str { std::istream_iterator<std::string>{ss}, {} };
    std::sort(std::begin(v_str), std::end(v_str), 
        [](const std::string& lhs, const std::string& rhs)
        {
            return std::accumulate(std::begin(lhs), std::end(lhs), 0) < 
               std::accumulate(std::begin(rhs), std::end(rhs), 0);
        }
    ); // end std::sort
    for (const auto& elem : v_str)
        std::cout << elem << std::endl;
}

答案 1 :(得分:0)

您可以在矢量中拆分字符串和push_back,并按以下方式对矢量进行排序:

#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>

using namespace std;

 int main()
 {

  vector<string>v;
  std::string s="ab nn ac mm";
  istringstream t(s);

  string ss;

  while(t>>ss){

    v.push_back(ss);
   }

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

  for (auto i=v.begin(); i!=v.end(); ++i){
          cout<<*i<<endl;

      }   
  return 0;
}

答案 2 :(得分:0)

这段代码使用通用标准函数/算法,并且(在我看来)效率很高。 如你所见,分裂由字符串流完成。

#include <algorithm>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

int main()
{
    std::string input = "abz acd";
    std::vector<std::string> substrings{ std::istream_iterator<std::string>{ std::stringstream{ input } }, std::istream_iterator<std::string>{} };

    std::sort(std::begin(substrings), std::end(substrings),
        [](const std::string& a, const std::string& b) -> bool 
        { 
            auto calcAscii = [](const std::string& str) -> int 
            {   
                int ascii = 0;
                for (auto const& it : str)
                {
                    ascii += static_cast<int>(it);
                }

                return ascii;
            };

            return calcAscii(a) < calcAscii(b); 
        });

    std::string result;

    for (auto const& it : substrings)
    {
        result += it + " ";
    }

    std::cout << result;
}

答案 3 :(得分:0)

我假设你的字符串在单词和单词之间只有一个空格。另外我假设你的字符串是trimed,这意味着它在字符串的头部和尾部没有任何空格。让我展示代码。

std::string sort_by_word_code(const std::string &src)
{
    if (src.empty())
        return "";

    typedef std::string::const_iterator const_iterator;
    typedef std::tuple<const_iterator, const_iterator, int> WordTuple;
    std::vector<WordTuple> words;

    const_iterator i = src.begin(), j;
    int code;

    while (1)
    {
        code = 0;
        for (j = i; j != src.end() && *j != ' '; ++j)
        {
            code += *j;
        }

        words.push_back(WordTuple(i, j, code));

        if (j == src.end())
            break;

        i = j + 1;
    }

    std::sort(words.begin(), words.end(),
        [](const WordTuple &t1, const WordTuple &t2) { return std::get<2>(t1) < std::get<2>(t2); }
        );

    std::string result;
    result.reserve(src.size());

    for (auto it = words.begin(); ; )
    {
        result.insert(result.end(),
            std::get<0>(*it),
            std::get<1>(*it)
            );

        ++it;
        if (it == words.end())
            break;

        result.push_back(' ');
    }

    return result;
}

(live example)

这个想法很简单。创建一个向量,其中包含每个单词的ascii和begin / end之和,对其进行排序,并从中创建结果字符串。