我想知道如果你能告訴我重複字符串的最有效方法是什麼。我需要創建一個長度爲33554432字節的字符串,重複字符串「hello,world」,直到它填充該緩衝區。什麼是最好的辦法,在這種情況下,C很容易:代碼翻譯:重複一個字符串,直到最大值
for (i = 0; i < BIGSTRINGLEN - step; i += step)
memcpy(bigstring+i, *s, step);
謝謝。
我想知道如果你能告訴我重複字符串的最有效方法是什麼。我需要創建一個長度爲33554432字節的字符串,重複字符串「hello,world」,直到它填充該緩衝區。什麼是最好的辦法,在這種情況下,C很容易:代碼翻譯:重複一個字符串,直到最大值
for (i = 0; i < BIGSTRINGLEN - step; i += step)
memcpy(bigstring+i, *s, step);
謝謝。
的有效方法是使用一個StringBuilder:
string text = "hello, world";
StringBuilder builder = new StringBuilder(BIGSTRINGLEN);
while (builder.Length + text.Length <= BIGSTRINGLEN) {
builder.Append(text);
}
string result = builder.ToString();
我不知道這是否是最有效的方式,但如果你使用.NET 3.5或更高版本,這可能是工作:
String.Join("", System.Linq.Enumerable.Repeat("hello, world", 2796203).ToArray()).Substring(0, 33554432);
如果你想要的長度是動態的,那麼你就可以用簡單的數學替換一些硬編碼的數字。
嗯......我在Mono上,沒有LinQ。相應地更新標籤。謝謝。 – 2010-12-15 18:33:17
沒有Linq?傷心!那麼我會看弗雷德裏克的答案。不管你做什麼,如果使用大字符串,你應該使用字符串連接的StringBuilder。 – 2010-12-15 18:35:08
你知道ToArray() - 調用創建一個包含2796203個字符串的數組,你是否(我知道它是必需的String.Join)。如果沒有這個ToArray(),你的方法將具有與StringBuilder大致相同的性能,因爲String.Join在內部使用StringBuilder,所以枚舉器的開銷很小。 – codymanix 2010-12-15 18:40:51
首先,你希望字符串是33554432個字節長,或字符? .NET和C#使用16位字符,因此它們不相同。
如果你想要33554432個字符,天真的解決方案將是字符串連接。見Frédéric Hamidi的答案。
如果你想要個字節,你需要做一些更有趣:
int targetLength = 33554432;
string filler = "hello, world";
byte[] target = new byte[targetLength];
// Convert filler to bytes. Can use other encodings here.
// I am using ASCII to match C++ output.
byte[] fillerBytes = Encoding.ASCII.GetBytes(filler);
//byte[] fillerBytes = Encoding.Unicode.GetBytes(filler);
//byte[] fillerBytes = Encoding.UTF8.GetBytes(filler);
int position = 0;
while((position + fillerBytes.Length) < target.Length)
{
fillerBytes.CopyTo(target, position);
position += fillerBytes.Length;
}
// At this point, need to possibly do a partial copy.
if (position < target.Length)
{
int bytesNecessary = target.Length - position;
Array.Copy(fillerBytes, 0, target, position, bytesNecessary);
}
這個是什麼?將StringBuilder設置爲最大預期大小,然後添加所需的字符串,只要添加另一個字符串不會超過所需的最大大小。
StringBuilder sb = new StringBuilder(33554432);
int max = sb.MaxCapacity;
String hello = "hello, world";
while (sb.Length + hello.Length <= max)
{
sb.Append(hello);
}
string longString = sb.ToString();
這可避免重複添加字符串的循環。相反,我將字符串「加倍」,直到接近正確的長度,然後適當地將「加倍」部分放在一起。
static string Repeat(string s, int length) {
if (length < s.Length) {
return s.Substring(0, length);
}
var list = new List<string>();
StringBuilder t = new StringBuilder(s);
do {
string temp = t.ToString();
list.Add(temp);
t.Append(temp);
} while(t.Length < length);
int index = list.Count - 1;
StringBuilder sb = new StringBuilder(length);
while (sb.Length < length) {
while (list[index].Length > length) {
index--;
}
if (list[index].Length <= length - sb.Length) {
sb.Append(list[index]);
}
else {
sb.Append(list[index].Substring(0, length - sb.Length));
}
}
return sb.ToString();
}
因此,例如,在輸入(「你好,世界!」,64),我們所建立的字符串
13: Hello, World!
26: Hello, World!Hello, World!
52: Hello, World!Hello, World!Hello, World!Hello, World!
然後,我們將通過長度52的字符串串聯到構建結果長度爲12的字符串的長度爲12的子串。
我當然假設按字節表示長度。否則,您可以使用編碼輕鬆修改上述內容,以便按字節獲取所需內容。
給我:使用時間(float):315.9855毫秒,stringbuilder仍然是最好的...雖然我明白你的觀點。 – 2010-12-15 18:51:31
對一個輸入的一個測試會告訴你什麼。 – jason 2010-12-15 18:52:18
除非你的宇宙只是這個字符串,並且數字加倍,在這種情況下它會告訴你所有你想知道的東西! – 2010-12-15 18:54:20
你認爲1個字符== 1個字節嗎?因爲對於純ASCII編碼是正確的,但對於其他編碼,它可能是錯誤的... – digEmAll 2010-12-15 18:38:28