关于c#:有一种简单的方法可以重复多次返回一个字符串吗?

Is there an easy way to return a string repeated X number of times?

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

1
2
3
4
5
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"---------".


如果您只想重复同一个字符,那么可以使用接受字符的字符串构造函数和重复该字符的次数new String(char c, int count)

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

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


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

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

否则我会选择亚当的答案。

我一般不建议使用Andrey的答案的原因只是ToArray()调用引入了多余的开销,这是通过Adam建议的StringBuilder方法避免的。这就是说,至少它在不需要.NET 4.0的情况下工作;而且它快速简单(如果效率不是一个太大的问题,它不会杀死你)。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
    }
}


字符串的最佳性能解决方案

1
string result = new StringBuilder().Insert(0,"---", 5).ToString();


如果所需的字符串只包含一个字符,请使用string.padleft。

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

信用到期


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

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

然后使用:

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

这建立在其他答案的基础上(尤其是@c0rd)。除了简单之外,它还具有以下特性,这些特性并非所有讨论过的其他技术都具有相同的特点:

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


我同意丹涛的回答,但如果你不使用.NET 4.0,你可以这样做:

1
2
3
4
5
6
7
8
public static string Repeat(this string str, int count)
{
    return Enumerable.Repeat(str, count)
                     .Aggregate(
                        new StringBuilder(),
                        (sb, s) => sb.Append(s))
                     .ToString();
}


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

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

1
2
3
4
        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());


我喜欢给出的答案。不过,我过去也用过同样的方法:

".padleft(3*缩进,-")

这将完成创建缩进,但从技术上讲,问题是重复一个字符串。如果字符串缩进类似于>-<那么这个以及接受的答案将不起作用。在这种情况下,c0rd使用StringBuilder的解决方案看起来不错,尽管StringBuilder的开销实际上并不能使其成为最具性能的解决方案。一个选项是构建一个字符串数组,用缩进字符串填充它,然后进行concat。惠特:

1
2
3
4
5
6
7
8
9
10
11
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

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


不确定这将如何执行,但这是一段简单的代码。(我可能使它看起来比实际更复杂。)

1
2
3
4
5
6
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);

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

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


很惊讶没有人上过老学校。我并没有对这段代码做任何声明,只是为了好玩:

1
2
3
4
5
6
7
8
9
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);
}


我没有足够的代表来评论亚当的回答,但在我看来最好的方法是:

1
2
3
4
5
6
7
8
9
10
11
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是否大于零,否则您将得到一个异常。


通用的解决方案涉及使用StringBuilder类是最好的repeating对多字符的字符串。它的改进行动的组合两个大数。在一个简单的方式,concatenation不难,这将是不可能的。两个或更多的城市做有效的手。在这里shown StringBuilder的解决方案是使用O(n)的两个完整的iterations A的扁平率的比例的数小时的重复它。

然而,repeats非常大的数,或在高水平的效率,必须squeezed了它,一个更好的方法是相似的两个StringBuilder做一些基本的功能性产品,但两个额外的副本从目的地,而不是从原始的字符串,如下面的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    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);
    }

这双the length of the源/目的地与每个迭代字符串,它保存在头顶部resetting计数器每小时它会去通过原始的字符串,而不是通smoothly阅览和复制的字符串的语言。现在,现代加工的东西,可以做的更有效的多。

它辨别A座2 logarithm如何找到两个多小时的IT需求的两个双长度的字符串,然后做婊子,所得的两个多小时。由于这两个remainder copied是现在的总长度小于复制它是虔诚的,它可以是简单的copy of A的子集,它已生。

要使用的array.copy()方法在使用StringBuilder,作为一个复制的内容的StringBuilder到本身的开销将产生一个新的字符串,内容和与每个迭代。这avoids array.copy()的操作,在静止和率非常高的效率。

这个解决方案需要O(log n + 1)iterations两个完整率,这会增加对数与repeats(number of the number of doubling repeats equals一额外的迭代),增加储蓄,在其他的方法,这增长的比例。


我没有看到这个解决方案。我发现我目前从事软件开发的地方更简单:

1
2
3
4
5
6
7
8
public static void PrintFigure(int shapeSize)
{
    string figure ="\\/";
    for (int loopTwo = 1; loopTwo <= shapeSize - 1; loopTwo++)
    {
        Console.Write($"{figure}");
    }
}

重复打印一行。

1
2
Console.Write(new string('=', 30) +"
"
);

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


另一种方法是将string视为IEnumerable,并使用通用扩展方法,将集合中的项乘以指定的因子。

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

所以在你的例子中:

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

您可以创建一个扩展方法来实现这一点!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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解决方案:

1
2
3
4
5
6
7
8
9
10
public static class StringExtension
{
  public static string Repeat(this string str, int count)
  {
    if (count == 0)
      return"";

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