国际太阳娱乐网站2138字符串反转的9种方法

 

面是实现字符串反转的四种方法:

转自:

方法一:

国际太阳娱乐网站2138 1            static string Reverse1(string original)
国际太阳娱乐网站2138 2国际太阳娱乐网站2138 3            …{
国际太阳娱乐网站2138 4                char[] arr = original.ToCharArray();
国际太阳娱乐网站2138 5                Array.Reverse(arr);
国际太阳娱乐网站2138 6                return new string(arr);
国际太阳娱乐网站2138 7            }
国际太阳娱乐网站2138 8
国际太阳娱乐网站2138 9            static string Revease21(string original)
国际太阳娱乐网站2138 10国际太阳娱乐网站2138 11            …{
国际太阳娱乐网站2138 12                int length = original.Length;
国际太阳娱乐网站2138 13                char[] arr = new char[length];
国际太阳娱乐网站2138 14                for (int i = 0; i < (length & (~3)); i += 4)
国际太阳娱乐网站2138 15国际太阳娱乐网站2138 16                …{
国际太阳娱乐网站2138 17                    arr[i] = original[length – i – 1];
国际太阳娱乐网站2138 18                    arr[i+1] = original[length – i – 2];
国际太阳娱乐网站2138 19                    arr[i+2] = original[length – i – 3];
国际太阳娱乐网站2138 20                    arr[i+3] = original[length – i – 4];
国际太阳娱乐网站2138 21                }
国际太阳娱乐网站2138 22                for (int i = length & (~3); i < length; i++)
国际太阳娱乐网站2138 23国际太阳娱乐网站2138 24                …{
国际太阳娱乐网站2138 25                    arr[i] = original[length – i – 1];
国际太阳娱乐网站2138 26                }
国际太阳娱乐网站2138 27                return new string(arr);
国际太阳娱乐网站2138 28            }
国际太阳娱乐网站2138 29
国际太阳娱乐网站2138 30            static string Revease22(string original)
国际太阳娱乐网站2138 31国际太阳娱乐网站2138 32            …{
国际太阳娱乐网站2138 33                int length = original.Length;
国际太阳娱乐网站2138 34                char[] arr = new char[length];
国际太阳娱乐网站2138 35                for (int i = 0; i < length; i++)
国际太阳娱乐网站2138 36国际太阳娱乐网站2138 37                …{
国际太阳娱乐网站2138 38                    arr[i] = original[length – i – 1];
国际太阳娱乐网站2138 39                }
国际太阳娱乐网站2138 40                return new string(arr);
国际太阳娱乐网站2138 41            }
国际太阳娱乐网站2138 42
国际太阳娱乐网站2138 43            static string Revease3(string original)
国际太阳娱乐网站2138 44国际太阳娱乐网站2138 45            …{
国际太阳娱乐网站2138 46                int length = original.Length;
国际太阳娱乐网站2138 47                StringBuilder sb = new StringBuilder(length);
国际太阳娱乐网站2138 48                for (int i = length-1; i >= 0; i–)
国际太阳娱乐网站2138 49                sb.Append(original[i]);
国际太阳娱乐网站2138 50                return sb.ToString();
国际太阳娱乐网站2138 51            }

 

public static string Reverse(string name)
{
     if (String.IsNullOrEmpty(name))
       {
           throw new Exception(“字符串不能为空!”);
       }
    StringBuilder sb = new StringBuilder(name.Length);
    for (int i = name.Length-1; i >= 0; i–)
     {
        sb.Append(name[i]);
    }
        return sb.ToString();
}

 Revease1()中对char[]进行了两次赋值(ToCharArray()和Array.Revease),所以我有想到了Revease2和Revease3()两种方法,下面是对这四种方法进行简单性能测试的代码:

1. 使用Array.Reverse方法

 

国际太阳娱乐网站2138 52   static void Main(string[] args)
国际太阳娱乐网站2138 53国际太阳娱乐网站2138 54            …{
国际太阳娱乐网站2138 55                string testString = “测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转”;
国际太阳娱乐网站2138 56                DateTime start = DateTime.Now;
国际太阳娱乐网站2138 57                for (int i = 0; i < 3000000; i++)
国际太阳娱乐网站2138 58国际太阳娱乐网站2138 59                …{
国际太阳娱乐网站2138 60                    string s = Reverse1(testString);
国际太阳娱乐网站2138 61                }
国际太阳娱乐网站2138 62                DateTime end = DateTime.Now;
国际太阳娱乐网站2138 63                Console.WriteLine(“1 :  “+(end – start));
国际太阳娱乐网站2138 64
国际太阳娱乐网站2138 65                start = DateTime.Now;
国际太阳娱乐网站2138 66                for (int i = 0; i < 3000000; i++)
国际太阳娱乐网站2138 67国际太阳娱乐网站2138 68                …{
国际太阳娱乐网站2138 69                    string s = Revease21(testString);
国际太阳娱乐网站2138 70                }
国际太阳娱乐网站2138 71                end = DateTime.Now;
国际太阳娱乐网站2138 72                Console.WriteLine(“21:  ” + (end – start));
国际太阳娱乐网站2138 73
国际太阳娱乐网站2138 74                start = DateTime.Now;
国际太阳娱乐网站2138 75                for (int i = 0; i < 3000000; i++)
国际太阳娱乐网站2138 76国际太阳娱乐网站2138 77                …{
国际太阳娱乐网站2138 78                    string s = Revease22(testString);
国际太阳娱乐网站2138 79                }
国际太阳娱乐网站2138 80                end = DateTime.Now;
国际太阳娱乐网站2138 81                Console.WriteLine(“22:  ” + (end – start));
国际太阳娱乐网站2138 82
国际太阳娱乐网站2138 83                start = DateTime.Now;
国际太阳娱乐网站2138 84                for (int i = 0; i < 3000000; i++)
国际太阳娱乐网站2138 85国际太阳娱乐网站2138 86                …{
国际太阳娱乐网站2138 87                    string s = Revease3(testString);
国际太阳娱乐网站2138 88                }
国际太阳娱乐网站2138 89                end = DateTime.Now;
国际太阳娱乐网站2138 90                Console.WriteLine(“3 :  ” + (end – start));
国际太阳娱乐网站2138 91
国际太阳娱乐网站2138 92                Console.ReadLine();
国际太阳娱乐网站2138 93            }

对于字符串反转,我们可以使用.NET类库自带的Array.Reverse方法

方法二:.NET3.5以上

测试结果是Revease1()代码最简洁,运行速度也最快,Revease21()和Revease22()其次,Revease3()最慢。可见.net
framework中实现的ToCharArray()和Array.Revease()效率还是蛮高的^_^

public static string ReverseByArray(string original)
{
char[] c = original.ToCharArray();
Array.Reverse(c);
return new string(c);
}

public static string Reverse(string name)
{
     char[] reverse = name.Reverse().ToArray();

但还有个奇怪的问题,就是Debug版本中的Revease1()和Revease21()运行起来要比Release版本中的要快,而Revease22()和Revease3()就比较正常。按说Release时做了更多的优化工作,运行起来更快才对,迷惑ing…,下面是测试结果:

2. 使用字符缓存

     return new string(reverse);
}

Debug:

在面试或笔试中,往往要求不用任何类库方法,那么有朋友大概会使用类似下面这样的循环方法

 

1 :  00:00:03.4375000
21:  00:00:06.1250000
22:  00:00:09.9687500
3 :  00:01:05.5468750

public static string ReverseByCharBuffer(this string original)
{
char[] c = original.ToCharArray();
int l = original.Length;
char[] o = new char[l];
for (int i = 0; i < l ; i++)
{
o[i] = c[l – i – 1];
}
return new string(o);
}

方法三:二分法

Release:

当然,聪明的同学们一定会发现不必对这个字符数组进行完全遍历,通常情况下我们会只遍历一半

public static string Reverse(string name)
{
   if (String.IsNullOrEmpty(name))
   {
      throw new Exception(“字符串不能为空!”);
   }
  char[] nm = name.ToCharArray();
  for (int i = 0; i < (nm.Length-1 )/ 2; i++)
  {
     char q = nm[i];
     nm[i]= nm[nm.Length – 1 – i];
    nm[nm.Length – 1 – i] = q;
  }

1 :  00:00:05.7812500
21:  00:00:07.4218750
22:  00:00:08.2500000
3 :  00:00:50.3593750

public static string ReverseByCharBuffer2(string original)
{
char[] c = original.ToCharArray();
int l = original.Length;
for (int i = 0; i < l / 2; i++)
{
char t = c[i];
c[i] = c[l – i – 1];
c[l – i – 1] = t;
}
return new string(c);
}

  return new string(nm);

附1:Array.Revease()方法的源码(由Reflector.exe反汇编得到):

ReverseByCharBuffer使用了一个新的数组,而且遍历了字符数组的所有元素,因此时间和空间的开销都要大于ReverseByCharBuffer2。

}

国际太阳娱乐网站2138 94[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
国际太阳娱乐网站2138 95public static void Reverse(Array array)
国际太阳娱乐网站2138 96国际太阳娱乐网站2138 97…{
国际太阳娱乐网站2138 98      if (array == null)
国际太阳娱乐网站2138 99国际太阳娱乐网站2138 100      …{
国际太阳娱乐网站2138 101            throw new ArgumentNullException(“array”);
国际太阳娱乐网站2138 102      }
国际太阳娱乐网站2138 103      Array.Reverse(array, array.GetLowerBound(0), array.Length);
国际太阳娱乐网站2138 104}
国际太阳娱乐网站2138 105
国际太阳娱乐网站2138 106[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
国际太阳娱乐网站2138 107public static void Reverse(Array array, int index, int length)
国际太阳娱乐网站2138 108国际太阳娱乐网站2138 109…{
国际太阳娱乐网站2138 110      int num1;
国际太阳娱乐网站2138 111      int num2;
国际太阳娱乐网站2138 112      if (array == null)
国际太阳娱乐网站2138 113国际太阳娱乐网站2138 114      …{
国际太阳娱乐网站2138 115            throw new ArgumentNullException(“array”);
国际太阳娱乐网站2138 116      }
国际太阳娱乐网站2138 117      if ((index < array.GetLowerBound(0)) || (length < 0))
国际太阳娱乐网站2138 118国际太阳娱乐网站2138 119      …{
国际太阳娱乐网站2138 120            throw new ArgumentOutOfRangeException((index < 0) ? “index” : “length”, Environment.GetResourceString(“ArgumentOutOfRange_NeedNonNegNum”));
国际太阳娱乐网站2138 121      }
国际太阳娱乐网站2138 122      if ((array.Length – (index – array.GetLowerBound(0))) < length)
国际太阳娱乐网站2138 123国际太阳娱乐网站2138 124      …{
国际太阳娱乐网站2138 125            throw new ArgumentException(Environment.GetResourceString(“Argument_InvalidOffLen”));
国际太阳娱乐网站2138 126      }
国际太阳娱乐网站2138 127      if (array.Rank != 1)
国际太阳娱乐网站2138 128国际太阳娱乐网站2138 129      …{
国际太阳娱乐网站2138 130            throw new RankException(Environment.GetResourceString(“Rank_MultiDimNotSupported”));
国际太阳娱乐网站2138 131      }
国际太阳娱乐网站2138 132      if (!Array.TrySZReverse(array, index, length))
国际太阳娱乐网站2138 133国际太阳娱乐网站2138 134      …{
国际太阳娱乐网站2138 135            num1 = index;
国际太阳娱乐网站2138 136            num2 = (index + length) – 1;
国际太阳娱乐网站2138 137            object[] objArray1 = array as object[];
国际太阳娱乐网站2138 138            if (objArray1 == null)
国际太阳娱乐网站2138 139国际太阳娱乐网站2138 140            …{
国际太阳娱乐网站2138 141                  goto Label_00DE;
国际太阳娱乐网站2138 142            }
国际太阳娱乐网站2138 143            while (num1 < num2)
国际太阳娱乐网站2138 144国际太阳娱乐网站2138 145            …{
国际太阳娱乐网站2138 146                  object obj1 = objArray1[num1];
国际太阳娱乐网站2138 147                  objArray1[num1] = objArray1[num2];
国际太阳娱乐网站2138 148                  objArray1[num2] = obj1;
国际太阳娱乐网站2138 149                  num1++;
国际太阳娱乐网站2138 150                  num2–;
国际太阳娱乐网站2138 151            }
国际太阳娱乐网站2138 152      }
国际太阳娱乐网站2138 153      return;
国际太阳娱乐网站2138 154Label_00DE:
国际太阳娱乐网站2138 155      if (num1 >= num2)
国际太阳娱乐网站2138 156国际太阳娱乐网站2138 157      …{
国际太阳娱乐网站2138 158            return;
国际太阳娱乐网站2138 159      }
国际太阳娱乐网站2138 160      object obj2 = array.GetValue(num1);
国际太阳娱乐网站2138 161      array.SetValue(array.GetValue(num2), num1);
国际太阳娱乐网站2138 162      array.SetValue(obj2, num2);
国际太阳娱乐网站2138 163      num1++;
国际太阳娱乐网站2138 164      num2–;
国际太阳娱乐网站2138 165      goto Label_00DE;
国际太阳娱乐网站2138 166}

在Array.Reverse内部,调用了非托管方法TrySZReverse,如果TrySZReverse不成功,实际上也是调用了类似ReverseByCharBuffer2的方法。

 

附2:StringBuilder.Append()方法的源码(由Reflector.exe反汇编得到):

if (!TrySZReverse(array, index, length))
{
int num = index;
int num2 = (index + length) – 1;
object[] objArray = array as object[];
if (objArray == null)
{
while (num < num2)
{
object obj3 = array.GetValue(num);
array.SetValue(array.GetValue(num2), num);
array.SetValue(obj3, num2);
num++;
num2–;
}
}
else
{
while (num < num2)
{
object obj2 = objArray[num];
objArray[num] = objArray[num2];
objArray[num2] = obj2;
num++;
num2–;
}
}
}

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图