X 번 반복되는 문자열을 반환하는 쉬운 방법이 있습니까?


318

항목 깊이에 따라 문자열 앞에 일정한 수의 들여 쓰기를 삽입하려고하는데 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 "---------".

9
이것이 적용 가능한지 확실하지 않지만 IndentedTextWriter 를보고 싶을 수도 있습니다.
Chris Shouts

귀하의 질문이 허용되는 답변이 묘사하는 문자가 아닌 문자열 반복에 관한 것이므로 허용되는 답변을 변경하고 싶습니까? .Net v4.7까지는 String클래스의 오버로드 된 생성자가 문자열을 매개 변수로 사용하여 반복을 생성하지 않으므로 허용 된 답변을 완벽하게 맞출 수 있습니다.
RBT

답변:


538

동일한 문자 만 반복하려는 경우 문자 를 허용하는 문자열 생성자 와 반복 횟수를 사용할 수 new String(char c, int count)있습니다.

예를 들어 대시를 다섯 번 반복하려면

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

7
이 멋진 작은 기능을 상기시켜 주셔서 감사합니다. 나는 그것이 내 마음의 구석에서 길을 잃었다 고 생각합니다.
Chris Shouts

3
탭 메타 문자 '\ t'는 문자이므로 들여 쓰기에도 효과적입니다.
cori December

91
이것은 C #의 매우 유용한 트릭이지만 질문의 제목은 문자열 (문자가 아닌)을 묻는 것입니다. 이 답변 아래의 다른 답변은 실제로 질문에 대한 답변이지만 훨씬 낮은 등급입니다. 나는 Ahmad의 대답을 무시하지 않으려 고하지만이 질문의 제목을 변경해야하거나 (질문이 실제로 문자와 관련이있는 경우) 다른 답변을 실제로 반대해야한다고 생각합니다 (이 질문은 아닙니다).
pghprogrammer4

14
@Ahmad 내가 말했듯이, 나는 당신이 좋은 정보를 제공했다고 생각하지 않기 때문에 공감하지 않았습니다. 그러나 당신이 제공 한 정보는 현재 언급 된 질문에 대답하는 것과 관련이 없기 때문 입니다. 문자열 (문자가 아닌)을 반복하는 방법을 찾고 있었고 관련 질문에 도달했을 때 질문에 대한 실제 답변을 얻으려면 몇 가지 '유용한'팁을 스크롤해야한다고 상상해보십시오. downvote가 당신에게 공격적이라면 제거 할 수 있습니다. 하지만 내가 어디에서 왔는지 아나? 내가 완전히 기지 밖입니까?
pghprogrammer4

11
@ pghprogrammer4 IMHO, downvotes는 매우 실망 스러울 수 있으며, 중대한 변경이 필요하거나 저자가 삭제해야하는 해로운 / 오도적인 / truly_bad 답변에만 사용해야합니다. 사람들이 관대하고 자신이 알고있는 것을 나누고 싶어하기 때문에 답이 있습니다. 일반적으로 이러한 사이트는 유용한 답변을 맨 위로 가져 오기 위해 공감대를 장려합니다.
ToolmakerSteve

271

.NET 4.0을 사용 string.Concat하는 경우와 함께 사용할 수 있습니다 Enumerable.Repeat.

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

그렇지 않으면 나는 Adam 's answer 와 같은 것을 가지고 갈 것입니다 .

내가 Andrey의 답변을 사용 하지 말라고 일반적으로 조언 하지 않는 이유 는 단순히 전화 가 Adam이 제안한 접근 방식으로 피할 수없는 불필요한 오버 헤드를 유발하기 때문입니다 . 즉, 적어도 .NET 4.0을 요구하지 않고 작동합니다. 그리고 빠르고 쉽습니다 (효율성이 그다지 중요하지 않으면 당신을 죽이지 않을 것입니다).ToArray()StringBuilder


3
비 공백 공백을 연결해야하는 경우와 같이 문자열에서 잘 작동합니다 (& nbsp;). 그러나 나는 당신이 문자를 다루는 경우 문자열 생성자가 가장 빠를 것이라고 생각합니다 ...
woodbase

1
문자열 생성자는 한 문자에 대해서만 작동합니다. CONCAT 반복을 사용하는 옵션 문자열을 작동합니다
엘리 다간에게

4
실제 제목 질문에 답변 해 주셔서 감사합니다!
Mark K Cowan

나는이 대답을 좋아한다!
Ji_in_coding

-System.Linq.Enumerable 등을 출력으로 얻는다면 스 니펫을 복사 / 붙여 넣기 및 수정하기에 너무 빠르기 때문입니다. Enumerable.Repeat의 출력에 다른 문자열을 연결해야하는 경우 다음과 같이해야합니다. Console.WriteLine(string.Concat("-", string.Concat(Enumerable.Repeat(indent, N))));
Gabe

47
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;
    }
}

6
생성자 input.Length * count에게 전달 될 수도 StringBuilder있습니다.
Dan Tao

그리고 생성자 에게 전달 input.Length * count하면, 전체를 StringBuilder건너 뛰고 StringBuilder바로 적절한 크기의 char []를 만들 수 있습니다.
dtb

@ dtb : 왜 그렇게하고 싶어하는지 궁금합니다. 나는을 사용하는 것보다 훨씬 빠를 것이라고 상상할 수 없으며 StringBuilder코드는 덜 투명합니다.
Adam Robinson

@dtb : ck. StringBuilder를 사용하십시오. 이 작업을 효율적으로 수행하도록 설계되었습니다.
ToolmakerSteve

아담, 당신이 계산에 추가 할 때 입력을 null로 테스트하는 데 어려움을 겪은 것을 보았지만 추가를 허용하여 null을 지정하지 않았습니다. IMHO 이것은 분명하지 않습니다. null이 가능한 입력이라면, 먼저 테스트하고 빈 문자열을 반환하지 않겠습니까?
ToolmakerSteve

46

문자열에 가장 성능이 뛰어난 솔루션

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

1
물론 하나의 라이너입니다. 가장 성능이 좋지는 않습니다. StringBuilder는 매우 적은 수의 연결에 비해 약간의 오버 헤드가 있습니다.
Teejay

25

많은 시나리오에서 아마도 가장 적은 해결책 일 것입니다.

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스토리지 사전 할당을 효율적으로 사용 합니다.

동의합니다. 훌륭합니다. 방금 Bob에게 크레딧을 주어 코드에 이것을 추가했습니다! 감사!
John Burley

22

원하는 문자열에 단일 문자 만 포함 된 경우 String.PadLeft를 사용하십시오 .

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

여기에 크레딧


1
키스. 어쨌든 StringBuilders와 확장이 필요한 것은 무엇입니까? 이것은 매우 간단한 문제입니다.
DOK

1
나는 몰라, 이것은 우아함과 함께 표현 된 문제를 해결하는 것 같습니다. 그리고 btw, 당신은 누구를 'S'라고 부릅니까? :-)
Steve Townsend

7
그러나 이것은 정말로 단지 덜 분명 버전이 아닙니다 소요 생성자 와를 ? stringcharint
Dan Tao

""대신 String.Empty를 사용하면 더 좋아 보일 것입니다 ... 그렇지 않으면 좋은 해결책;)
Thomas Levesque

@Steve BTW String.PadLeft인수가 반대로됩니다. 는 count패딩 문자 앞에 온다.
Ahmad Mageed

17

문자열을 반복하고 (단일 문자가 아닌 경우) 다음과 같이 결과를 연결할 수 있습니다.

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

12

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();
}

3
내 프로젝트에서이 스 니펫을 발견하면 누가 KISS를 위반했는지 궁금합니다. 그렇지 않으면 왜
좋은지

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());

1
@Adam : .NET 4.0 이전 버전을 수행해야 할 것 같습니다.
Dan Tao

3

나는 주어진 대답을 좋아한다. 같은 줄을 따라 과거에 사용한 적이 있습니다.

"".PadLeft (3 * 들여 쓰기, '-')

이것은 들여 쓰기를 수행하지만 기술적으로 문자열을 반복하는 것이 었습니다. 문자열 들여 쓰기가>-<와 같은 경우 수락 된 답변뿐만 아니라 작동하지 않습니다. 이 경우 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

우리는 모두 영리한 솔루션을 좋아하지만 때로는 단순합니다.


3

확장 방법 추가 프로젝트 전체에서 사용하고 있습니다.

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

누군가가 그것을 사용할 수 있기를 바랍니다 ...


2

아무도 옛날 학교에 가지 않았다는 사실에 놀랐습니다. 나는 이 코드에 대해 어떤 주장도 하지 않고 단지 재미를 위해 :

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);
}

분명히 나는 그것을 독창적 인 독자를위한 시험으로 남겨 두었습니다 :) 매우 감사합니다.
OlduwanSteve

1
아무것도 구식이 매개 변수 @this 이름 지정있다, 그것은 항상 끔찍한 생각 :)이었다
데이브 Jellison

2
CSS를 참조하는 클래스가 필요하지만 C #의 키워드이기 때문에 MVC로 작업 할 때 강제하지 않는 한 키워드를 변수 이름으로 사용하지 않는 것이 좋습니다 (예 : @class = "something"). 이것은 일반적으로 컴파일 가능한 코드이며 합법적이지만 실제적인 이유와 함께 읽기와 타이핑의 용이성에 대해서도 생각하십시오. 매우 먼저 일어나는 일을 설명하기 위해 매개 변수 이름을 사용하는 것이 매우 중요합니다. INT 카운트가) 더 설명 이럴 수 있습니다.
데이브 Jellison

1
재미 있네요 이 경우에는 @this가 설명 할 수있는 것보다 덜 설명적일 것입니다. 그러나 일반적으로 나는 'this'에 대한 유일한 합리적인 이름이 다소 일반적인 클래스 또는 인터페이스를 확장하는 것이 일반적이라고 생각합니다. 'instance'또는 'it'또는 'str'( MSDN 참조 ) 이라는 매개 변수가 있으면 아마도 이것이 'this'입니다.
OlduwanSteve

1
나는 기본적으로 당신과 동의하지만 논쟁의 여지가 있습니다 ... 내가 만들고있는 문자열에 대해 더 많이 알고 있기 때문에 StringBuilder보다 약간 더 나은 일을 할 수 있습니다. StringBuilder는 메모리를 할당 할 때 추측해야합니다. 부여는 누군가가 : 병렬 반복 문자열의 거대한 수를 구축하고 다시 몇 클럭 사이클을 얻을 다행 수 있습니다에서 많은 시나리오에서 중요하지 않을하지만
OlduwanSteve

2

이것이 어떻게 수행되는지 확실하지 않지만 쉬운 코드입니다. (아마도 더 복잡하게 보이게 만들었을 것입니다.)

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;      

2

Adam의 답변에 대해 언급 할 충분한 담당자가 없지만 imo를 수행하는 가장 좋은 방법은 다음과 같습니다.

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가 0보다 큰지 확인해야합니다. 그렇지 않으면 예외가 발생합니다.


2

이 솔루션을 보지 못했습니다. 현재 소프트웨어 개발 위치가 더 간단합니다.

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

2

일반적으로 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의 내용을 자체로 복사하면 반복 할 때마다 해당 내용으로 새 문자열을 생성하는 오버 헤드가 있으므로 StringBuilder 사용에 대해 Array.Copy () 메서드를 사용했습니다. Array.Copy ()는 여전히 매우 높은 효율로 작동하면서 이것을 피합니다.

이 솔루션은 O (1 + log N) 반복을 완료하는데, 반복 횟수에 따라 대수적으로 증가하는 속도 (반복 횟수가 두 번의 추가 반복과 동일 함)는 다른 방법에 비해 실질적으로 절약되며 비례 적으로 증가합니다.


1

또 다른 방법은 고려하는 것입니다 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());

1

반복해서 줄을 인쇄하십시오.

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

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


문자열 끝에 \ n을 추가하는 대신 Console.WriteLine을 사용하지 않은 이유는 무엇입니까?
InxaneNinja

-1

이를 위해 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))
  }
}

3
Kyle의 답변에 대한 내 의견보기
Thomas Levesque
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.