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
This is my code.
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
CodePudding user response:
A Dictionary
provides a convenient entity to store the (digit, count_of_digit) data.
Then you just need to go through all the characters in the file and check if each one is a digit. If it is, then add one to the count_of_digit for that digit.
This is an example using a Console Application:
Imports System.IO
Module Module1
Sub CreateTestFile(s As String)
Dim rand As New Random()
Using sw As New StreamWriter(s)
For i = 1 To 10000
sw.Write(rand.Next(0, 10).ToString())
Next
End Using
End Sub
Function GetNumberFrequencies(s As String) As Dictionary(Of Integer, Integer)
Dim nf As New Dictionary(Of Integer, Integer)
For i = 0 To 9
nf.Add(i, 0)
Next
Using sr As New StreamReader(s)
While Not sr.EndOfStream
Dim line = sr.ReadLine()
For Each c In line
If c >= "0" AndAlso c <= "9" Then
' A quick way to convert the strings "0"-"9" to the numbers 0-9:
Dim index = AscW(c) - AscW("0)")
nf(index) = 1
End If
Next
End While
End Using
Return nf
End Function
Sub Main()
' Always specify a full path to a file that you use.
Dim testFile = "C:\temp\randNums.txt"
CreateTestFile(testFile)
Dim nf = GetNumberFrequencies(testFile)
For Each kvp As KeyValuePair(Of Integer, Integer) In nf
Console.WriteLine(kvp.Key & " - " & kvp.Value)
Next
Console.ReadLine()
End Sub
End Module
Sample output:
0 - 1013
1 - 963
2 - 991
3 - 1033
4 - 1001
5 - 966
6 - 962
7 - 1006
8 - 1018
9 - 1047
CodePudding user response:
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:
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
Console.WriteLine(result.ToString()
End Sub
See it work here:
Note this last skips missing digits.