#vb.net
#vb.net
Вопрос:
Как указано в названии, дополнительно я должен рядом с ними отображать число, в котором это число изначально появилось в тексте file…so если число появилось в первой строке файла .txt и десятой рядом с этим выводом, должно быть показано 1,10.
Пока это код, который я написал.
Даже написание решения на c # было бы полезно, потому что я могу его преобразовать.
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileReader As StreamReader
Dim results As DialogResult
Dim OpenFileDialog1 As New OpenFileDialog()
results = OpenFileDialog1.ShowDialog
If results = DialogResult.OK Then
FileReader = New StreamReader(OpenFileDialog1.FileName)
textBox1.Text = FileReader.ReadToEnd()
FileReader.Close()
End If
End Sub
End Class
Комментарии:
1. Было бы очень полезно, если бы вы могли показать нам образец файла.
2. ` 12 3 14 5 1 3 6 7 89 12 33 55 97 41 64 ` В основном сверху вниз
3. Значит, каждая строка имеет значение? Как в строке 1 содержится 12, строка 2 содержит 3 и т. Д.?
4. @John да, это правильно
5. Итак, в вашем примере будут ли номера строк 1 2 3 4 5 7 и т. Д. пропускать 6, потому что 6-я строка является дубликатом?
Ответ №1:
Вы можете прочитать файл в массив с помощью:
Dim lines = IO.File.ReadAllLines("path")
Вы можете выполнить итерацию по массиву с помощью цикла For, который знает номер строки:
For lineNumber = 0 To lines.Length-1
Вы можете создать Dictionary(Of String, Integer)
файл, в котором будут храниться значение и номер строки, но только в том случае, если значение ранее не просматривалось:
Dim d as New Dictionary(Of String, Integer)
For ....
Dim line = lines(lineNumber)
If Not d.ContainsKey(line) Then d(line) = lineNumber 1 ' plus one because arrays number from 0 but you seem to want first line numbered as 1
В процессе перечисления цикла словарь будет заполняться уникальными ключами и номером строки, которые они впервые увидели
Вы можете перечислить словарь и распечатать его:
For Each kvp as KeyValuePair in d
'if the file first line was "10 then
Console.WriteLine(kvp.Key) 'prints e.g. "10"
Console.WriteLine(kvp.Value) 'prints e.g. 1
Я не писал код для вас, потому что это действительно похоже на домашнее задание, но попробуйте — все, что вам нужно, здесь
ps; Все это в значительной степени можно сделать в одной строке с помощью LINQ.. Что-то вроде:
IO.File.ReadAllLines(path) _
.Select(Function(s,x) New With {.S = s, .X = x})
.GroupBy(Function(w) w.S) _
.Select(Function(g) $"{g.Key},{g.First()}")
Но если это домашнее задание, определенно не сдавайте его!
Комментарии:
1. «итак, если число появилось в первой строке файла .txt, а десятое рядом с этим выводом должно отображаться 1,10». Поскольку у нас есть ПОВТОРЯЮЩИЕСЯ строки (возможно, более двух, кто знает?), Не
Dictionary(Of String, List(Of Integer))
было бы лучше, Чтобы мы могли отслеживать ВСЕ строки, в которых это значение имело место? Таким образом, у вас будетunique line value
плюсlist of all lines where unique line value occurred
.2. Я думал упомянуть об этом, но в конце концов мои склонности «ответить на заданный вопрос» превзошли его. В этом вопросе действительно есть что-то вроде базового компьютерного программирования 101 «введение в словари / HashWhatevers», и когда я даю указатели на домашние задания, я, как правило, просто придерживаюсь того, что есть — я знаю, что если кто-то передаст что-то, чего они не понимают, тогда на их голове, но имеяСловарь списков был слишком простым переходом на территорию «я попросил кого-то другого написать это».. Оставаясь в стороне от него, он не рискует быть включенным, потому что OP не смог удалить
3. Все, что сказано, версия LINQ концептуально эквивалентна тому, что вы рекомендуете, с игрогруппировкой, чтобы вы могли сказать, что «это там для любопытных» 😀
Ответ №2:
Обратите внимание, что я обрабатываю строки как строки, а не числа. Надеюсь, это подходит для ваших целей.
Я бы использовал HashSet
для этого. Это позволит вам быстро и легко проверить, было ли значение уже просмотрено.
Далее мы можем ввести переменную для подсчета номера строки и чтения файла построчно, а не все сразу:
Dim line As String
Dim row as integer
Dim seenSet As New HashSet(Of string)()
do
line = FileReader.ReadLine()
if line is nothing then
exit do
end if
row = row 1
loop while not (line is nothing)
Теперь мы можем добавить line
значение в seenSet
using seenSet.Add(line)
. Если он возвращается true
, то у нас есть новая запись, если он возвращается false
, то это тот, который мы видели раньше:
// add this code inside the loop and directly below row = row 1
if seenSet.Add(line) then
Console.WriteLine(CStr(line) " " CStr(row))
end if
Теперь будет выведено значение строки, пробел и номер строки.
Если вам нужно собрать его в одну строку для отображения в текстовом поле, мы можем ввести StringBuilder
// Declare this before the loop (along with your other variables)
Dim result As New StringBuilder()
// Replace Console.WriteLine
result.AppendLine(CStr(line) " " CStr(row))
// After the `loop while` line
textBox1.Text = result.ToString()
В итоге вы должны получить это:
Dim line As String
Dim row as integer
Dim seenSet As New HashSet(Of string)()
Dim result As New StringBuilder()
do
line = FileReader.ReadLine()
if line is nothing then
exit do
end if
row = row 1
if seenSet.Add(line) then
result.AppendLine(CStr(line) " " CStr(row))
end if
loop while not (line is nothing)
textBox1.Text = result.ToString()