C++ 是否有一种方法可以使用排序将向量与字符串序列进行比较?

C++ 是否有一种方法可以使用排序将向量与字符串序列进行比较?,c++,string,sorting,vector,C++,String,Sorting,Vector,我有一个向量,包含几个基于用户输入的单词。它们都使用名为container的变量存储在向量中。我需要将字符串中的单词排列成非常规的QWERTY顺序,或者换句话说,我需要根据字符串对它们进行排序 字符串序列=qwertyuiopasdfghjklzxcvnm; 因此,示例运行将如下所示 输入一个单词:apple 输入一个单词:pear 输入一个单词:peach 按QWERTY顺序排序的单词: 梨 桃 苹果 我目前只能存储这些字符串,因为它们不是字母顺序,所以我不能在if语句中使用字符值 有人提示

我有一个向量,包含几个基于用户输入的单词。它们都使用名为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,即s1s2,则返回false


如果字符相等,我们将继续循环,直到没有字符可供比较。如果两个字符串在我们退出for循环时相等,则返回true或false,具体取决于字符串的长度,较短的字符串表示s1您不需要任何排序选择。这是一个非常简单的查找表,用于查找与qwerty字符串对应的字符。另外,请选择一种语言,C或C++。C++解决方案是两行,也许一条。抱歉,我不习惯浏览这个网站,我认为我输入的标签不正确。我不明白你所说的查找表是什么意思,有没有一个好的参考资料我可以看一下?跳出框框思考。如果我的字是梨呢。什么是序列[myword[0]]、序列[myword[1]]、序列[myword[2]]、序列[myword[3]]?因此,在排序中,您使用PEAR的字符作为查找来比较序列数组的值。它们的数值应该是10,3,11,4,对吗?记住数组是基于0的,所以应该是9,2,10,3。为每个字符分配某种值?我怎么能把排序函数应用到这上面呢?我明白你的意思,但我不需要为字母表的每个字母都设置一个循环吗?如果我给它们分配不同字母的值,它不会打印错误吗?这是我习惯看到的代码样式,所以我想我可以更好地理解它。不过我有点困惑,因为在本例中,“制服”和“上级”这两个词没有正确地按qwerty顺序排序,因为我设置了长度的优先级高于顺序,制服比上级短,所以它将排在第一位。[注:请确保以大写字母输入]顺便说一句,这只是一个示例代码,向您展示它是如何工作的。你可以在结构中设计你自己的排序条件,希望我的分享对你有帮助。对不起,我的帖子不清楚!单词的长度是不相关的,我只是尝试根据字母顺序Q->W->E等进行排序,这样就不需要第一个布尔值了?但是是的,你的例子非常有用!非常感谢您的时间。那么就不需要比较长度了,但您需要找出最短的长度。int shortestLen=s1.length;如果s1.length>s2.length{shortestLen=s2.length}。所以在循环中,使用forint i=0;我是最矮的;i++{您是否注意到您的实例得到了错误的答案?期望的结果是pearach<苹果,而你的实例给出的顺序是peach