|
蓝森林 http://www.lslnet.com 2006年6月6日 10:18
【转】超强版 Trim 横空出世!
昨天给一个同事讲 trim,一时豪情大发,一不小心编出了这段代码,后来仔细看看,确实是堪称精品,不过又怕有什么遗漏的地方,所以赶紧发到这里让大家帮我参详参详。
[code]void trim( char *str )
{
char *copied, *tail = NULL;
if ( str == NULL )
return;
for( copied = str; *str; str++ )
{
if ( *str != ' ' && *str != '\t' )
{
*copied++ = *str;
tail = copied;
}
else
{
if ( tail )
*copied++ = *str;
}
}
if ( tail )
*tail = 0;
else
*copied = 0;
return;
}[/code] |
【转】超强版 Trim 横空出世!
if ( str == NULL )
return NULL;
原型是返回void哦。 |
【转】超强版 Trim 横空出世!
-->
哦,粗心了,改过。 |
【转】超强版 Trim 横空出世!
还有else
*copied = 0;
是否也可以去掉。
因为你for循环结束时的条件就是*copied == 0
还有应该是*str != 32 && *str != 9吧? |
【转】超强版 Trim 横空出世!
-->
[color=red]真的是太不好意思了。[/color]
今天没有带电脑,刚才的这段代码是默写出来的,所以有很多错误。
刚才又改了一下,循环的条件改正确了。
另:TAB 的键值我可能的确是记错了。
但是程序中不建议直接写 ASCII 码,我是因为怕空格看不清楚才这么写的,现在改回去了。 |
【转】超强版 Trim 横空出世!
从那说起这个是超强的trim阿,它能去掉中间的空格,前面的空格,后面的空格,是全部还是部分阿。
还有,str!等于8或9有什么区别么?我看只要不等于32就算满足要求了! |
【转】超强版 Trim 横空出世!
-->
它能去掉前面的和后面的空格,中间的不会去掉。网络通讯中经常用到。
9 是 TAB,TAB 一般和空格做同样的解释。所以也要去掉。
之所以说“超强”是因为只用了一个循环两个变量,估计也不能更简洁了。 |
【转】超强版 Trim 横空出世!
-->
它是去掉字符串两端的空格。
ascii码是TAB键。
这个算法已经很不错了。
要不你也写一个出来。 |
【转】超强版 Trim 横空出世!
斑竹的确很负责,码了很多字出来。这段代码也非常好。
W25兄表老激动哦。 |
【转】超强版 Trim 横空出世!
不错!
但我觉得应该把所有控制符都去掉,举个例子:BS也应该处理吧?而且处理起来还很复杂。STX,ACK等等有意义吗?
我都是判<=空格的,又干净效率还高。 |
【转】超强版 Trim 横空出世!
-->
呵呵,这个就不好说了,比如我们公司的接口中,都用 \1 来当做字段的分隔符,所以是不能去掉的。
通常情况下,<32 的字符由于大多是不可见字符,实际应用中用不着,所以恰恰被很多接口采用为转义字符、分隔符、类型符、控制符等等,所以绝对是不可以去掉的。
再说了,要是想去掉,改一下我这个代码就可以了。
反正又不影响算法的效率:“时间复杂度”和“空间复杂度”,
所以我不会在意的。
我在意的是:我的这个算法有没有漏洞?有没有人能写出比我这个更好的算法? |
【转】超强版 Trim 横空出世!
不错不错,用了两个指针记录位置,tail只有在不是空格的情况下才写入,这样在tail不为空的时候就记录下了最后的空格出现的位置。 |
【转】超强版 Trim 横空出世!
不错,我觉得从算法而言,确实没有简化的余地了。 |
【转】超强版 Trim 横空出世!
算法不错!
但对用STX来做分隔符不赞同,控制码里也有专门的符号的,FS就是嘛!
这个算法在尾部空格较多时有损失。
我再给你简化一下,主要是从效率角度考虑:
[code]
void trim( char *str )
{
char *copied;
char *tail;
char c;
if ( str == NULL )
return;
for ( copied = str, tail = NULL; ( c = *str ) != 0; str ++ )
{
if ( c != ' ' && c != '\t' )
{
*copied ++ = c;
tail = copied;
}
else
{
if ( tail != NULL )
*copied ++ = c;
}
}
if ( tail != NULL )
*tail = 0;
else
*str = 0;
}
[/code] |
【转】超强版 Trim 横空出世!
不好意思刚才出去吃饭了,刚回来,我根本没激动,只不过我觉得tail的指针处理上有问题,手里没有编译器,这段代码考一下,回去调试调试。 |
【转】超强版 Trim 横空出世!
现在想找楼主研究一下,遗憾!晚了!!!555 |
【转】超强版 Trim 横空出世!
flw老兄的代码写得非常好,我是绝对写不出来的,在这个问题上,我只发表过一次代码,而且效率不高,剩下的帖子,倒像个批评家。
不过,这次我还是想做一次批评家,请大家不要介意。
1。如果该字符串前部没有空格(或空格串),只有尾部有,那么,if ( tail )这个条件判断就要进行O(n)次,这完全可以用分情况的办法解决,当然,大家会说,如果分情况的话,源代码就不会这么简洁了,那么*copied++ = *str出现过两次,也不简洁,但是效率比提到条件语句外稍高一点。
2。在《如何又简洁又安全地去掉字符串前面和后面的空符号?》中,大家降低时间复杂性的方法是在到达字符串结尾后又折回来。flw兄的是利用了tail变量来记住应该赋'\0'值的位置,但是这样一来,每次都要进行tail = copied; 赋值操作或者是if ( tail )比较+转跳操作,时间复杂性一下子加了一倍,在具有超流水线的机器中效率将会更低。
3。用strlen()或者memmove()的算法实际执行效率可能最高
大家可以试试用for循环来实现strlen()和memmove(),看看运行效率比它们低多少,稍微用心一点的strlen()等函数的实现都会用串处理指令,其运行效率,比用for循环高多了,但是高多少又无法像美国1787年宪法规定的“黑人人口按实际的四分之三折算”那样加以量化,因此是“可能”最高。
请大家多对我的看法提宝贵意见。 |
【转】超强版 Trim 横空出世!
tail 用的精妙 |
【转】超强版 Trim 横空出世!
| 【转】超强版 Trim 横空出世!
| |
|