我最近在字符串上遇到了一个问题,突然间我想到了这个问题,我怎么能按照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
答案 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;
}
这个想法很简单。创建一个向量,其中包含每个单词的ascii和begin / end之和,对其进行排序,并从中创建结果字符串。