Лучший способ повторить символ в C #

Какой это лучший способ для генерации строки \tв C #

Я изучаю C # и экспериментирую с разными способами сказать одно и то же.

Tabs(uint t)это функция , которая возвращает stringс tколичеством \t«с

Например Tabs(3)возвращает"\t\t\t"

Какой из этих трех способов реализации Tabs(uint numTabs)лучше?

Конечно, это зависит от того, что означает «лучший».

  1. Версия LINQ состоит всего из двух строк, что приятно. Но требуют ли повторные и агрегирующие вызовы ненужные затраты времени и ресурсов?

  2. StringBuilderВерсия очень ясно , но это StringBuilderкласс как - то медленнее?

  3. stringВерсия является основной, что означает , что это легко понять.

  4. Это не имеет значения вообще? Они все равны?

Все эти вопросы помогут мне лучше понять C #.

private string Tabs(uint numTabs)
{
    IEnumerable<string> tabs = Enumerable.Repeat("\t", (int) numTabs);
    return (numTabs > 0) ? tabs.Aggregate((sum, next) => sum + next) : ""; 
}  

private string Tabs(uint numTabs)
{
    StringBuilder sb = new StringBuilder();
    for (uint i = 0; i < numTabs; i++)
        sb.Append("\t");

    return sb.ToString();
}  

private string Tabs(uint numTabs)
{
    string output = "";
    for (uint i = 0; i < numTabs; i++)
    {
        output += '\t';
    }
    return output; 
}
4.01.2009 21:56:59
19 ОТВЕТОВ
РЕШЕНИЕ

Что насчет этого:

string tabs = new String('\t', n);

Где nсколько раз вы хотите повторить строку.

Или лучше:

static string Tabs(int n)
{
    return new String('\t', n);
}
1469
13.04.2016 08:36:17
есть ли способ повторить это на слово? вместо '\ t', как использовать "время"
asdfkjasdfjk 3.04.2013 12:41:03
@ user1478137 Или лучше (еще дальше): это
Xynariz 8.04.2014 19:51:38

Лучшая версия, безусловно, использовать встроенный способ:

string Tabs(int len) { return new string('\t', len); }

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

Если вы используете a StringBuilderи заранее знаете его результирующую длину, а затем также используете соответствующий конструктор, это гораздо более эффективно, потому что это означает, что происходит только одно трудоемкое выделение, и нет ненужного копирования данных. Чепуха: конечно, приведенный выше код более эффективен.

63
23.08.2011 17:31:32
sb.Append ('\ t', len);
dan-gph 3.06.2010 02:27:25
Мои тесты показывают, new string('\t', len)что они в 2-7 раз быстрее, чем StringBuilderподход. Почему вы считаете StringBuilderболее эффективным в этом случае?
StriplingWarrior 23.08.2011 16:32:31
@StriplingWarrior Спасибо за исправление этого (после того, как он простоял здесь два года, не меньше!).
Konrad Rudolph 23.08.2011 17:30:29

Как насчет использования метода расширения?


public static class StringExtensions
{
   public static string Repeat(this char chatToRepeat, int repeat) {

       return new string(chatToRepeat,repeat);
   }
   public  static string Repeat(this string stringToRepeat,int repeat)
   {
       var builder = new StringBuilder(repeat*stringToRepeat.Length);
       for (int i = 0; i < repeat; i++) {
           builder.Append(stringToRepeat);
       }
       return builder.ToString();
   }
}

Вы могли бы тогда написать:

Debug.WriteLine('-'.Repeat(100)); // For Chars  
Debug.WriteLine("Hello".Repeat(100)); // For Strings

Обратите внимание, что тест производительности при использовании версии stringbuilder для простых символов вместо строк дает основную штрафную степень при выполнении: на моем компьютере разница в измеренной производительности составляет 1:20 между: Debug.WriteLine ('-'. Repeat (1000000)) // char версия и
Debug.WriteLine ("-". Repeat (1000000)) // строковая версия

40
20.06.2011 14:24:53
Производительность строковой версии может быть улучшена с помощью StringBuilder.Insert(Int32, String, Int32), как ответил Binoj Anthony .
Palec 9.04.2016 15:00:07

Во всех версиях .NET вы можете повторить строку следующим образом:

public static string Repeat(string value, int count)
{
    return new StringBuilder(value.Length * count).Insert(0, value, count).ToString();
}

Повторить характер, new String('\t', count)это ваша лучшая ставка. Смотрите ответ по @CMS .

122
23.05.2017 12:03:03
На сегодняшний день это самая быстрая производительность для String. Другие методы создают слишком много накладных расходов.
midspace 11.05.2015 00:22:48
@midspace Знаете ли вы, если кто-нибудь объяснил, почему другие ответы хуже? Я бы предположил, что нативный String.Concat будет внутренне оптимизирован так же, как и StringBuilder
Marie 25.03.2019 14:24:02
@Marie Следующая статья объясняет некоторые достоинства. support.microsoft.com/en-au/help/306822/… В противном случае два других фактора: StringBuilder допускает строки и не ограничивается только символом (хотя это не относится к исходному вопросу) и строкой. Ответ Concat выше должен сначала создать массив с помощью Enumerable.Repeat. Как я уже сказал, это ненужные накладные расходы.
midspace 26.03.2019 22:35:21
Я предполагал, что сначала он не создаст массив, потому что он может просто перебирать элемент за элементом. Спасибо за ссылку, я прочитаю!
Marie 27.03.2019 14:14:02

Ответ действительно зависит от сложности, которую вы хотите. Например, я хочу обвести все мои отступы вертикальной чертой, поэтому моя строка отступа определяется следующим образом:

return new string(Enumerable.Range(0, indentSize*indent).Select(
  n => n%4 == 0 ? '|' : ' ').ToArray());
4
6.04.2009 10:58:42

Методы расширения:

public static string Repeat(this string s, int n)
{
    return new String(Enumerable.Range(0, n).SelectMany(x => s).ToArray());
}

public static string Repeat(this char c, int n)
{
    return new String(c, n);
}
51
7.02.2014 10:35:58
Когда-то люди использовали петли
prabhakaran 26.09.2013 11:31:58
@prabhakaran Я согласен, но преимущество Линка в общении; почти всегда тривиально переопределить выражение Linq, используя императивные конструкции.
Rodrick Chapman 7.10.2013 04:14:16
Enumerable.Range(0, n).SelectMany(x => s)можно заменить на простой Enumerable.Repeat(s, n).
Palec 9.04.2016 15:10:27
@Palec Нет, не может. В SelectManyзавещании для каждого отдельного манекена xдается последовательность charзначений (поскольку они string sреализованы IEnumerable<char>), и все эти charпоследовательности объединяются в одну длинную charпоследовательность. То, что вы предлагаете, вместо этого даст IEnumerable<string>. Это не то же самое.
Jeppe Stig Nielsen 20.12.2017 22:37:18
Я был неправ, @JeppeStigNielsen. Спасибо за хедз-ап. Если бы я действительно хотел бы использовать Enumerable.Repeat, я бы конкатенацию строк вместе: string.Concat(Enumerable.Repeat(s, n)). Это уже было опубликовано ранее .
Palec 24.12.2017 12:09:52

Ваш первый пример, который использует Enumerable.Repeat:

private string Tabs(uint numTabs)
{
    IEnumerable<string> tabs = Enumerable.Repeat(
                                 "\t", (int) numTabs);
    return (numTabs > 0) ? 
            tabs.Aggregate((sum, next) => sum + next) : ""; 
} 

можно переписать более компактно String.Concat:

private string Tabs(uint numTabs)
{       
    return String.Concat(Enumerable.Repeat("\t", (int) numTabs));
}
17
5.01.2016 14:22:52

Как насчет этого:

//Repeats a character specified number of times
public static string Repeat(char character,int numberOfIterations)
{
    return "".PadLeft(numberOfIterations, character);
}

//Call the Repeat method
Console.WriteLine(Repeat('\t',40));
23
7.02.2014 10:35:45
хаха .. вот о чем я мог подумать, когда однажды попал в такую ​​ситуацию. Но лично я нашел new string('\t', 10)лучшее решение
shashwat 18.11.2013 11:27:09
Этот прием также используется в Essential C # 6.0 .
Only The Paranoid Survive 25.01.2017 10:16:40
string.Concat(Enumerable.Repeat("ab", 2));

Возвращает

"ABAB"

А также

string.Concat(Enumerable.Repeat("a", 2));

Возвращает

«Аа»

от...

Есть ли встроенная функция для повторения строки или символа в .net?

153
23.05.2017 12:26:25
Сделайте это лучше, сделав это без Linq и с StruingBuilder!
Bitterblue 15.04.2014 15:29:17
'' StringBuilder '' не обязательно быстрее stackoverflow.com/questions/585860/…
Schiavini 9.12.2014 16:13:44
Это может быть не быстрее, но это может сэкономить на распределении памяти (нагрузке), если вы укажете правильную емкость заранее, и это может быть столь же важно, как и микропроцессор для профилирования.
wekempf 5.04.2016 13:03:26
var strRepeat = string.Concat (Enumerable.Repeat ("ABC", 1000000)); // 50ms
yongfa365 7.12.2018 02:31:06
@Pharap string.Joinбыл быстрее в этом примере, потому что они использовали пробел. string.Concatуместно, когда нет разделителя.
Carter Medlin 18.06.2019 15:21:24

Использование String.Concatи Enumerable.Repeatкоторое будет дешевле, чем использованиеString.Join

public static Repeat(this String pattern, int count)
{
    return String.Concat(Enumerable.Repeat(pattern, count));
}
14
23.04.2013 07:09:24

Допустим, вы хотите повторить '\ t' n раз, которые вы можете использовать;

String.Empty.PadRight(n,'\t')
19
28.08.2013 10:45:21
Спасибо. Это тоже очень быстро. codereview.stackexchange.com/questions/36391/…
Sunsetquest 8.04.2016 22:03:13
Я всегда так делал. Даже если он включен в метод расширения, он проще, чем другие реализации, размещенные здесь. Обратите внимание, что OP просто хотел повторить \ t, а не строки.
Michael Ribbons 29.04.2016 02:18:59
var str = new string(Enumerable.Repeat('\t', numTabs).ToArray());
9
7.02.2014 11:07:06

Я знаю, что этому вопросу уже пять лет, но есть простой способ повторить строку, которая даже работает в .Net 2.0.

Чтобы повторить строку:

string repeated = new String('+', 3).Replace("+", "Hello, ");

Возвращает

"Здравствуйте Здравствуйте Здравствуйте, "

Чтобы повторить строку как массив:

// Two line version.
string repeated = new String('+', 3).Replace("+", "Hello,");
string[] repeatedArray = repeated.Split(',');

// One line version.
string[] repeatedArray = new String('+', 3).Replace("+", "Hello,").Split(',');

Возвращает

{"Здравствуйте Здравствуйте Здравствуйте", ""}

Будь проще.

21
23.08.2015 22:37:53

Попробуй это:

  1. Добавить ссылку на Microsoft.VisualBasic
  2. Использование: String result = Microsoft.VisualBasic.Strings.StrDup (5, "hi");
  3. Дайте мне знать, если это работает для вас.
0
22.12.2017 16:21:05
Добавление зависимости от другой сборки и необходимости ее загрузки нецелесообразно в большинстве случаев, когда вам нужна такая функциональность. Тем не менее, приятно знать, что есть такая вещь в .NET.
Palec 24.12.2017 15:58:47
Там много плюсов и минусов в разных контекстах, поэтому каждый должен решать, в зависимости от ситуации, в которой он / она находится.
Toso Pankovski 25.12.2017 19:01:07

И еще один метод

new System.Text.StringBuilder().Append('\t', 100).ToString()
3
22.01.2018 08:31:48
Передача полученной длины строки в StringBuilderконструктор сохраняет перераспределение. Тем не менее, это более разговорчиво и менее эффективно, чем использование stringконструктора, который может повторять данный символ, как уже показано в принятом ответе.
Palec 22.01.2018 13:48:33

Вы можете создать метод расширения

static class MyExtensions
{
    internal static string Repeat(this char c, int n)
    {
        return new string(c, n);
    }
}

Тогда вы можете использовать это так

Console.WriteLine('\t'.Repeat(10));
2
16.02.2018 17:56:58

Для меня это хорошо

public static class Utils
{
    public static string LeftZerosFormatter(int zeros, int val)
    {
        string valstr = val.ToString();

        valstr = new string('0', zeros) + valstr;

        return valstr.Substring(valstr.Length - zeros, zeros);
    }
}
3
5.09.2018 11:57:14

Без сомнения, принятый ответ - лучший и самый быстрый способ повторить один символ.

Ответ Binoj Anthony - простой и довольно эффективный способ повторить строку.

Однако, если вы не против немного больше кода, вы можете использовать мою технику заполнения массива, чтобы эффективно создавать эти строки еще быстрее. В моих сравнительных тестах приведенный ниже код выполнялся примерно за 35% времени кода StringBuilder.Insert.

public static string Repeat(this string value, int count)
{
    var values = new char[count * value.Length];
    values.Fill(value.ToCharArray());
    return new string(values);
}

public static void Fill<T>(this T[] destinationArray, params T[] value)
{
    if (destinationArray == null)
    {
        throw new ArgumentNullException("destinationArray");
    }

    if (value.Length > destinationArray.Length)
    {
        throw new ArgumentException("Length of value array must not be more than length of destination");
    }

    // set the initial array value
    Array.Copy(value, destinationArray, value.Length);

    int copyLength, nextCopyLength;

    for (copyLength = value.Length; (nextCopyLength = copyLength << 1) < destinationArray.Length; copyLength = nextCopyLength)
    {
        Array.Copy(destinationArray, 0, destinationArray, copyLength, copyLength);
    }

    Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength);
}

Подробнее об этой методике заполнения массива см. В разделе Самый быстрый способ заполнения массива одним значением

1
24.08.2018 21:12:56

Хотя очень похоже на предыдущее предложение, я хотел бы сохранить его простым и применять следующее:

string MyFancyString = "*";
int strLength = 50;
System.Console.WriteLine(MyFancyString.PadRight(strLength, "*");

Стандартный .Net действительно,

-1
27.08.2018 07:28:17
Это просто добавит отступы, не повторяется
levi 6.02.2019 21:08:54