宝哥软件园

删除10中空白字符串的方法 网

编辑:宝哥软件园 来源:互联网 时间:2021-09-08

我们有无数种方法可以删除一个字符串中的所有空格,但是哪个更快呢?

介绍

如果问空白是什么,有点乱。很多人认为白色SPACE是空格字符(UnicodeU 0020,ASCII 32,HTML),但实际上它包括了布局中所有使白色空格横向和纵向出现的字符。事实上,这是定义为Unicode字符数据库的一整类字符。

文中提到的空白不仅指其正确定义,还包括字符串。替换(“”、“”)方法。

在这里的基准方法中,头部、尾部和中间的所有空白都会被删除。这就是文章标题中“全部空白”的意思。

背景

这篇文章是出于我的好奇心。事实上,我不需要最快的算法来删除字符串中的空白。

检查空白字符

检查空白字符很容易。您需要的所有代码是:

char wp=char a=' a断言。True(char。ishitespace(WP));断言。False(char。ishitespace(a));然而,当我实现手动优化删除方法时,我意识到它并没有预期的那么好。部分源代码可在微软参考源代码库的char.cs挖掘中找到:public static bool为空格(char c){ if(islatin 1(c)){ return(ishitespace 1(c));}返回CharUnicodeInfo。ishitespace(c);}然后是CharUnicodeInfo。IsWhiteSpace变成:内部静态bool是空格(char c){ unicode category UC=getunicodecategory(c);//在Unicode 3.0中,U 2028是唯一属于“行分隔符”类别的字符。//而U 2029是属于“段落分隔符”类别的最后一个字符。switch(UC){ case(unicode category。SpaceSeparator) :案例(UnicodeCategory。LineSeparator):大小写(UnicodeCategory。ParagraphSeparator):返回(true);} return(false);} GetUnicodeCategory()方法调用InternalGetUnicodeCategory()方法,其实挺快的,但是现在我们依次有4个方法调用!以下代码由评论员提供,可用于快速实现定制版本和JIT默认内联:

//空白检测方法:非常快,比Char快很多。ishitespace[method mpl(method mploptions。侵略性内嵌)】//如果它没有内嵌,那么它会很慢!公共静态bool ishitespace(char ch){//这比等效的if语句switch(ch){ case ' u 0009 ' : case ' u 000 a ' : case ' u 000b ' : case ' u 000c ' : case ' u 000d ' : case ' u 0020 ' 3: case ' u 0085 ' 3: case ' udefault:返回false}}删除字符串的不同方法

我用各种方法删除字符串中的所有空格。

分离结合法

这是我一直使用的一个非常简单的方法。根据空格字符分隔字符串,不包括空项,然后将结果片段再次合并在一起。这种方法听起来有点傻,但事实上,乍一看,这似乎是一个非常浪费的解决方案:

公共静态字符串TrimAllWithSplitAndJoin(字符串字符串){返回字符串。Concat(str。Split(默认值(字符串[]),StringSplitOptions。RemoveEmptyEntries));} LINQ这是实现这个过程的优雅且声明性的方式:公共静态字符串trimallwithlink(string str){ return new string(str。其中(c=!ishitespace(c))。ToArray());}正则表达式

正则表达式是一种非常强大的力量,任何程序员都应该意识到这一点。

静态正则表达式空白=新正则表达式(@'s ',正则表达式选项.已编译);公共静态字符串TrimAllWithRegex(字符串字符串){返回空白。替换(字符串' ');} 字符数组原地转换法

该方法将输入的字符串转换成字符数组,然后原地扫描字符串去除空白字符(不创建中间缓冲区或字符串)。最后,经过"删减"的数组会产生新的字符串。

公共静态字符串TrimAllWithInplaceCharArray(字符串字符串字符串){ var len=str .长度;var src=str .ToCharArray();int DstIDx=0;for(int I=0;我透镜;I){ var ch=src[I];if(!ishitespace(ch))src[DsIDx]=ch;}返回新字符串(src,0,DsIDx);} 字符数组复制法

这种方法类似于字符数组原地转换法,但它使用数组。复制复制连续非空白"字符串"的同时跳过空格。最后,它将创建一个适当尺寸的字符数组,并用相同的方式返回一个新的字符串。

公共静态字符串TrimAllWithCharArrayCopy(字符串字符串字符串){ var len=str .长度;var src=str .ToCharArray();int srcIdx=0,dstIdx=0,count=0;for(int I=0;我透镜;I){ if(ishitespace(src[I]){ count=I-srcIdx;数组。副本(src、srcIdx、src、dstIdx ),计数);srcIdx=计数1;dstIdx=计数;len-;} } if(DsIDx len)数组。副本(src、srcIdx、src、dstIdx、len-DsT idx);返回新字符串(src,0,len);}循环交换法

用代码实现循环,并使用StringBuilder类,通过依靠StringBuilder的内在优化来创建新的字符串。为了避免任何其他因素对本实施产生干扰,不调用其他的方法,并且通过缓存到本地变量避免访问类成员。最后通过设置StringBuilder .长度将缓冲区调整到合适大小。

//http://www . code project.com/Members/ThEsketCaseSoftware建议的代码

公共静态字符串TrimAllWithLexerLoop(字符串){ int length=s . Lengthvar缓冲区=new StringBuildervar dstIdx=0;for(int index=0;索引长度;index){ char ch=s[index];switch(ch){ case ' u 0020 ' : case ' u 00a 0 ' : case ' u 1680 ' : case ' u 2000 ' : case ' u 2001 ' : case ' u 2002 ' : case ' u 2003 ' : case ' u 2004 ' 3: case ' u 2005 '继续;default: break}缓冲区[DSidx]=ch;}缓冲区。长度=长度;返回缓冲区. ToString();}循环字符法

这种方法几乎和前面的循环交换法相同,不过它采用如果语句来调用isWhiteSpace(),而不是乱七八糟的转换伎俩:)。

公共静态字符串trimalwith lexeroopcharishitespece(个字符串){ int length=s . Lengthvar缓冲区=new StringBuildervar dstIdx=0;for(int index=0;索引长度;index){ char current char=s[index];if(ishitespace(当前字符))长度-;else buffer[DsIDx]=当前char}缓冲区。长度=长度;返回缓冲区. ToString();}

原地改变字符串法(不安全)

这种方法使用不安全的字符指针和指针运算来原地改变字符串。我不推荐这个方法,因为它打破了。网框架在生产中的基本约定:字符串是不可变的。

公共静态不安全字符串trimallteringinplace(字符串str){ fixed(char * pfixed=str){ char * dst=pfixed;for(char * p=pfixed;*p!=0;p ) if(!ishitespace(* p))* dst=* p;/*//重置字符串大小*只有它不起作用!使用后发生了垃圾收集访问冲突*所以我不得不返回一个新的字符串,只有相关的字节*如果它真的起作用的话会快很多.int 32 len=(int 32)(dst-pfixed);int 32 * pi=(int 32 *)pfixed;pi[-1]=len;pfixed[len]=' 0 ';*/返回新字符串(pfixed,0,(int)(dst-pfixed));}}原地改变字符串法V2(不安全)

这种方法几乎和前面那个相同,不过此处使用类似数组的指针访问。我很好奇,不知道这两种哪种存储访问会更快。

公共静态不安全字符串trimallteringinplacev2(字符串字符串字符串){ var len=str .长度;fixed(char * PStr=str){ int dstIdx=0;for(int I=0;我透镜;(一)如果(!ishitespace(PStr[I])(PStr[DSidx]=PStr[I];//由于不安全字符串长度重置不起作用,我们需要求助于这种较慢的折衷返回新字符串(pStr,0,DsIDx);} }字符串。替换(","")这种实现方法很天真,由于它只替换空格字符,所以它不使用空白的正确定义,因此会遗漏很多其他的空格字符。虽然它应该算是本文中最快的方法,但功能不及其他。

但如果你只需要去掉真正的空格字符,那就很难用纯。网写出胜过字符串。替换的代码。大多数字符串方法将回退到手动优化本地C代码。而字符串。替换本身将用comstring.cpp调用C方法:

FCIMPL3(对象*,comstring :替换字符串,StringObject * thisRefUNSAFE,StringObject* oldValueUNSAFE,StringObject* newValueUNSAFE)下面是基准测试套件方法:

公共静态字符串TrimAllWithStringReplace(字符串){ //该方法在功能上与其他方法不等同,因为它只会修剪"空格"//空白包含许多其他返回字符串的字符。替换(""、"");}

以上就是。网中删除空白字符串的10大方法,希望对大家的学习有所帮助。

更多资讯
游戏推荐
更多+