面试题42:翻转单词顺序VS左旋转字符串

题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。

例如输入字符串“I am a student.",则输出"student. a am I"。

解法一:利用字符串流分割单词

1 void reverseWords(string &s) {

2         istringstream sstr(s);

3         s = "";

4         string str;

5         while (sstr>>str)

6                 s = str + ' ' + s;

7         if (!s.empty())//删除最后一个多余的空格

8             s.erase(s.end()-1);

9     }

解法二:先翻转整个句子,再翻转句子中的单词

 1 void reverse(string&s, int left, int right)

 2 {//翻转字符串s的一个子字符串

 3   while(left < right)

 4   {

 5     char temp = s[left];

 6     s[left] = s[right];

 7     s[right] = temp;

 8     left++;

 9     right--;

10   }

11 }

12 void reverseSentence(string&s)

13 {

14     if (s.empty())

15         return ;

16     int left = 0;

17     int right = s.size()-1;

18     reverse(s, left,right);

19     left = 0;

20     right = 0;

21     while (left!=s.size())

22     {

23         if (s[left]==' ')

24         {

25             left++;

26             right++;

27         }

28         else if (s[right]==' ' || right == s.size())

29         {

30             reverse(s,left,--right);

31             left = ++right;

32         }

33         else

34         {

35             right++;

36         }

37     }

38 }

 题目二:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如输入字符串

"abcdefg"和数字2,该函数将返回左旋转2位得到的结果"cdefgab"。

分析:题目二与题目一相似,同样可以通过翻转字符串的办法来解决。以"abcdefg"为例,我们可以将它分为两部分。由于想把它的前两个字符移到后面,我们就把前两个字符分成第一部分,把后面的字符分成第二部分。我们先分别翻转这两部分,于是就得到”bagfedc”,再翻转整个字符串就可以得到"cdefgab",刚好就是字符串左旋转两位的结果。

void leftRotateString(string&s, int n)

{

    int length = s.size();

    if (length == 0 || n < 0)

        return;

    n = n%length;

    int left = 0, middle = left+n-1, right = length-1;

    reverse(s,left,middle);

    reverse(s,middle+1,right);

    reverse(s,left,right);

}

 

你可能感兴趣的:(字符串)