有一种简单的方法可以返回重复X次的字符串吗?

时间:2010-09-20 19:01:33

标签: c# .net

我正在尝试在基于项深度的字符串之前插入一定数量的缩进,我想知道是否有办法返回重复X次的字符串。例如:

string indent = "---";
Console.WriteLine(indent.Repeat(0)); //would print nothing.
Console.WriteLine(indent.Repeat(1)); //would print "---".
Console.WriteLine(indent.Repeat(2)); //would print "------".
Console.WriteLine(indent.Repeat(3)); //would print "---------".

20 个答案:

答案 0 :(得分:470)

如果您只打算重复相同的字符,可以使用接受字符的string constructor和重复字符的次数new String(char c, int count)

例如,要重复五次破折号:

string result = new String('-', 5); // -----

答案 1 :(得分:236)

如果您使用的是.NET 4.0,则可以将string.ConcatEnumerable.Repeat一起使用。

int N = 5; // or whatever
Console.WriteLine(string.Concat(Enumerable.Repeat(indent, N)));

否则我会选择像Adam's answer这样的东西。

我通常不会建议使用Andrey's answer的原因只是ToArray()调用引入了多余的开销,而StringBuilder方法建议避免使用亚当。也就是说,至少它可以在不需要.NET 4.0的情况下工作;它既快速又简单(如果效率不是太大的话,也不会杀了你。)

答案 2 :(得分:42)

public static class StringExtensions
{
    public static string Repeat(this string input, int count)
    {
        if (!string.IsNullOrEmpty(input))
        {
            StringBuilder builder = new StringBuilder(input.Length * count);

            for(int i = 0; i < count; i++) builder.Append(input);

            return builder.ToString();
        }

        return string.Empty;
    }
}

答案 3 :(得分:38)

字符串

的最佳性能解决方案
string result = new StringBuilder().Insert(0, "---", 5).ToString();

答案 4 :(得分:19)

如果您想要的字符串只包含一个字符,请使用String.PadLeft

public static string Indent(int count, char pad)
{
    return String.Empty.PadLeft(count, pad);
}

到期信用here

答案 5 :(得分:15)

对于许多情况,这可能是最好的解决方案:

public static class StringExtensions
{
    public static string Repeat(this string s, int n)
        => new StringBuilder(s.Length * n).Insert(0, s, n).ToString();
}

然后用法:

text = "Hello World! ".Repeat(5);

这建立在其他答案的基础上(尤其是@ c0rd)。除了简单性之外,它还具有以下功能,而不是所讨论的所有其他技术共享:

  • 重复任意长度的字符串,而不仅仅是字符(按照OP的要求)。
  • 通过存储预分配有效使用StringBuilder

答案 6 :(得分:11)

我会选择Dan Tao的答案,但如果您不使用.NET 4.0,您可以这样做:

public static string Repeat(this string str, int count)
{
    return Enumerable.Repeat(str, count)
                     .Aggregate(
                        new StringBuilder(),
                        (sb, s) => sb.Append(s))
                     .ToString();
}

答案 7 :(得分:9)

您可以重复字符串(如果不是单个字符)并合并结果,如下所示:

String.Concat(Enumerable.Repeat("---", 5))

答案 8 :(得分:3)

        string indent = "---";
        string n = string.Concat(Enumerable.Repeat(indent, 1).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 2).ToArray());
        string n = string.Concat(Enumerable.Repeat(indent, 3).ToArray());

答案 9 :(得分:2)

我喜欢给出的答案。沿着同样的路线,虽然是我过去使用过的:

“” PadLeft(3 *缩进, ' - ')。

这将完成创建缩进,但从技术上讲,问题是重复一个字符串。如果字符串缩进类似于&gt; - &lt;那么这个以及接受的答案都行不通。在这种情况下,使用stringbuilder的c0rd解决方案看起来不错,尽管stringbuilder的开销可能实际上并不能使其成为最高性能的。一种选择是构建一个字符串数组,用缩进字符串填充它,然后连接它。致白:

int Indent = 2;

string[] sarray = new string[6];  //assuming max of 6 levels of indent, 0 based

for (int iter = 0; iter < 6; iter++)
{
    //using c0rd's stringbuilder concept, insert ABC as the indent characters to demonstrate any string can be used
    sarray[iter] = new StringBuilder().Insert(0, "ABC", iter).ToString();
}

Console.WriteLine(sarray[Indent] +"blah");  //now pretend to output some indented line

我们都喜欢聪明的解决方案,但有时简单是最好的。

答案 10 :(得分:1)

我没有足够的代表对Adam的答案发表评论,但最好的方式就是这样:

public static string RepeatString(string content, int numTimes) {
        if(!string.IsNullOrEmpty(content) && numTimes > 0) {
            StringBuilder builder = new StringBuilder(content.Length * numTimes);

            for(int i = 0; i < numTimes; i++) builder.Append(content);

            return builder.ToString();
        }

        return string.Empty;
    }

您必须检查numTimes是否大于零,否则您将获得异常。

答案 11 :(得分:1)

不确定这会如何表现,但它是一段简单的代码。 (我可能认为它看起来比现在更复杂。)

int indentCount = 3;
string indent = "---";
string stringToBeIndented = "Blah";
// Need dummy char NOT in stringToBeIndented - vertical tab, anyone?
char dummy = '\v';
stringToBeIndented.PadLeft(stringToBeIndented.Length + indentCount, dummy).Replace(dummy.ToString(), indent);

或者,如果您知道可以预期的最大级别数,则可以声明一个数组并将其编入索引。您可能希望将此数组设为静态或常量。

string[] indents = new string[4] { "", indent, indent.Replace("-", "--"), indent.Replace("-", "---"), indent.Replace("-", "----") };
output = indents[indentCount] + stringToBeIndented;      

答案 12 :(得分:1)

惊讶没有人去上学。我没有对此代码提出任何声明,只是为了好玩:

public static string Repeat(this string @this, int count)
{
    var dest = new char[@this.Length * count];
    for (int i = 0; i < dest.Length; i += 1)
    {
        dest[i] = @this[i % @this.Length];
    }
    return new string(dest);
}

答案 13 :(得分:0)

我没有看到这个解决方案。我觉得我目前在软件开发方面的位置比较简单:

public static void PrintFigure(int shapeSize)
{
    string figure = "\\/";
    for (int loopTwo = 1; loopTwo <= shapeSize - 1; loopTwo++)
    {
        Console.Write($"{figure}");
    }
}

答案 14 :(得分:0)

另一种方法是将string视为IEnumerable<char>,并使用通用扩展方法将系列中的项目乘以指定因子。

public static IEnumerable<T> Repeat<T>(this IEnumerable<T> source, int times)
{
    source = source.ToArray();
    return Enumerable.Range(0, times).SelectMany(_ => source);
}

所以在你的情况下:

string indent = "---";
var f = string.Concat(indent.Repeat(0)); //.NET 4 required
//or
var g = new string(indent.Repeat(5).ToArray());

答案 15 :(得分:0)

打印重复行。

Console.Write(new string('=', 30) + "\n");
  

=============================

答案 16 :(得分:0)

对于一般用途,涉及StringBuilder类的解决方案最适合重复多字符字符串。它经过优化,可以处理简单的串联无法实现的大量字符串的组合,而手工连接将很难或不可能高效地进行。此处显示的StringBuilder解决方案使用 O(N)迭代来完成,这是与重复次数成比例的固定费率。

但是,对于大量重复,或必须从中挤出高效率的情况,更好的方法是执行类似于StringBuilder基本功能的操作,但要从目标而不是从目标生成其他副本。原始字符串,如下所示。

    public static string Repeat_CharArray_LogN(this string str, int times)
    {
        int limit = (int)Math.Log(times, 2);
        char[] buffer = new char[str.Length * times];
        int width = str.Length;
        Array.Copy(str.ToCharArray(), buffer, width);

        for (int index = 0; index < limit; index++)
        {
            Array.Copy(buffer, 0, buffer, width, width);
            width *= 2;
        }
        Array.Copy(buffer, 0, buffer, width, str.Length * times - width);

        return new string(buffer);
    }

每次迭代都会使源/目标字符串的长度加倍,从而节省了每次通过原始字符串时重置计数器的开销,而无需平滑地读取并复制现在更长的字符串,这是现代处理器所需要的可以做得更有效率。

它使用以2为底的对数来查找将字符串长度加倍所需的次数,然后进行多次。由于现在要复制的其余部分小于要复制的总长度,因此它可以简单地复制已生成内容的子集。

我已经在使用StringBuilder时使用了Array.Copy()方法,因为将StringBuilder的内容复制到自身中会产生开销,每次迭代都会产生一个包含该内容的新字符串。 Array.Copy()避免了这种情况,同时仍然以极高的效率运行。

此解决方案需要完成 O(1 + log N)次迭代,该速率与重复次数成对数增长(重复次数加倍等于一个额外的迭代),在其他方法按比例增加。

答案 17 :(得分:0)

添加扩展方法我正在使用所有项目:

public static string Repeat(this string text, int count)
{
    if (!String.IsNullOrEmpty(text))
    {
        return String.Concat(Enumerable.Repeat(text, count));
    }
    return "";
}

希望有人可以使用它...

答案 18 :(得分:0)

使用字符串和字符:

string.Join("", Enumerable.Repeat("text" , 2 ));

//result: texttext

Ver2:

new StringBuilder().Insert(0, "text", 2).ToString();

//result: texttext

仅适用于字符:​​

new string('5', 5);

//result: 55555

答案 19 :(得分:-2)

你可以创建一个ExtensionMethod来做到这一点!

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    string ret = "";

    for (var x = 0; x < count; x++)
    {
      ret += str;
    }

    return ret;
  }
}

或使用@Dan Tao解决方案:

public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    if (count == 0)
      return "";

    return string.Concat(Enumerable.Repeat(indent, N))
  }
}