คุณจะนับเหตุการณ์ที่เกิดขึ้นของสตริง (จริง ๆ อักขระถ่าน) ภายในสตริงได้อย่างไร


864

ฉันกำลังทำสิ่งที่ฉันรู้ว่าฉันต้องการนับจำนวน /ที่ฉันสามารถหาได้ในสตริงและจากนั้นก็ทำให้ฉันหลงว่ามีหลายวิธีที่จะทำ แต่ไม่สามารถตัดสินใจได้ว่าสิ่งที่ดีที่สุด (หรือง่ายที่สุด) คืออะไร .

ในขณะนี้ฉันจะไปกับสิ่งที่ชอบ:

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;

34
+1: ฉันต้องบอกว่ามันเป็นวิธีที่แตกต่างกันมากในการนับ ฉันประหลาดใจที่ผลการทดสอบเครื่องหมายมาตรฐาน :)
naveen

4
มันไม่ได้แตกต่างกันดังนั้น ... มันเป็นวิธีการทั่วไปที่จะใช้ฟังก์ชันนี้ใน LEN(ColumnToCheck) - LEN(REPLACE(ColumnToCheck,"N",""))SQL:
Sheridan

6
ตามความจริงแล้วคุณควรหารด้วย "/".Length
Gerard

3
ฉันขอถามสิ่งที่คุณต้องการจะบอกว่าการนับควรเป็นจำนวนการเกิดของ "//" ภายใน "/////" 2 หรือ 4
Les

1
ใช้ regex น่าจะเป็นวิธีที่ดีที่สุดที่จะไปเกี่ยวกับเรื่องนี้
Adam Higgins

คำตอบ:


1009

หากคุณใช้. NET 3.5 คุณสามารถทำได้ด้วยการซับในด้วย LINQ:

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

หากคุณไม่ต้องการใช้ LINQ คุณสามารถทำได้ด้วย:

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

คุณอาจประหลาดใจที่รู้ว่าเทคนิคดั้งเดิมของคุณดูเหมือนจะเร็วกว่าประมาณ 30%! ฉันเพิ่งทำเกณฑ์มาตรฐานอย่างรวดเร็วด้วย "/ ครั้ง / เมื่อ / a / เวลา /" และผลลัพธ์มีดังนี้:

ต้นฉบับของคุณ = 12s
source.Count = 19s
source.Split = 17s
foreach ( จากคำตอบของ bobwienholt ) = 10s

(เวลาสำหรับการทำซ้ำ 50,000,000 ครั้งดังนั้นคุณไม่น่าจะสังเกตเห็นความแตกต่างมากมายในโลกแห่งความเป็นจริง)


6
ใช่ VS ซ่อนวิธีการขยาย LINQ ไว้ในคลาสสตริง ฉันคิดว่าพวกเขาคิด devs จะไม่ต้องการวิธีการขยายเหล่านั้นทั้งหมดที่จะแสดงในชั้นเรียนสตริง อาจเป็นการตัดสินใจที่ชาญฉลาด
Judah Gabriel Himango เมื่อ

11
อาจเป็นไปได้ว่าพฤติกรรมนี้เป็นเพราะ VS2010 รวม System.Linq โดยอัตโนมัติในไฟล์คลาสใหม่ VS2008 อาจไม่ เนมสเปซจำเป็นต้องอยู่ภายในเพื่อให้ระบบ Intellisense ทำงานได้
Sprague

30
โปรดทราบว่าโซลูชันการนับและแยกจะใช้งานได้เมื่อคุณนับจำนวนอักขระเท่านั้น พวกเขาจะไม่ทำงานกับสตริงเช่นเดียวกับวิธีแก้ปัญหาของ OP
Peter Lillevold

5
f == '\' เป็นเรื่องเกี่ยวกับตัวอักษรในสตริงไม่ใช่สตริงในสตริง
Thomas Weller

9
ดูเหมือนว่าคำตอบของคำถามอื่น: "คุณจะนับจำนวนอักขระภายในสตริงได้อย่างไร"
Ben Aaronson

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

จะต้องมีความรวดเร็วกว่าsource.Replace()โดยตัวของมันเอง


18
คุณสามารถปรับปรุงส่วนเพิ่มได้โดยเปลี่ยนเป็น for for แทนที่จะเป็น foreach แต่มีขนาดเล็กนิดหน่อย
ทำเครื่องหมาย

17
ไม่คำถามขอให้นับการปรากฏของสตริงไม่ใช่อักขระ
YukiSakura

3
นี่คือการนับตัวอักษรในสตริง หัวข้อเป็นเรื่องเกี่ยวกับการนับสตริงในสตริง
Thomas Weller

2
@ Mark เพียงแค่ทดสอบด้วย for for loop และมันช้ากว่าการใช้ foreach อาจเป็นเพราะการตรวจสอบขอบเขต? (เวลาคือ 1.65 วินาทีเทียบกับ 2.05 ในการทำซ้ำ 5 ล้านครั้ง)
วัด

4
ในขณะที่คำถามกำลังถามหาสตริงภายในสตริงตัวอย่างปัญหา OP ที่โพสต์จริง ๆ แล้วเป็นเพียงตัวละครตัวหนึ่งซึ่งในกรณีนี้ฉันจะเรียกคำตอบนี้ว่ายังคงเป็นคำตอบที่ถูกต้องเพราะมันแสดงวิธีที่ดีกว่า เพื่อแก้ไขปัญหาที่อยู่ในมือ
ชาด

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

8
1 - RegexOptions.IgnoreCaseในบางกรณีคุณอาจต้องการเพิ่ม
TrueWill

3
นี่มันต่ำอย่างไม่น่าเชื่อเหรอ?
โทมัส Ayoub

4
ค่าใช้จ่าย Regex ไม่เหมาะรวมทั้ง "ฉันไม่ต้องการขุด RegEx สำหรับสิ่งนี้ฉันควรทำอย่างไร"
ชาด

อาจไม่ต้องการRegex.Escape(...)เช่นนั้นnew System.Text.RegularExpressions.Regex(needle).Matches(haystack).Count;
barlop

2
ฉันไปกับอันนี้เพราะมันสามารถค้นหาสตริงไม่ใช่แค่ตัวละคร
James ใน Indy

86

หากคุณต้องการค้นหาสตริงทั้งหมดไม่ใช่เฉพาะอักขระ:

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

อ่านเป็น "สำหรับอักขระแต่ละตัวในสตริงใช้เวลาที่เหลือของสตริงเริ่มต้นจากอักขระนั้นเป็นสตริงย่อยให้นับถ้ามันเริ่มต้นด้วยสตริงเป้าหมาย"


1
ไม่แน่ใจว่าฉันสามารถอธิบายได้ชัดเจนกว่าคำอธิบายที่ให้ไว้ ความสับสนคืออะไร
mqp

58
สุดช้า! พยายามใช้หน้า html และใช้เวลาประมาณ 2 นาทีเหมือนกับวิธีอื่น ๆ ในหน้านี้ซึ่งใช้เวลา 2 วินาที คำตอบนั้นถูกต้อง มันช้าเกินไปที่จะใช้งานได้
JohnB

2
ตกลงช้าเกินไป ฉันเป็นแฟนตัวยงของโซลูชั่นแบบ linq แต่อันนี้ไม่สามารถทำงานได้
Sprague

5
โปรดทราบว่าสาเหตุที่ทำให้ช้ามากคือสร้างสตริงขึ้นมาดังนั้นจึงจัดสรรประมาณ n ^ 2/2 ไบต์
Peter Crabtree

6
OutOfMemoryException ถูกส่งออกไปสำหรับสตริง 210000 ตัวอักษรของฉัน
สิ้นสุด

66

ฉันได้ทำการวิจัยแล้วและพบว่าโซลูชันของ Richard Watsonนั้นเร็วที่สุดในเกือบทุกกรณี นั่นคือตารางที่มีผลลัพธ์ของทุกโซลูชันในโพสต์ (ยกเว้นที่ใช้Regexเพราะมันจะส่งข้อยกเว้นขณะแยกสตริงเช่น "test {test")

    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|

คุณจะเห็นว่าในกรณีของการค้นหาจำนวนที่เกิดขึ้นของสตริงย่อยสั้น (1-5 ตัวอักษร) ในสตริงสั้น (10-50 ตัวอักษร) ควรใช้อัลกอริทึมดั้งเดิม

สำหรับสตริงย่อยแบบหลายตัวคุณควรใช้รหัสต่อไปนี้ (ขึ้นอยู่กับโซลูชันของ Richard Watson )

int count = 0, n = 0;

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

ฉันกำลังจะเพิ่มโซลูชัน 'ระดับต่ำ' ของตัวเอง (โดยไม่ต้องสร้างสตริงย่อยโดยใช้แทนที่ / แยกหรือ Regex / Linq ใด ๆ ) แต่คุณอาจจะดีกว่าของฉัน (และอย่างน้อยก็สั้น) ขอบคุณ!
Dan W

สำหรับโซลูชันของ Regex ให้เพิ่มในRegex.Escape(needle)
Thymine

2
เพียงเพื่อชี้ให้คนอื่น ๆ ค่าการค้นหาจำเป็นต้องตรวจสอบว่าว่างเปล่ามิฉะนั้นคุณจะเข้าสู่วงวนไม่สิ้นสุด
WhoIsRich

2
อาจเป็นเพียงฉัน แต่สำหรับsource="aaa" substring="aa"ฉันคาดว่าจะได้รับคืน 2 ไม่ใช่ 1 เพื่อ "แก้ไข" สิ่งนี้เปลี่ยนn += substring.Lengthเป็นn++
ytoledano

คุณสามารถเพิ่มoverlappedธงเพื่อตอบสนองกรณีของคุณเช่นนี้:overlapped=True;.... if(overlapped) {++n;} else {n += substring.Length;}
tsionyx

54

LINQ ใช้งานได้กับคอลเลกชันทั้งหมดและเนื่องจากสตริงเป็นเพียงคอลเล็กชันของตัวละครวิธีการเกี่ยวกับซับในตัวนี้:

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

ตรวจสอบให้แน่ใจว่าคุณusing System.Linq;อยู่ที่ด้านบนสุดของไฟล์รหัสเช่นเดียวกับ.Countวิธีการขยายจากเนมสเปซนั้น


5
มันคุ้มค่าที่จะใช้ var ที่นั่นไหม? มีโอกาสใดที่ Count จะถูกแทนที่ด้วยบางสิ่งที่ไม่ส่งคืน int?
Whatsit

69
@Watsit: คุณสามารถพิมพ์ 'var' ด้วยมือซ้ายของคุณในขณะที่ 'int' ต้องใช้มือทั้งสองข้าง);
Sean Bright

7
intตัวอักษรทั้งหมดอยู่ในปุ่มโฮมขณะที่varไม่ เอ่อ .. ฉันกำลังใช้ Dvorak
Michael Buen

2
@BDotA ตรวจสอบให้แน่ใจว่าคุณมี 'using System.Linq;' ที่ด้านบนของไฟล์ของคุณ นอกจากนี้ IntelliSense อาจซ่อนการโทรออกจากคุณเนื่องจากเป็นสตริง ถึงกระนั้นมันก็จะรวบรวมและรันได้ดี
ยูดาห์กาเบรียล Himango

3
@JudahGabrielHimango ฉันจะยืนยันว่า var ควรใช้โดยเฉพาะอย่างยิ่งเมื่อประเภทตัวแปรที่เห็นได้ชัด (และสำหรับความกะทัดรัดและความมั่นคง)
EriF89

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

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

บนคอมพิวเตอร์ของฉันเร็วกว่าโซลูชันตัวละครสำหรับทุกตัวอักษรประมาณ 2 วินาทีสำหรับการทำซ้ำ 50 ล้านครั้ง

การแก้ไข 2013:

เปลี่ยนสตริงเป็นถ่าน [] แล้ววนซ้ำไปเรื่อย ๆ ตัดวินาทีหรือสองวินาทีถัดจากเวลาทั้งหมดซ้ำ 50m!

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

ฉันสงสัยว่าทำไมสิ่งนี้อาจเป็นและเป็น Googling ไปรอบ ๆ (ฉันจำบางสิ่งเกี่ยวกับการวนซ้ำแบบย้อนกลับที่เร็วขึ้น) และมาที่คำถาม SO นี้ซึ่งใช้เทคนิคสตริงเพื่อถ่าน [] อย่างน่ารำคาญ ฉันคิดว่าเคล็ดลับการพลิกกลับเป็นสิ่งใหม่ในบริบทนี้

วิธีที่เร็วที่สุดในการวนซ้ำผ่านตัวละครแต่ละตัวในสตริงใน C # คืออะไร?


1
คุณสามารถใส่source.IndexOf('/', n + 1)และสูญเสียn++และวงเล็บของในขณะที่ :) นอกจากนี้ให้ใส่ตัวแปรstring word = "/"แทนตัวละคร
neeKo

1
เฮ้ Niko เช็คเอาต์คำตอบใหม่ อาจเป็นเรื่องยากที่จะสร้างสตริงย่อยที่มีความยาวผันแปรได้
Richard Watson

ฉันใช้สิ่งที่คล้ายกันโดยก้าวผ่านการลบ จนกว่าฉันจะรู้ว่า indexOf มี startIndex ฉันชอบวิธีแก้ปัญหาแรกมากที่สุดเนื่องจากมีความสมดุลที่ดีระหว่างความเร็วและหน่วยความจำรอยเท้า
Samir Banjanovic

1
ฉันอ่านบางที่มันเร็วกว่าที่จะย้ำถอยหลังเพราะมันเร็วกว่าที่จะเปรียบเทียบค่ากับ 0
reggaeguitar

1
@ shitpoet yup หากคุณดูที่รหัสอ้างอิงมันเป็นสายพื้นเมือง ถ่านสาธารณะ [] toCharArray () {... System.arraycopy (ค่า, 0, ผลลัพธ์, 0, value.length); ... }
Richard Watson

46

ทั้งสองนี้ใช้ได้เฉพาะกับคำค้นหาอักขระเดียว ...

countOccurences("the", "the answer is the answer");

int countOccurences(string needle, string haystack)
{
    return (haystack.Length - haystack.Replace(needle,"").Length) / needle.Length;
}

อาจจะดีกว่าสำหรับเข็มที่ยาวกว่า ...

แต่จะต้องมีวิธีที่สวยงามกว่า :)


เพื่อบัญชีสำหรับการเปลี่ยนหลายตัวละคร โดยไม่ได้นับ "ว่า" ใน "การทดสอบเป็นกุญแจสำคัญ" จะกลับมา 6.
ZombieSheep

เปรียบเทียบและเปรียบเทียบกับสตริงแยกทาง - ทำงานได้เร็วขึ้นประมาณ 1.5 เท่า ความรุ่งโรจน์
Alex

20

แก้ไข:

source.Split('/').Length-1

2
นี่คือสิ่งที่ฉันทำ และsource.Split(new[]{"//"}, StringSplitOptions.None).Count - 1สำหรับตัวคั่นหลายตัว
bzlm

4
สิ่งนี้จะดำเนินการอย่างน้อย n การจัดสรรสตริงบนฮีปบวกกับ (อาจจะ) มีการปรับขนาดอาร์เรย์อีกสองสามครั้ง - และทั้งหมดนี้เพียงเพื่อให้ได้จำนวน? ไม่มีประสิทธิภาพมากขนาดไม่ดีและไม่ควรใช้ในรหัสที่สำคัญใด ๆ
Zar Shardan

17

ใน C # ตัวนับสตริง SubString ที่ดีคือเพื่อนที่ไม่คาดคิด:

public static int CCount(String haystack, String needle)
{
    return haystack.Split(new[] { needle }, StringSplitOptions.None).Length - 1;
}

1
วิธีแก้ปัญหาที่ดี - และทำงานกับสายอักขระด้วยเช่นกัน (ไม่ใช่แค่ตัวอักษร)!
ChriPf

ขอบคุณมันง่ายเกินไปที่จะลืมรายละเอียดปลีกย่อยบางส่วนของการจัดการสายอักขระเมื่อทำการสลับภาษา - เช่นเดียวกับพวกเราส่วนใหญ่ในทุกวันนี้!
เดฟ

1
-1 เนื่องจาก: คุณรู้จักความแตกต่างระหว่าง Count () และ Count หรือ Length หรือไม่ หากมีคนใช้ Count () แทน Count หรือ Length ฉันได้รับการกระตุ้น Count () สร้าง IEnumerator จากนั้นไปถึงเหตุการณ์ที่เกิดขึ้นทั้งหมดของ IEnumerable ในขณะที่ Count หรือ Length ได้ตั้งค่าคุณสมบัติของวัตถุที่มีการนับจำนวนที่คุณต้องการโดยไม่จำเป็นต้องวนซ้ำองค์ประกอบทั้งหมด
aeroson

จุดที่ดีและสิ่งที่แปลกคือในห้องสมุดของฉันจากที่ฉันใช้ฟังก์ชั่นฉันใช้ "ความยาว" แก้ไข!
เดฟ

15
Regex.Matches(input,  Regex.Escape("stringToMatch")).Count

1
สิ่งนี้ไม่ถูกต้องหากป้อนอักขระพิเศษ regex regaint input เช่น | จะต้องมี Regex.Escape (อินพุต)
Esben Skov Pedersen

1
ที่จริงความต้องการหลบหนีไม่ได้stringToMatch input
Theodor Zoulias

ใช่คุณ ซ่อมมัน.
cederlof

13
private int CountWords(string text, string word) {
    int count = (text.Length - text.Replace(word, "").Length) / word.Length;
    return count;
}

เนื่องจากโซลูชันดั้งเดิมเป็นวิธีที่เร็วที่สุดสำหรับตัวอักษรฉันคิดว่ามันจะเป็นสตริง ดังนั้นนี่คือผลงานของฉัน

สำหรับบริบท: ฉันกำลังมองหาคำเช่น 'ล้มเหลว' และ 'ประสบความสำเร็จ' ในล็อกไฟล์

Gr, Ben


2
อย่าส่งสตริงว่างสำหรับตัวแปร "word" (หารด้วยศูนย์ข้อผิดพลาด)
แอนดรูเจนส์

12
string s = "65 fght 6565 4665 hjk";
int count = 0;
foreach (Match m in Regex.Matches(s, "65"))
  count++;

20
หรือ Regex.Matches (s, "65") นับ ^ _ ^
Meta

ใช้งานไม่ได้กับทุกสตริง ลองค้นหา "++" ใน "abc ++ def ++ xyz"
marsh-wiggle

7

สำหรับทุกคนที่ต้องการวิธีการขยาย String แบบพร้อมใช้งาน

นี่คือสิ่งที่ฉันใช้ซึ่งมาจากคำตอบที่ดีที่สุดที่โพสต์:

public static class StringExtension
{    
    /// <summary> Returns the number of occurences of a string within a string, optional comparison allows case and culture control. </summary>
    public static int Occurrences(this System.String input, string value, StringComparison stringComparisonType = StringComparison.Ordinal)
    {
        if (String.IsNullOrEmpty(value)) return 0;

        int count    = 0;
        int position = 0;

        while ((position = input.IndexOf(value, position, stringComparisonType)) != -1)
        {
            position += value.Length;
            count    += 1;
        }

        return count;
    }

    /// <summary> Returns the number of occurences of a single character within a string. </summary>
    public static int Occurrences(this System.String input, char value)
    {
        int count = 0;
        foreach (char c in input) if (c == value) count += 1;
        return count;
    }
}

วิธีที่สองจะไม่เฟื่องฟูถ้าสตริงที่ส่งผ่านนั้นว่างเปล่าหรือเปล่า? จากมุมมองของสไตล์คุณจะกำหนดอินพุตเป็น System.String แทนที่จะเป็นเพียงสตริงเท่านั้น
Nodoid

7
public static int GetNumSubstringOccurrences(string text, string search)
{
    int num = 0;
    int pos = 0;

    if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(search))
    {
        while ((pos = text.IndexOf(search, pos)) > -1)
        {
            num ++;
            pos += search.Length;
        }
    }
    return num;
}

5

ฉันคิดว่าวิธีที่ง่ายที่สุดในการทำเช่นนี้คือการใช้นิพจน์ปกติ วิธีนี้คุณจะได้รับจำนวนการแบ่งเท่ากันกับที่คุณสามารถใช้ myVar.Split ('x') แต่ในการตั้งค่าอักขระจำนวนมาก

string myVar = "do this to count the number of words in my wording so that I can word it up!";
int count = Regex.Split(myVar, "word").Length;

3
string search = "/string";
var occurrences = (regex.Match(search, @"\/")).Count;

สิ่งนี้จะนับทุกครั้งที่โปรแกรมค้นหา "/ s" (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) และจำนวนครั้งของสิ่งนี้จะถูกเก็บไว้ในตัวแปร "การเกิดขึ้น"


3

ฉันรู้สึกว่าเราขาดการนับจำนวนสตริงย่อยเช่นการเปรียบเทียบไบต์ที่ไม่ปลอดภัยต่อไบต์ ฉันรวบรวมวิธีดั้งเดิมของโปสเตอร์และวิธีการต่าง ๆ ที่ฉันนึก

นี่คือส่วนขยายสตริงที่ฉันทำ

namespace Example
{
    using System;
    using System.Text;

    public static class StringExtensions
    {
        public static int CountSubstr(this string str, string substr)
        {
            return (str.Length - str.Replace(substr, "").Length) / substr.Length;
        }

        public static int CountSubstr(this string str, char substr)
        {
            return (str.Length - str.Replace(substr.ToString(), "").Length);
        }

        public static int CountSubstr2(this string str, string substr)
        {
            int substrlen = substr.Length;
            int lastIndex = str.IndexOf(substr, 0, StringComparison.Ordinal);
            int count = 0;
            while (lastIndex != -1)
            {
                ++count;
                lastIndex = str.IndexOf(substr, lastIndex + substrlen, StringComparison.Ordinal);
            }

            return count;
        }

        public static int CountSubstr2(this string str, char substr)
        {
            int lastIndex = str.IndexOf(substr, 0);
            int count = 0;
            while (lastIndex != -1)
            {
                ++count;
                lastIndex = str.IndexOf(substr, lastIndex + 1);
            }

            return count;
        }

        public static int CountChar(this string str, char substr)
        {
            int length = str.Length;
            int count = 0;
            for (int i = 0; i < length; ++i)
                if (str[i] == substr)
                    ++count;

            return count;
        }

        public static int CountChar2(this string str, char substr)
        {
            int count = 0;
            foreach (var c in str)
                if (c == substr)
                    ++count;

            return count;
        }

        public static unsafe int CountChar3(this string str, char substr)
        {
            int length = str.Length;
            int count = 0;
            fixed (char* chars = str)
            {
                for (int i = 0; i < length; ++i)
                    if (*(chars + i) == substr)
                        ++count;
            }

            return count;
        }

        public static unsafe int CountChar4(this string str, char substr)
        {
            int length = str.Length;
            int count = 0;
            fixed (char* chars = str)
            {
                for (int i = length - 1; i >= 0; --i)
                    if (*(chars + i) == substr)
                        ++count;
            }

            return count;
        }

        public static unsafe int CountSubstr3(this string str, string substr)
        {
            int length = str.Length;
            int substrlen = substr.Length;
            int count = 0;
            fixed (char* strc = str)
            {
                fixed (char* substrc = substr)
                {
                    int n = 0;

                    for (int i = 0; i < length; ++i)
                    {
                        if (*(strc + i) == *(substrc + n))
                        {
                            ++n;
                            if (n == substrlen)
                            {
                                ++count;
                                n = 0;
                            }
                        }
                        else
                            n = 0;
                    }
                }
            }

            return count;
        }

        public static int CountSubstr3(this string str, char substr)
        {
            return CountSubstr3(str, substr.ToString());
        }

        public static unsafe int CountSubstr4(this string str, string substr)
        {
            int length = str.Length;
            int substrLastIndex = substr.Length - 1;
            int count = 0;
            fixed (char* strc = str)
            {
                fixed (char* substrc = substr)
                {
                    int n = substrLastIndex;

                    for (int i = length - 1; i >= 0; --i)
                    {
                        if (*(strc + i) == *(substrc + n))
                        {
                            if (--n == -1)
                            {
                                ++count;
                                n = substrLastIndex;
                            }
                        }
                        else
                            n = substrLastIndex;
                    }
                }
            }

            return count;
        }

        public static int CountSubstr4(this string str, char substr)
        {
            return CountSubstr4(str, substr.ToString());
        }
    }
}

ตามด้วยรหัสทดสอบ ...

static void Main()
{
    const char matchA = '_';
    const string matchB = "and";
    const string matchC = "muchlongerword";
    const string testStrA = "_and_d_e_banna_i_o___pfasd__and_d_e_banna_i_o___pfasd_";
    const string testStrB = "and sdf and ans andeians andano ip and and sdf and ans andeians andano ip and";
    const string testStrC =
        "muchlongerword amuchlongerworsdfmuchlongerwordsdf jmuchlongerworijv muchlongerword sdmuchlongerword dsmuchlongerword";
    const int testSize = 1000000;
    Console.WriteLine(testStrA.CountSubstr('_'));
    Console.WriteLine(testStrA.CountSubstr2('_'));
    Console.WriteLine(testStrA.CountSubstr3('_'));
    Console.WriteLine(testStrA.CountSubstr4('_'));
    Console.WriteLine(testStrA.CountChar('_'));
    Console.WriteLine(testStrA.CountChar2('_'));
    Console.WriteLine(testStrA.CountChar3('_'));
    Console.WriteLine(testStrA.CountChar4('_'));
    Console.WriteLine(testStrB.CountSubstr("and"));
    Console.WriteLine(testStrB.CountSubstr2("and"));
    Console.WriteLine(testStrB.CountSubstr3("and"));
    Console.WriteLine(testStrB.CountSubstr4("and"));
    Console.WriteLine(testStrC.CountSubstr("muchlongerword"));
    Console.WriteLine(testStrC.CountSubstr2("muchlongerword"));
    Console.WriteLine(testStrC.CountSubstr3("muchlongerword"));
    Console.WriteLine(testStrC.CountSubstr4("muchlongerword"));
    var timer = new Stopwatch();
    timer.Start();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountSubstr(matchA);
    timer.Stop();
    Console.WriteLine("CS1 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrB.CountSubstr(matchB);
    timer.Stop();
    Console.WriteLine("CS1 and: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrC.CountSubstr(matchC);
    timer.Stop();
    Console.WriteLine("CS1 mlw: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountSubstr2(matchA);
    timer.Stop();
    Console.WriteLine("CS2 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrB.CountSubstr2(matchB);
    timer.Stop();
    Console.WriteLine("CS2 and: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrC.CountSubstr2(matchC);
    timer.Stop();
    Console.WriteLine("CS2 mlw: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountSubstr3(matchA);
    timer.Stop();
    Console.WriteLine("CS3 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrB.CountSubstr3(matchB);
    timer.Stop();
    Console.WriteLine("CS3 and: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrC.CountSubstr3(matchC);
    timer.Stop();
    Console.WriteLine("CS3 mlw: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountSubstr4(matchA);
    timer.Stop();
    Console.WriteLine("CS4 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrB.CountSubstr4(matchB);
    timer.Stop();
    Console.WriteLine("CS4 and: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrC.CountSubstr4(matchC);
    timer.Stop();
    Console.WriteLine("CS4 mlw: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountChar(matchA);
    timer.Stop();
    Console.WriteLine("CC1 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountChar2(matchA);
    timer.Stop();
    Console.WriteLine("CC2 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountChar3(matchA);
    timer.Stop();
    Console.WriteLine("CC3 chr: " + timer.Elapsed.TotalMilliseconds + "ms");

    timer.Restart();
    for (int i = 0; i < testSize; ++i)
        testStrA.CountChar4(matchA);
    timer.Stop();
    Console.WriteLine("CC4 chr: " + timer.Elapsed.TotalMilliseconds + "ms");
}

ผลลัพธ์: CSX สอดคล้องกับ CountSubstrX และ CCX สอดคล้องกับ CountCharX "chr" ค้นหาสตริงสำหรับ '_', "และ" ค้นหาสตริงสำหรับ "และ" และ "mlw" ค้นหาสตริงสำหรับ "muchlongerword"

CS1 chr: 824.123ms
CS1 and: 586.1893ms
CS1 mlw: 486.5414ms
CS2 chr: 127.8941ms
CS2 and: 806.3918ms
CS2 mlw: 497.318ms
CS3 chr: 201.8896ms
CS3 and: 124.0675ms
CS3 mlw: 212.8341ms
CS4 chr: 81.5183ms
CS4 and: 92.0615ms
CS4 mlw: 116.2197ms
CC1 chr: 66.4078ms
CC2 chr: 64.0161ms
CC3 chr: 65.9013ms
CC4 chr: 65.8206ms

และในที่สุดฉันก็มีไฟล์ที่มี 3.6 ล้านตัวอักษร มันคือ "derp adfderdserp dfaerpderp deasderp" ซ้ำ 100,000 ครั้ง ฉันค้นหา "derp" ในไฟล์ด้วยวิธีการด้านบน 100 ครั้งผลลัพธ์เหล่านี้

CS1Derp: 1501.3444ms
CS2Derp: 1585.797ms
CS3Derp: 376.0937ms
CS4Derp: 271.1663ms

ดังนั้นวิธีที่ 4 ของฉันคือผู้ชนะแน่นอน แต่ถ้าหากไฟล์ตัวอักษร 3.6 ล้านตัว 100 ครั้งใช้เวลาเพียง 1586 มิลลิวินาทีเท่านั้นในกรณีที่แย่กว่านั้นทั้งหมดนี้ก็ค่อนข้างเล็กน้อย

โดยวิธีการที่ฉันยังสแกนสำหรับอักขระ 'd' ในไฟล์ 3.6 ล้านตัวอักษรด้วยวิธีการนับ 100 CountSubstr และ CountChar ผล...

CS1  d : 2606.9513ms
CS2  d : 339.7942ms
CS3  d : 960.281ms
CS4  d : 233.3442ms
CC1  d : 302.4122ms
CC2  d : 280.7719ms
CC3  d : 299.1125ms
CC4  d : 292.9365ms

วิธีการโพสต์ต้นฉบับไม่ดีมากสำหรับเข็มตัวละครตัวเดียวในกองหญ้าขนาดใหญ่ตามนี้

หมายเหตุ: ค่าทั้งหมดได้รับการอัพเดตเป็นเอาต์พุตเวอร์ชัน Release ฉันลืมสร้างในโหมด Release โดยไม่ตั้งใจในครั้งแรกที่ฉันโพสต์สิ่งนี้ ข้อความบางส่วนของฉันได้รับการแก้ไข


ขอบคุณสำหรับผลการปฏิบัติงาน ปัจจัยที่แตกต่างกันในความเร็ว 10 อาจเป็นเหตุผลที่จะไม่พิจารณา linq หรือวิธีการเขียนที่เป็นระเบียบอื่น ๆ แต่ไปด้วยวิธีการขยาย
Andreas Reiff

2

ฟังก์ชั่นทั่วไปสำหรับการเกิดขึ้นของสตริง:

public int getNumberOfOccurencies(String inputString, String checkString)
{
    if (checkString.Length > inputString.Length || checkString.Equals("")) { return 0; }
    int lengthDifference = inputString.Length - checkString.Length;
    int occurencies = 0;
    for (int i = 0; i < lengthDifference; i++) {
        if (inputString.Substring(i, checkString.Length).Equals(checkString)) { occurencies++; i += checkString.Length - 1; } }
    return occurencies;
}

2
สิ่งนี้สร้างสตริงชั่วคราวจำนวนมากและทำให้ตัวรวบรวมขยะทำงานหนักมาก
EricLaw

2
string source = "/once/upon/a/time/";
int count = 0, n = 0;
while ((n = source.IndexOf('/', n) + 1) != 0) count++;

ความแตกต่างของคำตอบของ Richard Watson เร็วขึ้นเล็กน้อยด้วยการปรับปรุงประสิทธิภาพยิ่งมีอักขระเกิดขึ้นในสตริงมากขึ้นและใช้รหัสน้อยลง!

แม้ว่าฉันต้องบอกว่าโดยไม่ต้องทดสอบอย่างครอบคลุมทุกสถานการณ์ฉันก็เห็นการปรับปรุงความเร็วที่สำคัญมากโดยใช้:

int count = 0;
for (int n = 0; n < source.Length; n++) if (source[n] == '/') count++;

2
            var conditionalStatement = conditionSetting.Value;

            //order of replace matters, remove == before =, incase of ===
            conditionalStatement = conditionalStatement.Replace("==", "~").Replace("!=", "~").Replace('=', '~').Replace('!', '~').Replace('>', '~').Replace('<', '~').Replace(">=", "~").Replace("<=", "~");

            var listOfValidConditions = new List<string>() { "!=", "==", ">", "<", ">=", "<=" };

            if (conditionalStatement.Count(x => x == '~') != 1)
            {
                result.InvalidFieldList.Add(new KeyFieldData(batch.DECurrentField, "The IsDoubleKeyCondition does not contain a supported conditional statement. Contact System Administrator."));
                result.Status = ValidatorStatus.Fail;
                return result;
            }

จำเป็นต้องทำสิ่งที่คล้ายกับการทดสอบคำสั่งแบบมีเงื่อนไขจากสตริง

แทนที่สิ่งที่ฉันกำลังค้นหาด้วยอักขระเดี่ยวและนับอินสแตนซ์ของอักขระเดี่ยว

เห็นได้ชัดว่าตัวละครเดียวที่คุณใช้จะต้องมีการตรวจสอบเพื่อไม่ให้มีอยู่ในสตริงก่อนที่จะเกิดเหตุการณ์นี้เพื่อหลีกเลี่ยงการนับที่ไม่ถูกต้อง


2

สตริงในสตริง:

ค้นหา "etc" ใน ".. JD JD JD JD และอื่น ๆ JDJDJDJDJDJDJDJDJD และอื่น ๆ "

var strOrigin = " .. JD JD JD JD etc. and etc. JDJDJDJDJDJDJDJD and etc.";
var searchStr = "etc";
int count = (strOrigin.Length - strOrigin.Replace(searchStr, "").Length)/searchStr.Length.

ตรวจสอบประสิทธิภาพก่อนที่จะยกเลิกอันนี้เป็น unsound / เงอะงะ ...


2

การเริ่มต้นของฉันทำให้ฉันชอบ:

public static int CountOccurrences(string original, string substring)
{
    if (string.IsNullOrEmpty(substring))
        return 0;
    if (substring.Length == 1)
        return CountOccurrences(original, substring[0]);
    if (string.IsNullOrEmpty(original) ||
        substring.Length > original.Length)
        return 0;
    int substringCount = 0;
    for (int charIndex = 0; charIndex < original.Length; charIndex++)
    {
        for (int subCharIndex = 0, secondaryCharIndex = charIndex; subCharIndex < substring.Length && secondaryCharIndex < original.Length; subCharIndex++, secondaryCharIndex++)
        {
            if (substring[subCharIndex] != original[secondaryCharIndex])
                goto continueOuter;
        }
        if (charIndex + substring.Length > original.Length)
            break;
        charIndex += substring.Length - 1;
        substringCount++;
    continueOuter:
        ;
    }
    return substringCount;
}

public static int CountOccurrences(string original, char @char)
{
    if (string.IsNullOrEmpty(original))
        return 0;
    int substringCount = 0;
    for (int charIndex = 0; charIndex < original.Length; charIndex++)
        if (@char == original[charIndex])
            substringCount++;
    return substringCount;
}

เข็มในวิธีการกองฟางโดยใช้การแทนที่และการหารให้เวลา 21+ วินาทีโดยใช้เวลาประมาณ 15.2

แก้ไขหลังจากเพิ่มบิตซึ่งจะเพิ่ม substring.Length - 1ไปยัง charIndex (อย่างที่ควรจะเป็น) เวลา 11.6 วินาที

แก้ไข 2: ฉันใช้สตริงที่มี 26 อักขระสองตัวต่อไปนี้เป็นเวลาที่ได้รับการปรับปรุงเป็นข้อความตัวอย่างเดียวกัน:

เข็มในกองหญ้า (เวอร์ชั่นของ OP): 7.8 วินาที

กลไกที่แนะนำ: 4.6 วินาที

แก้ไข 3: การเพิ่มมุมตัวอักษรเดียวมันไป 1.2 วินาที

แก้ไข 4: สำหรับบริบท: มีการใช้ซ้ำ 50 ล้านครั้ง


2

คิดว่าฉันจะโยนวิธีการขยายของฉันลงในแหวน (ดูความคิดเห็นสำหรับข้อมูลเพิ่มเติม) ฉันไม่ได้ทำเครื่องหมายอย่างเป็นทางการ แต่ฉันคิดว่ามันจะต้องเร็วมากสำหรับสถานการณ์ส่วนใหญ่

แก้ไข: ตกลง - ดังนั้นคำถามนี้ทำให้ฉันสงสัยว่าประสิทธิภาพของการใช้งานในปัจจุบันของเราจะซ้อนทับกับโซลูชั่นที่นำเสนอที่นี่ได้อย่างไร ฉันตัดสินใจที่จะทำเครื่องหมายบนม้านั่งเล็ก ๆ น้อย ๆ และพบว่าวิธีการแก้ปัญหาของเรานั้นสอดคล้องกับประสิทธิภาพของโซลูชั่นที่จัดทำโดยRichard Watsonขึ้นจนกว่าคุณจะทำการค้นหาเชิงรุกด้วยสตริงขนาดใหญ่ (100 Kb +) สตริงย่อยขนาดใหญ่ (32 Kb + ) และการทำซ้ำหลายครั้งในตัว (10K +) ณ จุดนั้นทางออกของเราอยู่ที่ประมาณ 2X ถึง 4X ช้ากว่า จากสิ่งนี้และความจริงที่ว่าเราชอบโซลูชันที่นำเสนอโดย Richard Watson เราได้ปรับแก้ปัญหาของเราใหม่ตามนั้น ฉันแค่อยากทำให้มันเป็นแบบนี้สำหรับทุกคนที่อาจได้รับประโยชน์จากมัน

โซลูชันดั้งเดิมของเรา:

    /// <summary>
    /// Counts the number of occurrences of the specified substring within
    /// the current string.
    /// </summary>
    /// <param name="s">The current string.</param>
    /// <param name="substring">The substring we are searching for.</param>
    /// <param name="aggressiveSearch">Indicates whether or not the algorithm 
    /// should be aggressive in its search behavior (see Remarks). Default 
    /// behavior is non-aggressive.</param>
    /// <remarks>This algorithm has two search modes - aggressive and 
    /// non-aggressive. When in aggressive search mode (aggressiveSearch = 
    /// true), the algorithm will try to match at every possible starting 
    /// character index within the string. When false, all subsequent 
    /// character indexes within a substring match will not be evaluated. 
    /// For example, if the string was 'abbbc' and we were searching for 
    /// the substring 'bb', then aggressive search would find 2 matches 
    /// with starting indexes of 1 and 2. Non aggressive search would find 
    /// just 1 match with starting index at 1. After the match was made, 
    /// the non aggressive search would attempt to make it's next match 
    /// starting at index 3 instead of 2.</remarks>
    /// <returns>The count of occurrences of the substring within the string.</returns>
    public static int CountOccurrences(this string s, string substring, 
        bool aggressiveSearch = false)
    {
        // if s or substring is null or empty, substring cannot be found in s
        if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(substring))
            return 0;

        // if the length of substring is greater than the length of s,
        // substring cannot be found in s
        if (substring.Length > s.Length)
            return 0;

        var sChars = s.ToCharArray();
        var substringChars = substring.ToCharArray();
        var count = 0;
        var sCharsIndex = 0;

        // substring cannot start in s beyond following index
        var lastStartIndex = sChars.Length - substringChars.Length;

        while (sCharsIndex <= lastStartIndex)
        {
            if (sChars[sCharsIndex] == substringChars[0])
            {
                // potential match checking
                var match = true;
                var offset = 1;
                while (offset < substringChars.Length)
                {
                    if (sChars[sCharsIndex + offset] != substringChars[offset])
                    {
                        match = false;
                        break;
                    }
                    offset++;
                }
                if (match)
                {
                    count++;
                    // if aggressive, just advance to next char in s, otherwise, 
                    // skip past the match just found in s
                    sCharsIndex += aggressiveSearch ? 1 : substringChars.Length;
                }
                else
                {
                    // no match found, just move to next char in s
                    sCharsIndex++;
                }
            }
            else
            {
                // no match at current index, move along
                sCharsIndex++;
            }
        }

        return count;
    }

และนี่คือทางออกที่แก้ไขของเรา:

    /// <summary>
    /// Counts the number of occurrences of the specified substring within
    /// the current string.
    /// </summary>
    /// <param name="s">The current string.</param>
    /// <param name="substring">The substring we are searching for.</param>
    /// <param name="aggressiveSearch">Indicates whether or not the algorithm 
    /// should be aggressive in its search behavior (see Remarks). Default 
    /// behavior is non-aggressive.</param>
    /// <remarks>This algorithm has two search modes - aggressive and 
    /// non-aggressive. When in aggressive search mode (aggressiveSearch = 
    /// true), the algorithm will try to match at every possible starting 
    /// character index within the string. When false, all subsequent 
    /// character indexes within a substring match will not be evaluated. 
    /// For example, if the string was 'abbbc' and we were searching for 
    /// the substring 'bb', then aggressive search would find 2 matches 
    /// with starting indexes of 1 and 2. Non aggressive search would find 
    /// just 1 match with starting index at 1. After the match was made, 
    /// the non aggressive search would attempt to make it's next match 
    /// starting at index 3 instead of 2.</remarks>
    /// <returns>The count of occurrences of the substring within the string.</returns>
    public static int CountOccurrences(this string s, string substring, 
        bool aggressiveSearch = false)
    {
        // if s or substring is null or empty, substring cannot be found in s
        if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(substring))
            return 0;

        // if the length of substring is greater than the length of s,
        // substring cannot be found in s
        if (substring.Length > s.Length)
            return 0;

        int count = 0, n = 0;
        while ((n = s.IndexOf(substring, n, StringComparison.InvariantCulture)) != -1)
        {
            if (aggressiveSearch)
                n++;
            else
                n += substring.Length;
            count++;
        }

        return count;
    }

1
string Name = "Very good nice one is very good but is very good nice one this is called the term";
bool valid=true;
int count = 0;
int k=0;
int m = 0;
while (valid)
{
    k = Name.Substring(m,Name.Length-m).IndexOf("good");
    if (k != -1)
    {
        count++;
        m = m + k + 4;
    }
    else
        valid = false;
}
Console.WriteLine(count + " Times accures");

1
string s = "HOWLYH THIS ACTUALLY WORKSH WOWH";
int count = 0;
for (int i = 0; i < s.Length; i++)
   if (s[i] == 'H') count++;

มันจะตรวจสอบตัวละครทุกตัวในสตริงถ้าตัวละครนั้นเป็นตัวละครที่คุณกำลังค้นหาให้เพิ่มอีกหนึ่งตัวเพื่อนับ


1

หากคุณตรวจสอบหน้าเว็บนี้ 15 วิธีในการทำเช่นนี้เป็นเกณฑ์มาตรฐานรวมถึงการใช้ลูปแบบขนาน

วิธีที่เร็วที่สุดดูเหมือนจะใช้เธรด for-loop แบบเธรดเดียว (ถ้าคุณมี. Net version <4.0) หรือ parallel.for loop (ถ้าใช้. Net> 4.0 พร้อมเช็คหลายพัน)

สมมติว่า "ss" เป็นสตริงการค้นหาของคุณ "ch" เป็นอาร์เรย์อักขระของคุณ (ถ้าคุณมีอักขระมากกว่าหนึ่งตัวที่คุณกำลังมองหา) นี่คือส่วนสำคัญพื้นฐานของรหัสที่มีเธรดเวลาทำงานเร็วที่สุด:

for (int x = 0; x < ss.Length; x++)
{
    for (int y = 0; y < ch.Length; y++)
    {
        for (int a = 0; a < ss[x].Length; a++ )
        {
        if (ss[x][a] == ch[y])
            //it's found. DO what you need to here.
        }
    }
}

ซอร์สโค้ดมาตรฐานมีให้ด้วยเพื่อให้คุณสามารถเรียกใช้การทดสอบของคุณเอง


1
str="aaabbbbjjja";
int count = 0;
int size = str.Length;

string[] strarray = new string[size];
for (int i = 0; i < str.Length; i++)
{
    strarray[i] = str.Substring(i, 1);
}
Array.Sort(strarray);
str = "";
for (int i = 0; i < strarray.Length - 1; i++)
{

    if (strarray[i] == strarray[i + 1])
    {

        count++;
    }
    else
    {
        count++;
        str = str + strarray[i] + count;
        count = 0;
    }

}
count++;
str = str + strarray[strarray.Length - 1] + count;

นี่คือการนับจำนวนอักขระที่เกิดขึ้น ตัวอย่างผลลัพธ์นี้จะเป็น "a4b4j3"


2
ไม่ใช่ 'การนับที่เกิดขึ้นของสตริง' จำนวนตัวอักษรที่นับได้มากขึ้น - วิธีที่จะระบุว่าสตริงที่จะจับคู่คือ Narenda อย่างไร
Paul Sullivan

1
int count = 0; string str = "เรามี foo และ foo โปรดนับ foo ในสิ่งนี้"; string stroccurance = "foo"; string [] strarray = str.Split (''); Array.Sort (strArray); str = ""; สำหรับ (int i = 0; i <strarray.Length - 1; i ++) {ถ้า (strarray [i] == stroccurance) {count ++; }} str = "จำนวนที่ใช้สำหรับ" + stroccurance + "คือ" + count; ด้วยวิธีนี้คุณสามารถนับการปรากฎของสตริงใด ๆ ในตัวอย่างนี้ฉันนับการปรากฎของ "foo" และมันจะให้ผลลัพธ์ที่ 3
Narendra Kumar

1

สำหรับกรณีของตัวคั่นสตริง (ไม่ใช่สำหรับกรณี char ตามที่หัวเรื่องระบุไว้):
string source = "@@@ ครั้งหนึ่ง @@@ @ @ @ @ @ @
int count = source.Split (ใหม่ [] {"@@@"}, StringSplitOptions.RemoveEmptyEntries) ความยาว - 1;

โปสเตอร์ต้นฉบับมีค่าตัวคั่นธรรมชาติ ("/ ครั้ง / เมื่อ / a / เวลา /") เป็นอักขระ '/' และคำตอบจะอธิบายตัวเลือก source.Split (char []) แต่ ...


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.