C #에서 문자를 반복하는 가장 좋은 방법


812

\tC #에서 의 문자열을 생성하는 가장 좋은 방법은 무엇입니까?

나는 C #을 배우고 같은 말을하는 다른 방법으로 실험하고 있습니다.

Tabs(uint t)함수입니다 리턴 stringt\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; 
}

답변:


1490

이건 어때?

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

n문자열을 반복하려는 횟수는 어디 입니까?

또는 더 나은 :

static string Tabs(int n)
{
    return new String('\t', n);
}

2
단어에 대해 이것을 반복 할 수있는 방법이 있습니까? '\ t'를 사용하는 대신 "time"을 사용하는 방법
asdfkjasdfjk

6
@ user1478137 또는 더 낫다 (더 아래로) : this
Xynariz

161
string.Concat(Enumerable.Repeat("ab", 2));

보고

"아밥"

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

보고

"aa"

에서...

.net에서 문자열 또는 문자를 반복하는 내장 함수가 있습니까?


1
Linq와 함께라면 더 잘할 수 있습니다 StruingBuilder!
Bitterblue

4
''StringBuilder ''가 반드시 더 빠른 것은 아닙니다. stackoverflow.com/questions/585860/…
Schiavini

6
더 빠르지는 않지만 올바른 용량을 미리 지정하면 메모리 할당 (압력)을 줄일 수 있으며 이는 프로파일 링의 마이크로 벤치 마크만큼 중요 할 수 있습니다.
wekempf

1
var strRepeat = string.Concat (Enumerable.Repeat ( "ABC", 1000000)); // 50ms
yongfa365

1
@Pharap string.Join은 공백 구분 기호를 사용했기 때문에 예제에서 더 빠릅니다. string.Concat구분자가없는 경우에 적합합니다.
카터 메 드린

124

모든 버전의 .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의 답변을 참조하십시오 .


7
이것은 String에있어서 현명한 성능입니다. 다른 방법으로는 너무 많은 오버 헤드가 발생합니다.
midspace

@midspace 왜 다른 답변이 더 나쁜지 설명한 사람이 있습니까? 네이티브 String.Concat은 StringBuilder
Marie

@Marie 다음 기사에서는 장점을 설명합니다. support.microsoft.com/en-au/help/306822/… 그렇지 않으면 두 가지 다른 요소가 있습니다. StringBuilder는 문자열을 허용하며 문자 (원래 질문과 관련이 없지만)와 문자열에만 제한되지 않습니다. 위의 Concat 답변은 Enumerable.Repeat을 사용하여 배열을 먼저 만들어야합니다. 내가 말했듯이 불필요한 오버 헤드입니다.
midspace

항목별로 항목을 반복 할 수 있기 때문에 배열을 먼저 만들지 않을 것이라고 가정했습니다. 링크 주셔서 감사합니다, 나는 그것을 읽어 줄 것이다!
Marie

63

가장 좋은 버전은 확실히 내장 방식을 사용하는 것입니다.

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

다른 솔루션 중에서 가장 쉬운 방법을 선호하십시오. 이것이 너무 느리게 입증되는 경우에만보다 효율적인 솔루션을 위해 노력하십시오.

a를 사용 StringBuilder하고 결과 길이를 미리 알고 적절한 생성자를 사용하는 경우 시간이 많이 걸리는 할당이 하나만 발생하고 데이터를 불필요하게 복사하지 않기 때문에 훨씬 효율적입니다. 넌센스 : 물론 위의 코드가 더 효율적입니다.


12
sb.Append ( '\ t', len);
dan-gph

7
내 벤치 마크는 접근 방식 new string('\t', len)보다 2 배에서 7 배 빠릅니다 StringBuilder. StringBuilder이 경우 왜 더 효율적 이라고 생각 하십니까?
StriplingWarrior

6
@StriplingWarrior이 문제를 해결해 주셔서 감사합니다 (2 년 동안 여기에 섰을 때!
Konrad Rudolph

51

확장 방법 :

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

39
옛날 옛적에 사람들이 while 루프를 사용
prabhakaran

2
@prabhakaran 동의하지만 Linq의 장점은 커뮤니케이션입니다. 명령형 구문을 사용하여 Linq 표현식을 다시 구현하는 것은 거의 사소한 일입니다.
Rodrick Chapman

10
Enumerable.Range(0, n).SelectMany(x => s)간단한 것으로 대체 할 수 있습니다 Enumerable.Repeat(s, n).
Palec

5
@Palec 아니요. SelectMany각 단일 더미위한 의지 x시퀀스 제공 char합니다 (보낸 값을 string s구현하는 IEnumerable<char>), 및 모든 char서열을 하나의 긴 연결된다 char시퀀스. 당신이 제안하는 것은 대신에을 줄 것 IEnumerable<string>입니다. 동일하지 않습니다.
Jeppe Stig Nielsen

2
@JeppeStigNielsen이 잘못되었습니다. 헤드 업 주셔서 감사합니다. 정말로을 사용 Enumerable.Repeat하고 싶다면 문자열을 함께 연결해야합니다 string.Concat(Enumerable.Repeat(s, n)). 이것은 이미 전에 게시 되었습니다 .
Palec

40

확장 방법을 사용하는 것은 어떻습니까?


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)) // 문자열 버전


2
Binoj Anthony가 대답 한StringBuilder.Insert(Int32, String, Int32) 것처럼 문자열 버전의 성능은을 사용하여 향상 될 수 있습니다 .
Palec

23

이건 어때요:

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

4
haha .. 그것이 내가이 상황에 한 번 빠졌을 때 생각할 수있는 것입니다. 그러나 개인적으로 내가 찾은 new string('\t', 10)최고의 솔루션으로
shashwat

이 트릭은 Essential C # 6.0 에서도 사용됩니다 .
돈 지향 프로그래머

22

나는이 질문이 이미 5 살이라는 것을 알고 있지만 .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(',');

보고

{"안녕 안녕 안녕", ""}

간단하게 유지하십시오.



17

사용하는 첫 번째 예 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));
}

14

사용 String.Concat하고 사용 Enumerable.Repeat하는 것보다 비용이 적게 듭니다String.Join

public static Repeat(this String pattern, int count)
{
    return String.Concat(Enumerable.Repeat(pattern, count));
}

9
var str = new string(Enumerable.Repeat('\t', numTabs).ToArray());

4

답은 실제로 원하는 복잡성에 달려 있습니다. 예를 들어, 모든 들여 쓰기를 세로 막대로 설명하고 싶습니다. 따라서 들여 쓰기 문자열은 다음과 같이 결정됩니다.

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

3

그리고 또 다른 방법

new System.Text.StringBuilder().Append('\t', 100).ToString()

결과 문자열 길이를 StringBuilder생성자에 전달 하면 재 할당이 저장됩니다. 그럼에도 불구하고 이것은 string이미 허용 된 답변에 표시된 것처럼 주어진 문자를 반복 할 수 있는 생성자를 사용하는 것보다 수다스럽고 덜 효율적 입니다.
Palec

3

나를 위해 괜찮습니다 :

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

2

확장 방법을 만들 수 있습니다

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

그러면 이렇게 사용할 수 있습니다

Console.WriteLine('\t'.Repeat(10));

1

의심의 여지없이 허용되는 답변은 한 문자를 반복하는 가장 빠르고 빠른 방법입니다.

Binoj Anthony의 대답은 문자열을 반복하는 간단하고 매우 효율적인 방법입니다.

그러나 조금 더 코드가 마음에 들지 않으면 배열 채우기 기술을 사용하여 이러한 문자열을 더욱 빠르게 만들 수 있습니다. 필자의 비교 테스트에서 아래 코드는 StringBuilder.Insert 코드 시간의 약 35 %에서 실행되었습니다.

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

이 배열 채우기 기술에 대한 자세한 내용 은 단일 값으로 배열을 채우는 가장 빠른 방법을 참조하십시오.


0

이 시도:

  1. Microsoft.VisualBasic 참조 추가
  2. 사용 : String result = Microsoft.VisualBasic.Strings.StrDup (5, "hi");
  3. 그것이 당신을 위해 작동하는지 알려주세요.

다른 어셈블리에 대한 의존성과로드 필요성을 추가하는 것은 그러한 기능이 필요한 대부분의 경우 부당합니다. 여전히 .NET에는 그러한 것이 있다는 것을 아는 것이 좋습니다.
Palec

상황에 따라 많은 장단점이 있으므로 모든 사람은 자신이 처한 상황에 따라 결정해야합니다.
Toso Pankovski

-1

이전 제안과 매우 유사하지만 간단하게 유지하고 다음을 적용하고 싶습니다.

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

표준 .Net은 정말


패딩 만 추가하고 반복하지 않습니다
levi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.