如何取消旋转置换索引
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;
【讨论】:
以上是关于如何取消旋转置换索引的主要内容,如果未能解决你的问题,请参考以下文章