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"---------". |
如果您只想重复同一个字符,那么可以使用接受字符的字符串构造函数和重复该字符的次数
例如,要重复破折号五次:
1 |
如果您使用的是.NET 4.0,那么可以将
1 2 | int N = 5; // or whatever Console.WriteLine(string.Concat(Enumerable.Repeat(indent, N))); |
否则我会选择亚当的答案。
我一般不建议使用Andrey的答案的原因只是
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.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 |
我没有足够的代表来评论亚当的回答,但在我看来最好的方法是:
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 |
==============================
另一种方法是将
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)) } } |