[C#] 문자열 내에서 문자열 (실제로는 char)의 발생을 어떻게 계산합니까?

나는 /문자열에서 찾을 수있는 수 를 세고 싶다는 것을 깨달은 것을하고 있는데, 여러 가지 방법이 있었지만 가장 좋았거나 가장 쉬운 것이 무엇인지 결정할 수 없었습니다. .

현재 나는 다음과 같은 일을하고있다 :

string source = "/once/upon/a/time/";
int count = source.Length - source.Replace("/", "").Length;

그러나 나는 그것을 전혀 좋아하지 않는다.

나는 이것을 정말로 파고 싶지 않다 RegEx.

내 문자열에 내가 찾고있는 용어가 있다는 것을 알고 있으므로 다음과 같이 가정 할 수 있습니다 …

물론 길이> 1 인 문자열의 경우

string haystack = "/once/upon/a/time";
string needle = "/";
int needleCount = ( haystack.Length - haystack.Replace(needle,"").Length ) / needle.Length;



답변

.NET 3.5를 사용하는 경우 LINQ의 단일 라이너 에서이 작업을 수행 할 수 있습니다.

int count = source.Count(f => f == '/');

LINQ를 사용하지 않으려면 다음을 수행하십시오.

int count = source.Split('/').Length - 1;

원래 기술이이 기술들 중 약 30 % 더 빠르다는 것을 알게되면 놀랄 것입니다! 방금 “/ once / upon / a / time /”으로 빠른 벤치 마크를 수행했으며 결과는 다음과 같습니다.

원본 = 12

소스 카운트 = 19 초 소스 스플릿 = 17 초
foreach ( bobwienholt의 답변에서 ) = 10 초

(시간은 50,000,000 회 반복되므로 실제 세계에서 큰 차이를 느끼지 못할 것입니다.)


답변

string source = "/once/upon/a/time/";
int count = 0;
foreach (char c in source)
  if (c == '/') count++;

source.Replace()자체 보다 빨라야 합니다.


답변

int count = new Regex(Regex.Escape(needle)).Matches(haystack).Count;


답변

문자뿐만 아니라 전체 문자열을 검색하려면 다음을 수행하십시오.

src.Select((c, i) => src.Substring(i))
    .Count(sub => sub.StartsWith(target))

“문자열의 각 문자에 대해 해당 문자에서 시작하는 나머지 문자열을 하위 문자열로 사용하고 대상 문자열로 시작하는 경우 계산하십시오.”


답변

조사한 결과 , 대부분 Richard Richard의 솔루션이 가장 빠릅니다. 그것은 게시물에있는 모든 솔루션의 결과가있는 표입니다 ( “test {test”와 같은 문자열을 구문 분석하는 동안 예외가 발생하기 때문에 Regex를 사용하는 것을 제외하고 )

    Name      | Short/char |  Long/char | Short/short| Long/short |  Long/long |
    Inspite   |         134|        1853|          95|        1146|         671|
    LukeH_1   |         346|        4490|         N/A|         N/A|         N/A|
    LukeH_2   |         152|        1569|         197|        2425|        2171|
Bobwienholt   |         230|        3269|         N/A|         N/A|         N/A|
Richard Watson|          33|         298|         146|         737|         543|
StefanosKargas|         N/A|         N/A|         681|       11884|       12486|

짧은 문자열 (10-50 자)에서 짧은 부분 문자열 (1-5 자)이 나타나는 경우 원래 알고리즘이 선호된다는 것을 알 수 있습니다.

또한 다중 문자 하위 문자열의 경우 다음 코드를 사용해야합니다 ( Richard Watson의 솔루션 기반 ).

int count = 0, n = 0;

if(substring != "")
{
    while ((n = source.IndexOf(substring, n, StringComparison.InvariantCulture)) != -1)
    {
        n += substring.Length;
        ++count;
    }
}


답변

LINQ는 모든 컬렉션에서 작동하며 문자열은 문자의 모음이므로이 멋진 한 줄짜리는 어떻습니까?

var count = source.Count(c => c == '/');

되어 있는지 확인하십시오 using System.Linq;으로, 코드 파일의 맨 위에 .Count해당 네임 스페이스에서 확장 방법이다.


답변

string source = "/once/upon/a/time/";
int count = 0;
int n = 0;

while ((n = source.IndexOf('/', n)) != -1)
{
   n++;
   count++;
}

내 컴퓨터에서는 5 천만 번 반복되는 모든 문자 솔루션보다 약 2 초 빠릅니다.

2013 년 개정 :

문자열을 char []로 변경하고 반복하십시오. 50m 반복 동안 총 시간을 2 초 더 줄입니다!

char[] testchars = source.ToCharArray();
foreach (char c in testchars)
{
     if (c == '/')
         count++;
}

이것은 여전히 ​​더 빠릅니다.

char[] testchars = source.ToCharArray();
int length = testchars.Length;
for (int n = 0; n < length; n++)
{
    if (testchars[n] == '/')
        count++;
}

좋은 측정을 위해 배열의 끝에서 0까지 반복하는 것이 약 5 %가 가장 빠릅니다.

int length = testchars.Length;
for (int n = length-1; n >= 0; n--)
{
    if (testchars[n] == '/')
        count++;
}

나는 이것이 왜 가능하고 인터넷 검색을하고 있는지 궁금해하고 있었고 (반복 반복이 빠르다는 것에 대해 무언가를 회상했다), 이미 귀찮게 문자열을 char [] 기술로 사용하는이 SO 질문에 나왔다. 그러나이 맥락에서 반전 트릭은 새로운 것이라고 생각합니다.

C #에서 문자열의 개별 문자를 반복하는 가장 빠른 방법은 무엇입니까?