Search code examples
vb.nettext-filesfrequency

Vb.net how to display the frequency of digits from a text file


I am still studying this stuff and been looking through google and Youtube but there doesn't seem to have this problem for VB.net I saw some on python or Java though. This is the output that I have to get but when i read the text file and try to find the frequency its doesn't go as hoped

enter image description here

This is my code.

enter image description here

Imports System.IO
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click

        Dim reader As TextReader = New StreamReader("number.txt")
        Dim num As Integer = 0

        For Each item In reader.ReadToEnd
            If item.CompareTo(reader.ReadLine) = True Then
                num += 1
            End If

        Next

        rtbshow.Text = "Digit" & " " & " " & " Frequency " & vbNewLine & reader.ReadToEnd() & " " & " " & num

    End Sub
End Class

Solution

  • A dictionary can work for this, but given just the nine digits an indexed array can do just as well and probably be faster.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
        Dim digitCounts = Enumerable.Repeat(0,10).ToArray()
    
        Dim digits = File.ReadAllText("number.txt").
                       Where(Function(c) Char.IsDigit(c)).
                       Select(Function(c) Asc(c) - Asc("0"c))
        For Each d As Integer In digits
            digitCounts(d) += 1
        Next
        Dim result As New StringBuilder($"Digit{vbTab}Frequency{vbCrLf}")
        For i As Integer = 0 To 9
            result.AppendLine($"{i,3}{vbTab}{digitCounts(i),7}")
        Next
        rtbshow.Text = result.ToString()
    End Sub
    

    You can (kind of) see it working here, except I couldn't get .Net fiddle to do the string interpolation:

    https://dotnetfiddle.net/FMWnMg

    We could also solve this with a GroupBy() operation:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
        Dim result As New StringBuilder($"Digit{vbTab}Frequency{vbCrLf}")
        Dim digits = File.ReadAllText("number.txt").
                 Where(Function(c) Char.IsDigit(c)).
                 OrderBy(Function(d) d).
                 GroupBy(Function(d) d, 
                         Function(d, g) $"{d,3}{vbTab}{g.Count(),7}{vbCrLf}"
                 )
        
        For Each d As String in digits
            result.Append(d)
        Next
        rtbshow.Text = result.ToString()
    End Sub
    

    See it work here:

    https://dotnetfiddle.net/Xxl2z3

    Note this last skips missing digits.