|
| 1 | +# 问题 |
| 2 | + |
| 3 | +将字符串中的单词逆序输出。标点符号也被视为有效字符。所有单词以空格分割。 |
| 4 | + |
| 5 | +例子:pig 123 456 |
| 6 | + |
| 7 | +输出:456 123 pig |
| 8 | + |
| 9 | +# 思路 |
| 10 | + |
| 11 | +## 1 整体交换 |
| 12 | + |
| 13 | +先对字符串进行整体交换, |
| 14 | + |
| 15 | +将第1个字符和倒数第1个字符交换,将第2个字符和倒数第2个字符交换。 |
| 16 | + |
| 17 | +循环,直到到达了字符串的中间位置,退出。 |
| 18 | + |
| 19 | +如果到达字符串中间位置后,还继续遍历并执行交换,就会将之前已经交换的字符又再交换回去。 |
| 20 | + |
| 21 | +比如,倒数第1个字符将重新和第1个字符交换,倒数第二个字符将重新和第2个字符进行交换。 |
| 22 | + |
| 23 | +## 1.1 例子 |
| 24 | + |
| 25 | +给定字符串 `pig`,长度为3,中间下标为 `index = 3 / 2 = 1`。 |
| 26 | + |
| 27 | +1. i = 0,将 `pig`第1个字符和倒数第1个字符交换,也就是 `p` 和 `g` 互换,得到 `gip` |
| 28 | +2. i = 1,将 `gip`第2个字符和倒数第2个字符交换,也就是 `i` 和 `i` 自己换,得到 `gip` |
| 29 | +3. i = 2, 此时已经超过了中间下标 ,退出循环。 |
| 30 | + |
| 31 | +最终得到 `gip` |
| 32 | + |
| 33 | +如果继续执行i = 2,此时会将 `gip` 第2个字符与倒数第2个字符交换,也就是 `p` 和 `g` 互换,得到 `pig` |
| 34 | + |
| 35 | +## 2 局部交换 |
| 36 | + |
| 37 | +对每个单词进行局部交换。 |
| 38 | + |
| 39 | +先根据空格来分割单词,对于1个单词,将它第1个字符和倒数第1个字符交换,将第2个字符和倒数第2个字符交换。直到到达了单词的中间位置。 |
| 40 | + |
| 41 | +## 2.1 例子 |
| 42 | + |
| 43 | +给定字符串 `gip gip`,交换后,变成 `pig gip`。 |
| 44 | + |
| 45 | +注意看,经过以上步骤后,最后一个单词 `gip` 是没有改变的。 |
| 46 | + |
| 47 | +这是由于最后一个单词的后面没有空格,然而,单词分割是依赖空格去分割的, |
| 48 | + |
| 49 | +在遍历到字符串最后一个单词时,就会直接退出循环,而不进入交换的操作。 |
| 50 | + |
| 51 | +所以,完成第2步后,还需要将字符串的最后一个单词进行手动的交换。 |
| 52 | + |
| 53 | +## 2.2例子 |
| 54 | + |
| 55 | +给定字符串 `pig gip`,手动交换后,变成 `pig pig`。 |
| 56 | + |
| 57 | +# 3 实现代码 |
| 58 | + |
| 59 | +```csharp |
| 60 | +// 问题:将字符串中的单词逆序输出。标点符号也被视为有效字符。所有单词以空格分割。 |
| 61 | +using System; |
| 62 | +namespace HelloWorldApplication |
| 63 | +{ |
| 64 | + class HelloWorld |
| 65 | + { |
| 66 | + static void Main(string[] args) |
| 67 | + { |
| 68 | + string input = "pig 123 456"; |
| 69 | + HelloWorld helloWorld = new HelloWorld(); |
| 70 | + helloWorld.TraverseString(ref input); |
| 71 | + Console.WriteLine(input); |
| 72 | + Console.ReadKey(); |
| 73 | + } |
| 74 | + |
| 75 | + void TraverseString(ref string input){ |
| 76 | + char[] charArray = input.ToCharArray(); |
| 77 | + // 1. 字符串从前往后遍历,交换每个字符 |
| 78 | + SwapEachChar(ref charArray); |
| 79 | + // 2. 对每个单词,交换单词中每个字符 |
| 80 | + SwapEachWord(ref charArray); |
| 81 | + // 3. 修改原始字符串 |
| 82 | + input = new String(charArray); |
| 83 | + } |
| 84 | + |
| 85 | + void SwapEachChar(ref char[] charArray){ |
| 86 | + for(int i = 0; i < charArray.Length / 2; i++){ |
| 87 | + int index = charArray.Length - 1 - i; |
| 88 | + SwapChar(charArray, i, index); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + void SwapEachWord(ref char[] charArray){ |
| 93 | + int begin = 0, end; |
| 94 | + for(int i = 0; i < charArray.Length; i++){ |
| 95 | + if(charArray[i] == ' '){ |
| 96 | + end = i - 1; |
| 97 | + if(begin < end){ |
| 98 | + SwapWord(charArray, begin, end); |
| 99 | + begin = i + 1; |
| 100 | + } |
| 101 | + } |
| 102 | + } |
| 103 | + SwapWord(charArray, begin, charArray.Length - 1); |
| 104 | + } |
| 105 | + |
| 106 | + void SwapWord(char[] input, int begin, int end){ |
| 107 | + while(begin < end){ |
| 108 | + SwapChar(input, begin, end); |
| 109 | + begin++; |
| 110 | + end--; |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + void SwapChar(char[] charArray, int i1, int i2){ |
| 115 | + if(i1 < 0 || i2 < 0 || i1 >= charArray.Length || i2 >= charArray.Length){ |
| 116 | + Console.WriteLine("Error"); |
| 117 | + return; |
| 118 | + } |
| 119 | + char temp = charArray[i1]; |
| 120 | + charArray[i1] = charArray[i2]; |
| 121 | + charArray[i2] = temp; |
| 122 | + } |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
0 commit comments