我需要从给定的输入字符串中找到按字典顺序排列的最大字符串。 所以如果输入是
enjoy
o / p应该是
yenjo
我试过的代码是......
int n;
cout<<"Enter the number of strings";
cin>>n;
int len[n];
char str[n][1000];
for(int i=0;i<n;i++)
{
cin>>str[i];
len[i]=strlen(str[i]);
}
int num,pos[n];
for(int i=0;i<n;i++)
{
pos[i]=0;
num=int(str[i][0]);
for(int j=1;j<len[i];j++)
{
if(int(str[i][j])>num)
{
num=int(str[i][j]);
pos[i]=j;
}
}
}
int i,j,k;
char temp[1];
for(i=0;i<n;i++)
{
for(j=0;j<pos[i];j++)
{
temp[0]=str[i][0];
for(k=0;k<len[i];k++)
{
str[i][k]=str[i][k+1];
}
strcat(str[i],temp);
str[i][len[i]]='\0';
}
cout<<str[i]<<"\n";
}
return 0;
}
但是这段代码只有最大数量的ckecks而不是它旁边的数字,因此i / p
失败blowhowler
o / p应为wlerblowho
,但我将o / p视为whowlerblo
。
如何跟踪最大字符前面的每个元素以获得正确的输出?
答案 0 :(得分:1)
为了在平均情况下获得良好的性能(实际上是O(N)),但在最差的情况下仍然是O ^ 2(并且总是正确的),您可以跟踪可能性,并随时随地消除它们。基本上是这样的。
struct PermSum
{
int sum;
int perm;
}
LinkedList<PermSum> L;
for(int i = 0; i != input.size(); ++i) L.append(PermSum{0,i});
int depth = 0;
int max = 0;
const int length = input.size()
while(L.size() > 1 && depth < length)
{
for(l in L)
{
l.sum += input[(l.perm + depth) % length]
if (l.sum > max) max = l.sum
}
for(l in L)
{
if (l.sum < max) L.delete(l)
}
depth ++;
}
if (L.size() == 1)
return L.front().perm
else
return -1
我在某些部分使用c ++代码有点懒,但我确定你可以在l中找出l。关键是第一个for循环。这个想法是它在l.perm-th排列的深度字母处添加了词典值。通过这种方式,它可以更新所有可能性,同时跟踪最佳可能性的级别。然后你做第二遍以删除任何不符合最佳状态的可能性。值得注意的是,我对其进行编码的方式,它可能使用与循环排列的标准约定相反的方式。也就是说,我的程序中的perm字段表示向左移动多少个点,而通常正数是向右移动的。你可以用某个减号来解决这个问题。
至于运行时间分析,它与Quickselect基本相同。每次while循环迭代都需要与L的长度成比例的时间。第一次迭代,L将始终具有length = N(其中N是字符串的长度,与代码中的变量长度相同)。下一轮,我们通常只期望1/26的数据通过,再次在1/26之后的回合...所以我们有N(1 + 1/26 + 2/26 ^ 2 ...)是O(N)。
答案 1 :(得分:1)
你可以: 1.产生旋转 2.将所有旋转放在地图中&lt;&gt; 3.找到地图的最后一个元素。 这是C ++中的实现。
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
int main() {
// your code goes here
string str;int len,i=0,j=0,k=0;char temp;
cin>>str;
len = str.length();
map<string,int>m;
while(i<len)
{
temp = str[0];
while(j<len-1)
{
str[j] = str[j+1];
j++;
}
str[j] = temp;
m[str] = k;
k++;
i++;j=0;
}
str = m.rbegin()->first;
cout<<str;
return 0;
}
答案 2 :(得分:1)
通过首先将字符串附加到自身并从中构建后缀数组,可以在O(n log n)时间内解决问题。找到相应的条目,并找到您想要的结果。实施留作练习。
答案 3 :(得分:1)
//Here the index with greater value is selected,
//if the same char occurs again the next characters
// of prev and curr characters is checked:-Prev=maxIndex,curr=i
#include<bits/stdc++.h>
using namespace std;
int getIndex(char *str){
int max=INT_MIN,maxIndex;
int n=strlen(str);
int j,p;
for(int i=0;i<n;i++)
{
if(str[i]>max)
{
max=str[i];
maxIndex=i;
}
else if(str[i]==max)
{
j=maxIndex+1;
p=(i+1)%n;
while(j<n && p<n && str[j]==str[p]){
j++;
p=(p+1)%n;
}
maxIndex=str[p]>str[j]?i:maxIndex;
}
}
return maxIndex;
}
int main(void)
{
char str[4000008];
scanf("%s",str);
int i=getIndex(str);
for(int j=i;j<strlen(str);j++)
cout<<str[j];
for(int j=0;j<i;j++)
cout<<str[j];
}
答案 4 :(得分:0)
您的算法已更正,可归结为:
wrapcmp
。时间复杂度:O(n * n)
空间复杂性:就地
// Function to do ordinal-comparison on two rotations of a buffer
// buffer: The buffer containing the string
// n: The buffers size (string-length)
// a: Index where the first buffer starts pre-rotation
// b: Index where the second buffer starts pre-rotation
int wrapcmp(const void* buffer, size_t n, size_t a, size_t b) {
auto x = (const unsigned char*)buffer;
auto m = n - std::max(a, b);
int ret = memcmp(x+a, x+b, m);
if(ret) return ret;
auto left = n - m;
a = (a + m) % n;
b = (b + m) % n;
m = left - std::max(a, b);
ret = memcmp(x+a, x+b, m);
if(ret) return ret;
a = (a + m) % n;
b = (b + m) % n;
return memcmp(x+a, x+b, left - m);
}
用于coliru:http://coliru.stacked-crooked.com/a/4b138a6394483447
把它放到一般的算法中留下作为读者的练习。
答案 5 :(得分:0)
这太诱人了,所以我不妨发表我的努力。不确定它如何评价效率wize。就我测试它似乎有效:
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
std::string max_rot(const std::string& s)
{
std::string tmp;
std::string max;
std::string::const_iterator m = std::max_element(s.begin(), s.end());
if(m != s.end())
for(char c = *m; (m = std::find(m, s.end(), c)) != s.end(); ++m)
if(max < tmp.assign(m, s.end()).append(s.begin(), m))
max = tmp;
return max;
}
int main()
{
size_t times = 0;
std::string text;
do { std::cout << "\nHow many words? : "; }
while(std::getline(std::cin, text) && !(std::istringstream(text) >> times));
std::vector<std::string> words;
while(times-- && (std::cin >> text))
words.push_back(text);
for(const auto& s: words)
std::cout << max_rot(s) << '\n';
}
作为解释。它在字符串中找到最高字符值,并旋转字符串以使该字符成为第一个。如果然后在字符串的其余部分中查找重复的最高字符,则跟踪最高尝试次数。可能还有优化空间。
答案 6 :(得分:0)
这项挑战在积极的比赛中使用,我请求在9月18日晚上9点之前提供答案。由于代码可见,我们可能必须禁止用户参与我们未来的任何竞赛。