如何取消旋转置换索引

Posted

技术标签:

【中文标题】如何取消旋转置换索引【英文标题】:How to un-rotate a permuted index 【发布时间】:2016-07-09 08:19:47 【问题描述】:

我现在正在学习Accelerated C++: Practical Programming by Example,被下面的问题困住了。

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


vector<string> split(const string&s)
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i=0;
    while (i!=s.size())
        while (i!=s.size() && isspace(s[i]))
            i++;
        
        string_size j=i;
        while (j!=s.size() && !isspace(s[j]))
            j++;
        
        if (i!=j)
            ret.push_back(s.substr(i,j-i));
            i=j;
        
    
    return ret;


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


vector<string> Rotation(string&s)
    string ss=s+" "+s;
    vector<string>s1=split(s);
    vector<string>ret;
    ret.push_back(s);
    string::size_type slength=s.size();
    string::size_type count=0;
    for (vector<string>::size_type i=0;i!=s1.size()-1;i++)
        string k=s1[i];
        string::size_type ksize=k.size();
        count+=ksize+1;
        string pushed=ss.substr(count,slength);
        ret.push_back(pushed);
    
    return ret;


string lower(const string&s)
    string ret;
    for(string::size_type i=0;i!=s.size();i++)
        ret.push_back(tolower(s[i]));
    
    return ret;


bool compare(const string& s1, const string& s2)
    return lower(s1)<lower(s2);


int main() 
    string s;
    cout<<"Enter String"<<endl;
    vector<string> vs;
    while (getline(cin,s))
        vector<string>Rotated=Rotation(s);
        vs.insert(vs.end(),Rotated.begin(),Rotated.end());
    
    sort(vs.begin(),vs.end(),compare);
    Display(vs);
    return 0;

我已经完成了第 1 步和第 2 步(旋转和排序),但我不知道如何取消旋转。我已经在这个问题上搜索了一段时间,一些解决方案说我应该在一开始就初始化结构。我想知道我当前的代码是否仍然可以解决最后一步,或者我需要更改我编码的所有内容。

【问题讨论】:

你为什么用awk标记这个?在任何情况下 - edit 你的问题是提供一个 minimal reproducible example 包括简洁、可测试的样本输入和预期输出。 我认为你应该在某处使用std::rotate ...which involves finding the separator 似乎是一个关键短语:听起来您必须人工添加消息结束标记才能取消旋转 【参考方案1】:

我想了一会儿解决了我的这个问题。下面是我的代码。尽管我已经觉得它很好,但有什么方法可以改进我的算法。

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

struct Input
    string word;
    int interpoint;
;

vector<string> split(const string&s)
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i=0;
    while (i!=s.size())
        while (i!=s.size() && isspace(s[i]))
            i++;
        
        string_size j=i;
        while (j!=s.size() && !isspace(s[j]))
            j++;
        
        if (i!=j)
            ret.push_back(s.substr(i,j-i));
            i=j;
        
    
    return ret;


string joinstring(vector<string>&vs)
    string result;
    for (vector<string>::size_type i=0;i!=vs.size();i++)
        if (i==vs.size()-1)
            result+=vs[i];
        else
            result+=vs[i]+" ";
    
    return result;


vector<Input> Rotation(const string& s)
    vector<Input> Rotated;
    vector<string> splited=split(s);
    vector<string>::size_type splitsize=splited.size();
    for (vector<string>::size_type i=0;i!=splitsize;i++)
        Input OneRotated;
        vector<string> splited=split(s);
        rotate(splited.begin(),splited.begin()+i,splited.end());
        OneRotated.interpoint=splitsize-i;
        OneRotated.word=joinstring(splited);
        Rotated.push_back(OneRotated);
    
    return Rotated;



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


string lower(const string&s)
    string ret;
    for(string::size_type i=0;i!=s.size();i++)
        ret.push_back(tolower(s[i]));
    
    return ret;


bool compare(Input& s1, Input& s2)
    return lower(s1.word)<lower(s2.word);


vector<string> Unrotate(vector<Input>& Total, vector<string>& Left)
    vector<string>Right;
    for(vector<Input>::size_type i=0;i!=Total.size();i++)
        vector<string>splited=split(Total[i].word);
        int spoint=Total[i].interpoint;
        vector<string>TheLeft(splited.begin()+spoint,splited.end());
        vector<string>TheRight(splited.begin(),splited.begin()+spoint);
        Left.push_back(joinstring(TheLeft));
        Right.push_back(joinstring(TheRight));
    
    return Right;


vector<string> reconstruct(vector<string>&s)
    string::size_type maxlen=0;
    for (vector<string>::size_type i=0;i!=s.size();i++)
        maxlen=max(maxlen,s[i].size());
    
    vector<string>ret;
    for (vector<string>::size_type j=0;j!=s.size();j++)
        ret.push_back(string(maxlen-s[j].size(),' ')+s[j]);
    
    return ret;



vector<string>hcat(const vector<string>& left, const vector<string>& right)

    vector<string> ret;
    vector<string>::size_type i = 0, j = 0;
    while (i != left.size() || j != right.size()) 

        string s;
        // copy a row from the left-hand side, if there is one
        if (i != left.size())
            s = left[i++];


        if (j != right.size())
            s += "  "+right[j++];

        ret.push_back(s);
    
    return  ret;


int main() 
    string s;
    cout << "Enter String" <<endl;
    vector<Input> vs;
    while (getline(cin, s)) 
        vector<Input> Rotated=Rotation(s);
        vs.insert(vs.end(),Rotated.begin(),Rotated.end());
    
    sort(vs.begin(),vs.end(),compare);
    vector<string> LeftBlock;
    vector<string> RightBlock = Unrotate(vs,LeftBlock);
    Display(hcat(reconstruct(LeftBlock),RightBlock));

    return 0;

【讨论】:

以上是关于如何取消旋转置换索引的主要内容,如果未能解决你的问题,请参考以下文章

如何旋转图像选定行和取消旋转图像未选定行

如何通过取消旋转标题行来转置Excel中的列[重复]

[置换 前缀和]牛牛的猜球游戏

如何避免 Touches 取消事件?

如何从 PHP 数组中取消设置数字索引元素?

旋转或取消旋转小桌子