C++ 是否有一种方法可以使用排序将向量与字符串序列进行比较?
我有一个向量,包含几个基于用户输入的单词。它们都使用名为container的变量存储在向量中。我需要将字符串中的单词排列成非常规的QWERTY顺序,或者换句话说,我需要根据字符串对它们进行排序 字符串序列=qwertyuiopasdfghjklzxcvnm; 因此,示例运行将如下所示 输入一个单词:apple 输入一个单词:pear 输入一个单词:peach 按QWERTY顺序排序的单词: 梨 桃 苹果 我目前只能存储这些字符串,因为它们不是字母顺序,所以我不能在if语句中使用字符值C++ 是否有一种方法可以使用排序将向量与字符串序列进行比较?,c++,string,sorting,vector,C++,String,Sorting,Vector,我有一个向量,包含几个基于用户输入的单词。它们都使用名为container的变量存储在向量中。我需要将字符串中的单词排列成非常规的QWERTY顺序,或者换句话说,我需要根据字符串对它们进行排序 字符串序列=qwertyuiopasdfghjklzxcvnm; 因此,示例运行将如下所示 输入一个单词:apple 输入一个单词:pear 输入一个单词:peach 按QWERTY顺序排序的单词: 梨 桃 苹果 我目前只能存储这些字符串,因为它们不是字母顺序,所以我不能在if语句中使用字符值 有人提示
有人提示我使用排序选择或插入将向量字符串与QWERTY序列进行比较,但我在教科书或在线上找不到如何将其应用于代码的示例。如果您有任何帮助,我们将不胜感激,谢谢您的时间。一个选择是用您的特殊字母表中相应的字符替换每个字符。然后做一个排序,然后换回来 例如:
we -> bc, er -> cd
只需使用std::string::find查找符号的索引并进行比较:
bool sequenceLess( const std::string &s1, const std::string &s2 )
{
static const std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
for( size_t i = 0; i < s1.length(); ++i ) {
if( i >= s2.length() ) return false;
auto idx1 = sequence.find( ::toupper( s1[i] ) );
auto idx2 = sequence.find( ::toupper( s2[i] ) );
if( idx1 == idx2 ) continue;
return idx1 < idx2;
}
return true;
}
std::vector<size_t> convert( const std::string &s )
{
static const std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
std::vector<size_t> r( s.size() );
std::transform( s.begin(), s.end(), r.begin(), [sequence]( char c ) {
return sequence.find( ::toupper( c ) );
} );
return r;
}
// now comparison is obvious
bool sequenceLess( const std::string &s1, const std::string &s2 )
{
return convert( s1 ) < convert( s2 );
}
另一个版本是将字符串转换为索引向量并进行比较:
bool sequenceLess( const std::string &s1, const std::string &s2 )
{
static const std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
for( size_t i = 0; i < s1.length(); ++i ) {
if( i >= s2.length() ) return false;
auto idx1 = sequence.find( ::toupper( s1[i] ) );
auto idx2 = sequence.find( ::toupper( s2[i] ) );
if( idx1 == idx2 ) continue;
return idx1 < idx2;
}
return true;
}
std::vector<size_t> convert( const std::string &s )
{
static const std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
std::vector<size_t> r( s.size() );
std::transform( s.begin(), s.end(), r.begin(), [sequence]( char c ) {
return sequence.find( ::toupper( c ) );
} );
return r;
}
// now comparison is obvious
bool sequenceLess( const std::string &s1, const std::string &s2 )
{
return convert( s1 ) < convert( s2 );
}
此解决方案效率不高,但出于学习目的应该可以。您可以尝试自定义排序。 请参考此链接 下面是我的代码样本为您的情况下,但我力处理小写字母
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct mySort{
inline bool operator() (const string& s1, const string& s2)
{
bool isSort = false;
if(s1.length() < s2.length()){
return true;
}else if(s1.length() > s2.length()){
return false;
}
//s1.length() == s1.length()
string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
int index1 = 0 , index2 = 0;
for(int i = 0 ; i < s1.length() ; i++){
for(int j = 0 ; j < sequence.length() ; j++){
if(s1[i] == sequence[j]){
index1 = j;
}
if(s2[i] == sequence[j]){
index2 = j;
}
}
if(index1 < index2){return true;}
}
return false;
}
};
int main(){
vector<string> myVector;
myVector.push_back("APPLE");
myVector.push_back("PEAR");
myVector.push_back("PEACH");
sort(myVector.begin(), myVector.end(), mySort());
for(int i = 0 ; i < myVector.size() ; i++){
cout<<myVector[i]<<endl;
}
return 1;
}
这是结果
PS:可能我错过了一些条件,但请与您分享如何应用自定义排序。您可以重载编辑:添加查找表并在getless中更正测试 下面是另一个使用std::sort和一个函数的解决方案,该函数测试每个字符串,如果一个字符串小于QWERTY顺序中的另一个字符串,则返回true:
#include <algorithm>
#include <string>
#include <vector>
#include <cctype>
#include <iostream>
typedef std::vector<std::string> StringVect;
std::string sequence = "QWERTYUIOPASDFGHJKLZXCVBNM";
std::vector<int> lookup(26);
bool getless(const std::string& s1, const std::string& s2)
{
for (size_t i = 0; i < std::min(s1.size(), s2.size()); ++i)
if (s1[i] != s2[i])
return (lookup[toupper(s1[i])-'A'] < lookup[toupper(s2[i])-'A']);
return s1.size() < s2.size();
};
int main()
{
StringVect sv = {{ "apple" },{ "pear" },{ "peach" }};
// build the lookup table
int i = 0;
std::for_each(sequence.begin(), sequence.end(), [&](char ch) {lookup[ch-'A'] = i; ++i; });
// sort the data
std::sort(sv.begin(), sv.end(), getless);
// output results
for (auto& s : sv)
std::cout << s << "\n";
}
建立一个查找表,将字符的相对ASCII位置映射到序列字符串中字符所在的位置。例如,查找[0]是A的位置,是10,查找[1]是B的位置,是23,等等
getless函数扫描字符串,并使用相应的查找位置测试与每个字符串的第i个字符关联的字符
for循环基本上等待比较的两个字符串中的字符差异。如果s1字符串中的字符的查找值小于s2中字符的查找值,则我们立即返回true,即s1如果字符相等,我们将继续循环,直到没有字符可供比较。如果两个字符串在我们退出for循环时相等,则返回true或false,具体取决于字符串的长度,较短的字符串表示s1