[英]How can I count the occurences of a certain character combination in a text file in the fastest possible way?
[英]How can I retrieve the count of a certain character in a string array?
我有這段代碼來嘗試計算字符串數組中出現了多少傳入的字符:
string[] doc1StrArray;
. . .
private int GetCountOfSpecificCharacter(string CharToCount)
{
int count = 0;
count = doc1StrArray.Count(f => f == CharToCount);
return count;
}
...這樣稱呼:
iCountOfCommasInDoc1 = GetCountOfSpecificCharacter(",");
...但它不起作用。 它找不到逗號,例如,在以下情況下,盡管文檔確實包含逗號。
兩者都在工作 - Roman 的建議和 Teroneko 的:
private int GetCountOfSpecificCharacterInDoc1(char CharToCount)
{
return doc1StrArray.Sum(s => s.Count(c => c == CharToCount));
}
private int GetCountOfSpecificCharacterInDoc2(char CharToCount)
{
return doc2StrArray.SelectMany(x => x).Count(c => c == CharToCount);
}
...但我不知道哪個更好/更有效。
private int GetCountOfSpecificCharacter(char charToCount)
{
int count = 0;
foreach (var word in doc1StrArray)
foreach (char character in word)
if (character == charToCount)
count++;
return count;
}
@Jawad 是對的。 您可以執行以下操作來實現您的目標:
var count = doc1StrArray.SelectMany(x => x).Count(c => c == CharToCount);
這將選擇每個數組項中的任何字符並將它們作為一個IEnumerable<char>
返回。 當您知道對其應用.Count(..)
時,您就在對每個字符進行計數。
編輯:我做了一些測試,似乎 for 循環是最快的
public int GetAmountOfChar(string[] strings, char character) {
int amountOfChar = 0;
var linesLength = strings.Length;
for (var lineIndex = 0; lineIndex < linesLength; lineIndex++)
{
var line = TextExample[lineIndex];
var charsLength = line.Length;
for (var charIndex = 0; charIndex < charsLength; charIndex++)
if (line[charIndex] == character)
amountOfChar++;
}
return amountOfChar;
}
但不是 foreach 循環:
[TestSelectManyCount] Found 5861172 characters in 3295,8278ms
[TestForForIncrement] Found 5861172 characters in 377,0376ms
[TestForCount] Found 5861172 characters in 1064,9164ms
[TestForEachWhileIndexOfIncrement] Found 5861172 characters in 1550,894ms
[TestForEachForEachIncrement] Found 5861172 characters in 473,4347ms
[TestSumCounts] Found 5861172 characters in 1062,2644ms
using System;
using System.Diagnostics;
using System.Linq;
namespace StackOverflow._62505315
{
public partial class Program
{
public const char CharToBeFound = 'a';
public const int Iterations = 5000;
static Stopwatch stopWatch = new Stopwatch();
static void Main(string[] args)
{
TestSelectManyCount();
TestForForIncrement();
TestForCount();
TestForEachWhileIndexOfIncrement();
TestForEachForEachIncrement();
TestSumCounts();
}
public static void TestSelectManyCount()
{
var iterations = Iterations;
int amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
amountOfChar += TextExample.SelectMany(x => x).Count(c => c == CharToBeFound);
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestSelectManyCount)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
public static void TestForForIncrement()
{
var iterations = Iterations;
int amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
var linesLength = TextExample.Length;
for (var lineIndex = 0; lineIndex < linesLength; lineIndex++)
{
var line = TextExample[lineIndex];
var charsLength = line.Length;
for (var charIndex = 0; charIndex < charsLength; charIndex++)
if (line[charIndex] == CharToBeFound)
amountOfChar++;
}
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestForForIncrement)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
public static void TestForCount()
{
var iterations = Iterations;
var amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
var lineLength = TextExample.Length;
for (var lineIndex = 0; lineIndex < lineLength; lineIndex++)
{
amountOfChar += TextExample[lineIndex].Count(c => c == CharToBeFound);
}
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestForCount)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
public static void TestForEachWhileIndexOfIncrement()
{
var iterations = Iterations;
var amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
foreach (string word in TextExample)
{
int startIndex = 0;
int charIndex = 0;
while ((charIndex = word.IndexOf(CharToBeFound, startIndex)) != -1)
{
startIndex = charIndex + 1;
amountOfChar++;
}
}
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestForEachWhileIndexOfIncrement)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
public static void TestForEachForEachIncrement()
{
var iterations = Iterations;
int amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
foreach (var word in TextExample)
foreach (char character in word)
if (character == CharToBeFound)
amountOfChar++;
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestForEachForEachIncrement)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
public static void TestSumCounts()
{
var iterations = Iterations;
int amountOfChar = 0;
stopWatch.Start();
checked
{
while (iterations-- >= 0)
{
amountOfChar += TextExample.Sum(s => s.Count(c => c == CharToBeFound));
}
}
stopWatch.Stop();
Console.WriteLine($"[{nameof(TestSumCounts)}] Found {amountOfChar} characters in {stopWatch.Elapsed.TotalMilliseconds}ms");
stopWatch.Reset();
}
}
}
令我驚訝的是,我還在這里找到了一個參考,它強調了一個事實,即 for 循環超出了 foreach 循環
這是一個示例,您可以使用它來迭代字符串數組以檢查字符在字符串中出現的次數,然后將其全部加起來。
string[] test = new string[] {
"This is, the first test string",
"This, is the second, test string",
"this is the, third"};
string inp = ",";
Console.WriteLine(test.Sum(stringItem => stringItem.Count(charItem => charItem.ToString().Equals(inp))));
// Prints 4
在比較期間,您可以將被迭代的字符轉換為字符串以進行正確的string.Equals(string)
比較。 您要將其轉換為字符串的原因是因為字符“a”不等於字符串“a”。 如果要進行字符比較,請參見下面的字符比較方法(但注意字符應與字符進行比較,字符串與字符串進行比較。)。
這可以是你計算的方法,
private int GetCountOfSpecificCharacter(string CharToCount)
{
return doc1StrArray.Sum(stringItem => stringItem.Count(charItem => charItem.ToString().Equals(CharToCount)));
}
// And this one to use for Character Comparisons using `.ToCharArray()` method.
// You can parse each character as well by the use of char.Parse(str)
private int GetCountOfSpecificCharacter(string CharToCount)
{
return test.Sum(stringItem => stringItem.ToCharArray().Count(charItem => charItem.Equals(CharToCount.ToCharArray().First())));
}
或者像這樣
private int GetCountOfSpecificCharacter(string[] doc1StrArray, char charToCount)
{
int count = 0;
count = doc1StrArray.Sum(s => s.Count(c => c == charToCount));
return count;
}
您還可以使用正則表達式:
private int GetCountOfSpecificCharacter(string CharToCount)
{
return Regex.Matches(string.join("", doc1StrArray), CharToCount).Count;
}
您可以使用並行 linq 來實現。
public static int GetBounty(string[] gettysburgLines, char c)
{
int count = 0;
gettysburgLines.AsParallel().ForAll(line => {
int q = line.AsParallel().Where(a => a == c).Count();
count += q;
});
return count;
}
只需使用:
var ad = Array.FindAll(yourArray,u=>u.Equals(passedChar).Length
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.