问题:如何把字符串 “We are the world” 转成 “world the are we” ?如果最多只能用两个额外的变量又该如何实现这样的转换?
分析:1.把字符串转成字符数组,然后对字符数组进行操作。
2.选择倒置字符数组的方法:用一个临时变量来交换两个字符;如果元素整数可以利用 A=A+B, B=A-B, A=A-B 方式来交换元素。
3.根据数组中首尾字符的位置来倒置它们之间的字符。
4.优化方法:减少循环的次数,减少变量的个数。
C#代码:
using System.Linq; namespace MyTest { /// <summary> /// 用最少的变量和最高的效率实现: /// 把"we are the world"倒置成"world the are we" /// </summary> public class Program { static void Main(string[] args) { //待处理的字符串 string myStr = "we are the world"; System.Console.WriteLine("原始字符串:{0}", myStr); System.Console.WriteLine("改进方法的处理结果:{0}", ReverseArray(myStr.ToArray())); System.Console.ReadKey(); } /// <summary> /// 倒置字符数组,改进后的方法 /// 改进地方: /// 1.只利用两个额外的变量:start 和 end /// 2.最多两层循环 /// </summary> /// <param name="array">被倒置的字符数组</param> /// <returns>倒置后的字符数组</returns> static string ReverseArray(char[] array) { //第一步:把整个字符数组倒置 ReverseArrayEmlement(array, 0, array.Length - 1); //第二步:依次倒置字符数组中的某个单词(不包括最后一个单词) //记录某个单词的起始位置 int wordStartPosition = 0; for (int wordEndPosition = 0; wordEndPosition < array.Length; wordEndPosition++) { if (array[wordEndPosition] == ' ') { ReverseArrayEmlement(array, wordStartPosition, wordEndPosition - 1); wordStartPosition = wordEndPosition + 1; } } //第三步:倒置字符数组中的最后一个单词 for (int wordEndPosition = array.Length - 1; wordEndPosition > 0; wordEndPosition--) { if (array[wordEndPosition] == ' ') { ReverseArrayEmlement(array, wordEndPosition + 1, array.Length - 1); break; } } //返回字符串 return new string(array); } /// <summary> /// 倒置字符数组中,起始位置和结束位置之间的字符 /// </summary> /// <param name="localArray">字符数组</param> /// <param name="startPosition">起始位置</param> /// <param name="endPosition">结束位置</param> static void ReverseArrayEmlement(char[] localArray, int startPosition, int endPosition) { // 注意:(startPosition + endPosition) / 2 + 1 这里必须+1,不然最中间位置的两个元素就没有交换了 // 1.利用辅助变量,依次交换数组中的头尾元素(优点:数组元素类型可以为任意类型,缺点:需要额外存储空间) char temp = ' '; for (int i = startPosition; i < (startPosition + endPosition) / 2 + 1; i++) { temp = localArray[i]; localArray[i] = localArray[startPosition + endPosition - i]; localArray[startPosition + endPosition - i] = temp; } // 2.结合整数运算规则,依次交换数组中的头尾元素(优点:不需要任何额外空间,缺点:数组元素类型只能是整数类型) for (int i = startPosition; i < (startPosition + endPosition) / 2 + 1; i++) { //交换两个整型变量的思路: a = a + b, b = a - b, a = a - b //注意:当 a=b 时,该方法就会出错,把 a 变成 0 了 if (i != startPosition + endPosition - i) { localArray[i] = (char)(localArray[i] + localArray[startPosition + endPosition - i]); localArray[startPosition + endPosition - i] = (char)(localArray[i] - localArray[startPosition + endPosition - i]); localArray[i] = (char)(localArray[i] - localArray[startPosition + endPosition - i]); } } // 3.模拟移位操作,每次交换数组元素后都移动整个数组(优点:可以通过移位来实现字符串的倒置,缺点:需要额外空间、移位操作在数组中好像无法实现) char temp1 = ' '; for (int i = startPosition; i < endPosition + 1; i++) { temp1 = localArray[endPosition]; for (int j = 0; j < endPosition - i; j++) { localArray[endPosition - j] = localArray[endPosition - j - 1]; } localArray[i] = temp1; } } } }