题目要求:
给定一个n位字符串,要求将字符串前面的m个字符移到字符串尾部。
解法一:暴力移位法
也就是要移多少位就一位一位地移。
时间复杂度O(mn),空间复杂度O(1)。
void ShiftOne(char *text,int n)//移动一个字符
{
char t=text[0];
for(int i=1;i<n;i++)
{
text[i-1]=text[i];
}
text[n-1]=t;
}
void ShiftAll(char *text,int n,int m)//逐次移动
{
while(m--)
{
ShiftOne(text,n);
}
}
解法二:三位反转法
以要移位的地方为分界线,将字符串0~m位反转,将m~(n-1)位反转,再将0~(n-1)位反转,经过三次反转之后可以得到后移m位的结果。
时间复杂度O(n),空间复杂度O(1)。
void ShiftOneText(char *text,int first,int last)//反转一个字符串
{
while(first<last)
{
char t=text[first];
text[first++]=text[last];
text[last--]=t;
}
}
void ShiftAllText(char *text,int n,int m)//反转全过程
{
m=m%n;//如果text17位,那移动20位和移动3位是一样的
ShiftOneText(text,0,m-1);
ShiftOneText(text,m,n-1);
ShiftOneText(text,0,n-1);
}
扩展
题目要求:
输入一个英文句子,翻转句子中单词的顺序。要求单词内字符的顺序不变,句子中单词以空格符隔开。
为简单起见,标点符号和普通字母一样处理。例如输入"I am a student.",则输出"student. a am I"。
解法:以空格为单位将字符串逐块反转,然后再整体反转。比如原字符串为"This is my pen.",以空格反转之后是"sihT si ym .nep",再将整体反转就得到"pen. my is This"。
string ReverseSentence(string text)
{
int i=0,j=0;
string str=text;
while(j<str.length())
{
if(str[j]==' ' || j==str.length()-1)
{
int m=i,n=j-1;
if(str[j]!=' ')
n=j;
while(m<n)
{
char t=str[m];
str[m++]=str[n];
str[n--]=t;
}
i=j+1;
}
j++;
}
i=0;
j=str.length()-1;
while(i<j)
{
char t=str[i];
str[i++]=str[j];
str[j--]=t;
}
return str;
}