9159金沙游艺场

图片 4
Bootstrap 4 alpha 发布

9159金沙游艺场Linux内存测量(基础篇)

字符串反转的9种方法

方法二:.NET3.5以上

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

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);
}

 

Debug:

在C#中,x ^= y相当于x = x ^
y。通过3次异或操作,可以将两个字符为止互换。对于算法具体的解释可以参考这篇文章。
6. 使用指针

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();
}

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

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

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[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
图片 2public static void Reverse(Array array)
图片 3图片 4…{
图片 5      if (array == null)
图片 6图片 7      …{
图片 8            throw new ArgumentNullException(“array”);
图片 9      }
图片 10      Array.Reverse(array, array.GetLowerBound(0), array.Length);
图片 11}
图片 12
图片 13[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
图片 14public static void Reverse(Array array, int index, int length)
图片 15图片 16…{
图片 17      int num1;
图片 18      int num2;
图片 19      if (array == null)
图片 20图片 21      …{
图片 22            throw new ArgumentNullException(“array”);
图片 23      }
图片 24      if ((index < array.GetLowerBound(0)) || (length < 0))
图片 25图片 26      …{
图片 27            throw new ArgumentOutOfRangeException((index < 0) ? “index” : “length”, Environment.GetResourceString(“ArgumentOutOfRange_NeedNonNegNum”));
图片 28      }
图片 29      if ((array.Length – (index – array.GetLowerBound(0))) < length)
图片 30图片 31      …{
图片 32            throw new ArgumentException(Environment.GetResourceString(“Argument_InvalidOffLen”));
图片 33      }
图片 34      if (array.Rank != 1)
图片 35图片 36      …{
图片 37            throw new RankException(Environment.GetResourceString(“Rank_MultiDimNotSupported”));
图片 38      }
图片 39      if (!Array.TrySZReverse(array, index, length))
图片 40图片 41      …{
图片 42            num1 = index;
图片 43            num2 = (index + length) – 1;
图片 44            object[] objArray1 = array as object[];
图片 45            if (objArray1 == null)
图片 46图片 47            …{
图片 48                  goto Label_00DE;
图片 49            }
图片 50            while (num1 < num2)
图片 51图片 52            …{
图片 53                  object obj1 = objArray1[num1];
图片 54                  objArray1[num1] = objArray1[num2];
图片 55                  objArray1[num2] = obj1;
图片 56                  num1++;
图片 57                  num2–;
图片 58            }
图片 59      }
图片 60      return;
图片 61Label_00DE:
图片 62      if (num1 >= num2)
图片 63图片 64      …{
图片 65            return;
图片 66      }
图片 67      object obj2 = array.GetValue(num1);
图片 68      array.SetValue(array.GetValue(num2), num1);
图片 69      array.SetValue(obj2, num2);
图片 70      num1++;
图片 71      num2–;
图片 72      goto Label_00DE;
图片 73}

return original;
}
}

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

图片 74   static void Main(string[] args)
图片 75图片 76            …{
图片 77                string testString = “测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转”;
图片 78                DateTime start = DateTime.Now;
图片 79                for (int i = 0; i < 3000000; i++)
图片 80图片 81                …{
图片 82                    string s = Reverse1(testString);
图片 83                }
图片 84                DateTime end = DateTime.Now;
图片 85                Console.WriteLine(“1 :  “+(end – start));
图片 86
图片 87                start = DateTime.Now;
图片 88                for (int i = 0; i < 3000000; i++)
图片 89图片 90                …{
图片 91                    string s = Revease21(testString);
图片 92                }
图片 93                end = DateTime.Now;
图片 94                Console.WriteLine(“21:  ” + (end – start));
图片 95
图片 96                start = DateTime.Now;
图片 97                for (int i = 0; i < 3000000; i++)
图片 98图片 99                …{
图片 100                    string s = Revease22(testString);
图片 101                }
图片 102                end = DateTime.Now;
图片 103                Console.WriteLine(“22:  ” + (end – start));
图片 104
图片 105                start = DateTime.Now;
图片 106                for (int i = 0; i < 3000000; i++)
图片 107图片 108                …{
图片 109                    string s = Revease3(testString);
图片 110                }
图片 111                end = DateTime.Now;
图片 112                Console.WriteLine(“3 :  ” + (end – start));
图片 113
图片 114                Console.ReadLine();
图片 115            }

当然,你可以预见,这种算法的效率不会比ReverseByCharBuffer要高。

}

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

5. 使用逻辑异或也可以进行反转

 

图片 116            static string Reverse1(string original)
图片 117图片 118            …{
图片 119                char[] arr = original.ToCharArray();
图片 120                Array.Reverse(arr);
图片 121                return new string(arr);
图片 122            }
图片 123
图片 124            static string Revease21(string original)
图片 125图片 126            …{
图片 127                int length = original.Length;
图片 128                char[] arr = new char[length];
图片 129                for (int i = 0; i < (length & (~3)); i += 4)
图片 130图片 131                …{
图片 132                    arr[i] = original[length – i – 1];
图片 133                    arr[i+1] = original[length – i – 2];
图片 134                    arr[i+2] = original[length – i – 3];
图片 135                    arr[i+3] = original[length – i – 4];
图片 136                }
图片 137                for (int i = length & (~3); i < length; i++)
图片 138图片 139                …{
图片 140                    arr[i] = original[length – i – 1];
图片 141                }
图片 142                return new string(arr);
图片 143            }
图片 144
图片 145            static string Revease22(string original)
图片 146图片 147            …{
图片 148                int length = original.Length;
图片 149                char[] arr = new char[length];
图片 150                for (int i = 0; i < length; i++)
图片 151图片 152                …{
图片 153                    arr[i] = original[length – i – 1];
图片 154                }
图片 155                return new string(arr);
图片 156            }
图片 157
图片 158            static string Revease3(string original)
图片 159图片 160            …{
图片 161                int length = original.Length;
图片 162                StringBuilder sb = new StringBuilder(length);
图片 163                for (int i = length-1; i >= 0; i–)
图片 164                sb.Append(original[i]);
图片 165                return sb.ToString();
图片 166            }

4.
栈是一个很神奇的数据结构。我们可以使用它后进先出的特性来对数组进行反转。先将数组所有元素压入栈,然后再取出,顺序很自然地就与原先相反了。

public static string ReverseByStack(this string original)
{
Stack<char> stack = new Stack<char>();
foreach (char ch in original)
{
stack.Push(ch);
}
char[] c = new char[original.Length];
for (int i = 0; i < original.Length; i++)
{
c[i] = stack.Pop();
}
return new string(c);
}

方法三:二分法

图片 167public StringBuilder Append(string value)
图片 168图片 169…{
图片 170      if (value != null)
图片 171图片 172      …{
图片 173            string text1 = this.m_StringValue;
图片 174            IntPtr ptr1 = Thread.InternalGetCurrentThread();
图片 175            if (this.m_currentThread != ptr1)
图片 176图片 177            …{
图片 178                  text1 = string.GetStringForStringBuilder(text1, text1.Capacity);
图片 179            }
图片 180            int num1 = text1.Length;
图片 181            int num2 = num1 + value.Length;
图片 182            if (this.NeedsAllocation(text1, num2))
图片 183图片 184            …{
图片 185                  string text2 = this.GetNewString(text1, num2);
图片 186                  text2.AppendInPlace(value, num1);
图片 187                  this.ReplaceString(ptr1, text2);
图片 188            }
图片 189            else
图片 190图片 191            …{
图片 192                  text1.AppendInPlace(value, num1);
图片 193                  this.ReplaceString(ptr1, text1);
图片 194            }
图片 195      }
图片 196      return this;
图片 197}
图片 198
图片 199private bool NeedsAllocation(string currentString, int requiredLength)
图片 200图片 201…{
图片 202      return (currentString.ArrayLength <= requiredLength);
图片 203
图片 204
图片 205internal unsafe void AppendInPlace(string value, int currentLength)
图片 206图片 207…{
图片 208      int num1 = value.Length;
图片 209      int num2 = currentLength + num1;
图片 210      fixed (char* chRef1 = &this.m_firstChar)
图片 211图片 212      …{
图片 213            fixed (char* chRef2 = &value.m_firstChar)
图片 214图片 215            …{
图片 216                  string.wstrcpy(chRef1 + currentLength, chRef2, num1);
图片 217            }
图片 218            chRef1[num2] = ‘

 

 

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

public static string ReverseByStringBuilder(this string original)
{
StringBuilder sb = new StringBuilder(original.Length);
for (int i = original.Length – 1; i >= 0; i–)
{
sb.Append(original[i]);
}
return sb.ToString();
}

     return new string(reverse);
}

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

public static unsafe string ReverseByPointer(this string original)
{
fixed (char* pText = original)
{
char* pStart = pText;
char* pEnd = pText + original.Length – 1;
for (int i = original.Length / 2; i >= 0; i–)
{
char temp = *pStart;
*pStart++ = *pEnd;
*pEnd– = temp;
}

  return new string(nm);

 

package string;

public class StringTest3 {
   public  static void main(String[] args)
   {
     String s="abcdefg";
       String s2="";
     char[] cs=s.toCharArray();
        for(int i=cs.length-1;i>=0;i--)
        {
         s2=s2+cs[i];
      }
     System.out.println("对字符串进行反转操作后为:"+s2);
       StringBuffer sb=new StringBuffer("abcdefg");
      StringBuffer sb2=sb.reverse();
        System.out.println("对StringBuffer进行反转操作后为:"+sb2);
  }

}

 

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

public static string ReverseByRecursive2(this string original)
{
Func<string, string> f = null;
f = s => s.Length > 0 ? f(s.Substring(1)) + s[0] :
string.Empty;
return f(original);
}

方法一:

Release:

以上这几种方法按算法角度来说,其实可以归结为一类。然而下面的几种算法就完全不是同一类型的了。
使用栈

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图