Загрузите текстовый файл, содержащий 15 чисел, отобразите их и удалите дубликаты VB.net

#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()
  

Попробуйте онлайн