1

我有一串十六进制数字,比如说

"010104000202000AC80627061202"

我希望我的输出为

"01 01 04 00 02 02 00 0A C8 06 27 06 12 02"

我可以使用 for 循环,但有什么优化的方法吗?

我目前正在做的是:

int length = line.Length/2; // Store the length of String
string outputstr = String.Empty;
for (int count = 0; count < length; count++)
  {
       outputstr += line.Substring(0, 2) + " "; //Get First two bytes and add space
       line = line.Substring(2); // Remove those two bytes
 }
4

7 回答 7

4

您可以使用此正则表达式:

string outputstr = Regex.Replace(inputstr, ".{2}", "$0 ");
于 2013-10-31T12:54:13.883 回答
2

这看起来很简单但也很实用。

private static string DoThat(string input)
{
    var sb = new StringBuilder(input.Length);
    for (int i = 0; i < input.Length; i += 2)
    {
        sb.Append(input, i, 2);
        sb.Append(" ");
    }
    return sb.ToString();
}
于 2013-10-31T13:08:28.887 回答
1

因为你的输出字符串的长度是预先知道的,所以最快的方法是分配char[]最终大小的 a ,填充它,然后return new string(myCharBuffer);. 这也快了,总是被夸奖的StringBuilder。只需要两个分配,两个都具有完美的大小,第二个由memcpy.

于 2013-10-31T12:53:47.493 回答
1

如果您想要更快,您可以更改为 stringbuilder:

int length = line.Length; // Store the length of String -- see edit below
StringBuilder output = new StringBuilder();
for (int count = 0; count < length; count += 2)  // makes more sense to increment the loop by 2
{
    output.Append(line.Substring(count, 2) + " "); //Get First two bytes and add space
}

使用 Linq 的一种方法是

string.Join(" ",                      // join the string collection created below
    line.Select((c,i) => new {c,i})   // get each character and its index
        .GroupBy(g => g.i/2)          // group in pairs
        .Select(g => new string(g.Select(ci => ci.c).ToArray()))  // convert to char arrays and merge into strings
     );

或者

string.Join(" ",
Enumerable
    .Range(0, s.Length/2)
    .Select(i => s.Substring(i*2, 2))
 )

尽管这本质上是Substring在“循环”中调用,但它可能不是最有效的方法。

于 2013-10-31T12:53:59.040 回答
1

首先,如果您要循环并使用字符串操作,请使用 Stringbuilder。

这是因为 String 是不可变的,虽然看起来好像在更改它,但实际上每次迭代都会创建一个新对象并保存在堆栈中。

于 2013-10-31T12:54:41.463 回答
1

StringBuilder如果字符串很大,您可以使用 a :

if(line.Length > 100)
{
    StringBuilder sb = new StringBuilder(line.Length + line.Length/2);
    for(int i=0; i < line.Length; i++)
    {
        sb.Append(line[i]);
        if (i % 2 == 1 && i < line.Length-1)
            sb.Append(' ');
    }
    return sb.ToString();
}
// else your approach
于 2013-10-31T12:56:17.737 回答
0

你可以这样:

var unformatedString = "010104000202000AC80627061202";
var formatedString = Regex.Replace(@"..", "$0 ");

这绝对不是更快,但更容易阅读。

于 2013-10-31T12:55:55.500 回答