自己写代码实现String.Trim()方法(上)
在ASP.net中老是用到StringText.Trim(),因此让我对Trim()是如何实现产生了兴趣,我决定要自己写一个方法实现这个功能。由于本人是初学者可以写的不好规范,请大家多多指点。
首先在写Trim()前,我先分析一下这个方法的功能:(官方解释:从当前System.String对象中移除所有前导空白字符和尾部空白字符)也就是说在我们前面的StringText的字符串中删除前后的空白字符,举一个列子(string StringText=" abc ";StringText = StringText.Trim();//删除了StringText字符串" abc "中前面的空白字符与后面的空白字符,因此当前StringText="abc"),当然不只是删除abc前后的一个空白字符,也可以是多个空白字符。(如string StringText = " abc ";StringText = StringText.Trim();//当前StringText依然等于"abc")
根据上面的分析,我们可以发现Trim()做了两件事,一件事是删除了字符串中的前导空白字符,另一件事是删除了字符串中的尾部空白字符串。所以我们可以把Trim()方法分成TrimStart()方法与TrimEnd()方法,当然微软也是这样做的我们可以找字符串中找到TrimStart()与TrimEnd()这两个方法。
下面我们就对TrimStart()方法的具体实现做一下分析:TrimStart()微软是提供了我们要传一个可变字符数组(params char[] CharArray),所以我们先不考虑传入的字符数组是什么一律默认为空白字符处理。具体微软提供的TrimStart()方法,我们知道StringText调用这个方法后会返回一个处理完成的字符串,所以我们MyTrimStart()方法有一个返回值为string,同时我们知道这个返回值的前导中已经没有一个空白字符(如字符串" abc",返回为" abc" ; 字符串" a b c ",返回为" a b c ")。
这里是MyTrimStart方法具体的实现:
static string MyTrimStart(string StringText) { //无限循环删除StringText前的多个空格 while (true) { //记录从前面遍历到的位置 int index = StringText.IndexOf(' '); //如果找到index=0就说明空格在字符串的最前面, //就删除该字符串最前面的位子 if (index == 0&&index!=-1) { //如果成立就删除StringText中第一个空格 StringText = StringText.Substring(1); } else { //不成立 结束循环 break; } } return StringText; }
当然同理我们可以得出MyTrimEnd方法:
static string MyTrimEnd (string StringText) { //无限循环删除StringText前的多个空格 while (true) { //记录从后开始遍历到的位置 int index = StringText. LastIndexOf (' '); //如果找到index= StringText.Length - 1就说明空格在字符串的最后面, //就删除该字符串最后面的位子 if (index == StringText.Length - 1&&index!=-1) { //如果成立就删除StringText中第一个空格 StringText = StringText. Remove (index); } else { //不成立 结束循环 break; } } return StringText; }
我们将MyTrimStart()方法与MyTrimEnd()方法合起来就变成了MyTrim()方法了。
static string MyTrim(string StringText,) { //调用字符串前删除字符的方法 StringText = MyTrimStart(StringText); //调用字符串后删除字符的方法 StringText = MyTrimEnd(StringText); return StringText; }
我们已经完成了初步的MyTrim()方法,下面来优化上面的MyTrim()方法。首先我们MyTrimStart()方法,开始是一个while(true)的循环,if-else中值用到多次if,而else只用到了一次就是最后一次。
所以优化为:
static string MyTrimStart1(string StringText) { //记录从前面遍历到的位置 int index = StringText.IndexOf(' '); //如果找到index=0就说明空格在字符串的最前面, //就删除该字符串最前面的位子 while (index == 0&&index!=-1) { //如果成立就删除StringText中第一个空格 StringText = StringText.Substring(1); //继续记录从前面遍历到的位置 index = StringText.IndexOf(' '); } return StringText; }
通过比较计算同一个字符串(" a b c ")的处理得出运算时间我们可以看到:(这里插入一个计算运算时间Stopwatch类,使用这个类在一定程度上可以了解自己程序的运行时间)
原方法的时间为:0.0002348秒,优化后的时间为:0.0001258秒,速度将近快了一倍。
看到这个我们发现其实上面的方法还是可以优化的:
static string MyTrimStart2(string StringText) { //从前面记录遍历到的位置 int index = StringText.IndexOf(' '); if (index == 0&&index!=-1) { //如果成立删除 StringText = StringText.Substring(1); //递归上面的方法 StringText = MyTrimStart2(StringText); } return StringText; }
这里我们将while循环去掉,加入一个递归。如果这个方法不懂我建议单步运行一遍看运行的过程。为什么要这样做,我也不知道,只可以说是感觉吧。
跟上面一样再比较计算同一个字符串(" a b c ")的处理得出运算时间我们可以看到:
用上递归以后我们的速度又提高了一点,原因在与我们的使用过一遍的方法是记录在栈中的,用递归调用栈中的方法,而不用while方法体可以更好的提高我们的运算时间。为了证明我所说的我们在字符串(" a b c ")前再加10个空白字符成为(" a b c "),然后再计算:
我们可以发现MyTrimStart1与MyTrimStart2的差距就出来了,明显用了递归以后我们使用的效率提高了。
同理可得我们的MyTrimEnd()方法:
static string MyTrimEnd2(string StringText) { //从后面记录遍历到的位置 int index = StringText.LastIndexOf(' '); if (index == StringText.Length-1&&index!=-1) { //如果成立删除 StringText = StringText.Remove(index); //递归上面的方法 StringText = MyTrimEnd2(StringText); } return StringText; }
通过综合以上代码MyTrim()方法的运算时间如下:
这个方法还没有完成下次继续。
以上为本人自己的了解,如有什么不正确欢迎大家指出来了,大家一起来讨论。