перевод кода: повторение строки до некоторого максимума - PullRequest
1 голос
/ 15 декабря 2010

Мне было интересно, не могли бы вы сказать, какой самый эффективный способ повторить строку? Мне нужно создать строку длиной 33554432 байта, повторяющую строку «привет, мир», пока она не заполнит этот буфер. Каков наилучший способ сделать это, C легко в этом случае:

for (i = 0; i < BIGSTRINGLEN - step; i += step)
        memcpy(bigstring+i, *s, step);

Спасибо.

Ответы [ 5 ]

3 голосов
/ 15 декабря 2010

Эффективным способом было бы использование StringBuilder :

string text = "hello, world";
StringBuilder builder = new StringBuilder(BIGSTRINGLEN);
while (builder.Length + text.Length <= BIGSTRINGLEN) {
    builder.Append(text);
}
string result = builder.ToString();
2 голосов
/ 15 декабря 2010

Во-первых, хотите ли вы, чтобы длина строки составляла 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);
}
1 голос
/ 15 декабря 2010

Я не знаю, является ли это наиболее эффективным способом, но если вы используете .NET 3.5 или более позднюю версию, это может сработать:

String.Join("", System.Linq.Enumerable.Repeat("hello, world", 2796203).ToArray()).Substring(0, 33554432);

Если требуемая длина является динамической, тогдаможет заменить некоторые из жестко закодированных чисел простой математикой.

0 голосов
/ 15 декабря 2010

Это позволяет избежать цикла, который многократно добавляет строку.Вместо этого я «удваиваю» строку до тех пор, пока она не приблизится к нужной длине, а затем соответствующим образом соединю «сдвоенные» кусочки.

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 строки длины 13.

IЯ, конечно, предполагаю, что под байтами вы подразумевали длину.В противном случае вы можете легко изменить вышеперечисленное, используя кодировки, чтобы получить то, что вы хотите в виде байтов.

0 голосов
/ 15 декабря 2010

А как насчет этого?Установите для 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...