webForumDet fria alternativet

Räkna förekomsten av visst tecken?

.NET

6 svar · 625 visningar · startad av Travoni

Medlem sedan okt. 20041 556 inlägg
Frågan#1

Jag har kommit på två sätt att räkna en viss bokstav/tecken. Finns det någon annan inbyggd .net-funktion för detta?

Dim antal_komman as integer = ListLen("Jag, är, en, ful gris",",")
Dim antal_komman as integer = ListLen2("Jag, är, en, ful gris",",")

Private Function ListLen(ByVal inStr As String, ByVal chr As Char) As Int16
     Return CLng(inStr.Length - inStr.Replace(chr, String.Empty).Length)
End Function

Private Function ListLen2(ByVal inStr As String, ByVal chr As Char) As Int16
     Return CLng(inStr.Split(chr).Length - 1)
End Function
Medlem sedan okt. 20041 556 inlägg
#2

Nu har jag stresstestat båda funktionerna
100 * 100000 ggr vardera alltså 10000000 (Tio miljoner gånger)

Snittiden är något förvånande.

ListLen2
19,54 sek
20,2 sek

ListLen
15,3 sek
15,0 sek

Medlem sedan aug. 20003 575 inlägg
#3
RegEx regEx = new RegEx(@"\,", RegExOptions.Compiled);

MatchCollection matches = regEx.Matches("strängen,,..,.,.,,");

matches.Count
Medlem sedan okt. 20041 556 inlägg
#4

Jag gjorde en liten klass för att testa subbar och funktioner som hittas här:
http://www.webforum.nu/showthread.php?p=1402005
Ganska kul att se resultatet.
Nickemannens variant var bra mycket långsammare...i min uträkning.

Medlem sedan dec. 20025 483 inlägg
#5
Dim total As Int16 = 0
For Each c As Char In inStr
    If c = chr Then total += 1
Next
Return total

...bör ligga med i toppen.

Medlem sedan okt. 20041 556 inlägg
#6

ListLen1: 0,0481759553239308
ListLen2: 0,0493012380065064
ListLen3: 4,18607141410431
ListLen4: 0,046162291576164
Du har rätt, den verkar tom segra! :birp

Sen märkte jag att vb-funktionen CallByName verkar vara en riktig segis, men det skall inte påverka testet för att jämföra de sinsemellan.

Medlem sedan aug. 20003 575 inlägg
#7

Hmm, känner att RegEx blivit lite orättvisst behandlad.

RegEx regEx = new RegEx(@"\,", RegExOptions.Compiled);
får inte ligga i metoden utan måste vara en medlem i klassen annars blir den klart långsammast.
Men den vinner ändå antagligen inte.

Men när det blir mer än ett tecken man skall söka på så tror jag nog att RegularExpressions kan bli snabbare.

Skillnaden blev då..

ListLen1: 0,0369918523164257
ListLen2: 0,0345382583540646
ListLen3: 2,17376412365259
ListLen4: 0,0297156482178601
ListLen5: 0,039174951006343

Där ListLen4 är denna:

    'Räknar förekomsten av kommatecken med regexp
    Private _regEx As Regex = New Regex("\,", RegexOptions.Compiled)

    Public Function ListLen5(ByVal inStr As String, ByVal chr As Char) As Int16
        Return _regEx.Matches(inStr).Count
    End Function

Även om det inte slår dom första 2 alternativen. Men som sagt är det fler tecken så tror jag denna sopar mattan med de andra :). Eller om det skall vara ett tecken som t.ex. A som också kan vara ett litet a.

262 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
125 ms — deklarationer (db)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)
126 ms — ändringar (db)