Страница: 1 | 2 |
|
Вопрос: ВОПРОС к EROS'у!!!!!!
|
Добавлено: 08.06.06 20:19
|
|
Номер ответа: 16 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #16
|
Добавлено: 28.06.06 16:47
|
'VS 2005
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Button1_Click( ByVal sender As System. Object, ByVal e As System.EventArgs) Handles Button1.Click
'// Создай на рабочем столе текстовый файл с твоими
'// строками (с дубликатами) под именем "ZXCtest.txt"
Const messageTitle As String = "Find & remove duplicates"
'// Получаем путь к файлу
Dim filePath As String = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, _
"ZXCtest.txt"
'// Проверка на наличие файла по указанному пути
If Not File.Exists(filePath) Then
Dim errorMessage As String = String.Format("File '{0}'{1}not found!", filePath, vbNewLine)
MessageBox.Show(errorMessage, messageTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return
End If
'// Объявляем коллекцию
Dim dataLines As ArrayList
Try
'// Задаем кодировку файла.. (иначе не увидишь русских букв)
Dim currentEncoding As Encoding = System.Text.Encoding.Default
'// Читаем файл с указанием кодировки и заполняем
'// коллекцию строками из файла
dataLines = New ArrayList(File.ReadAllLines(filePath, currentEncoding))
Catch ex As Exception
'// Обрабатываем ошибки
MessageBox.Show(ex.Message, messageTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return
End Try
'// Проверка на то, что файл не пустой
If dataLines.Count = 0 Then
Dim errorMessage As String = String.Format("File '{0}'{1}is empty!", filePath, vbNewLine)
MessageBox.Show(errorMessage, messageTitle, MessageBoxButtons.OK, MessageBoxIcon.Information)
Return
End If
'// ОСНОВНАЯ ЧАСТЬ
'// Поскольку во время работы цикла у нас будут удаляться
'// строки, то свойство dataLines.Count будет постоянно
'// меняться. А это значит, что мы НЕ можем использовать
'// цикл вида For Each ... Next, так как изменение кол-ва
'// элементов коллекции будет вызывать ошибку. Обычно, в
'// таких случаях используют цикл вида:
'// For I as Int32 = dataLines.Count-1 To 0 Step -1
'// Что позволяет начать поиск с последнего элемента и
'// избежать возникновение этой ошибки. Я предлагаю НЕ
'// привязываться к свойству Count коллекции и использовать
'// цикл вида Do ... Loop
'// Индекс текущей строки, который позволит нам
'// определить конец коллекции
Dim currentIndex As Int32 = 0
'// Это первый цикл, который просто перебирает строки
'// от первой до последней
Do
'// Это стартовая позиция поиска. Делаем её на еденицу больше
'// относительно текущей позиции строки.
'// К примеру: Ищем строку 5 НАЧИНАЯ со строки 6
Dim startSearch As Int32 = currentIndex + 1
'// Это индекс найденной строки
Dim searchIndex As Int32
'// Берем из коллекции текущую строку
Dim searchLine As String = dataLines(currentIndex)
'// Это второй цикл. В котором непосредственно и происходит
'// поиск и удаление дубликатов текущей строки
Do
'// Ищем этекущую строчку НАЧИНАЯ со стартовой позиции поиска
'// Если строка найдена, то IndexOf вернет индекс этой строки
'// который будет больше, либо равен нулю. Если же нет, то вернет -1
searchIndex = dataLines.IndexOf(searchLine, startSearch)
'// Если совпадение найдено, то ...
If searchIndex <> -1 Then
'// удаляем эту строчку из коллекции
dataLines.RemoveAt(searchIndex)
'// Для ускорения поиска смещаем позицию начала поиска
'// и делаем ее равной индексу только что найденной строки
'// К примеру: Мы имеем 100 строк. Ищем строку 27 начиная
'// с позиции 28. И находим совпадение в строке 64
'// По логике вещей, следующий поиск мы должны начать со
'// строки 65, НО!!! после удаления, та строка которая была 65,
'// станет 64-й... А если мы этого не сделаем, то поиск опять
'// начнется со строки 28, что сам понимаешь, будет большой
'// глупостью. Хочу отметить, что на больших файлах
'// этот прием даст существенный выигрыш во времени..
startSearch = searchIndex
End If
'// Продолжаем цикл до тех пор, пока НЕ будет найдено совпадений
'// т.е. удаляем ВСЕ строки совпадающие с текущей
Loop While searchIndex >= 0
'// Переходим на следущую строчку
currentIndex += 1
'// Продолжаем цикл до тех пор, пока не достигнем последней строки
Loop While currentIndex < dataLines.Count
'// После работы этого кода в коллекции dataLines
'// остануться только по 1 экземпляру строк
'// И дальше уже можешь делать с коллекцией что угодно
'// Выгрузить в массив, записать обратно в файл и т.д......
End Sub
End Class
Ответить
|
Номер ответа: 18 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #18
|
Добавлено: 28.06.06 19:45
|
протестил вроде пашет
А ты сомневался????
вообщем хочу сделать так: сначало обработать файл этим кодом, а потом тем
это бред... ты выполнишь кучу лишних телодвижений.. все должно быть в 1 процедуре..
вот как записать результат работы кода?
ничего никуда писать не надо... до тех пор, пока задача не будет выполнена полностью
надо dataLines в String переводить?
ничего переводить не надо.. продолжай работать с коллекцией..
и правельно ли я понял, что после работы этого кода в переменной dataLines будет уже отсортированный от дубликатов содержание файла в котором искали?
понял ты правильно, с небольшой поправкой.. список никто НЕ сортировал.. он в первозданном виде,только без дубликатов..
у меня все записи местами переворачиваються
Если необходимо сохранить последовательность строк, то цикл For Each ... Next замени на обычный For ... Next
поэтому и решил сделать 2 разные программы
даже не думай...
Ответить
|
Номер ответа: 19 Автор ответа: ZXC
Вопросов: 30 Ответов: 106
|
Профиль | | #19
|
Добавлено: 28.06.06 21:50
|
записать обратно в файл и т.д......
я немогу записать в файл! если записываю так
Using myFileStream As New IO.FileStream("C:\Documents and Settings\ZXC\Рабочий стол\1234.txt", IO.FileMode.Create)
Dim myStreamWriter As New IO.StreamWriter(myFileStream)
myStreamWriter.Write(result)
myStreamWriter.Close()
End Using
Мне пишет в файл вот что:
System.Collections.ArrayList
Как записать в файл то? я имею ввиду результат как записать в файл?...
Ответить
|
Номер ответа: 20 Автор ответа: ZXC
Вопросов: 30 Ответов: 106
|
Профиль | | #20
|
Добавлено: 28.06.06 21:52
|
блин не то скопировал, вместо
myStreamWriter.Write(result)
Я делал
myStreamWriter.Write(dataLines)
Ответить
|
Номер ответа: 21 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #21
|
Добавлено: 28.06.06 22:34
|
Using myFileStream As New IO.FileStream("C:\Documents and Settings\ZXC\Рабочий стол\1234.txt", IO.FileMode.Create)
  im myStreamWriter As New IO.StreamWriter(myFileStream)
myStreamWriter.Write(result)
myStreamWriter.Close()
End Using
))))))) вот насмешил... спасибо!!!
Кто тебя так учил файлы писать???
Ответить
|
Номер ответа: 22 Автор ответа: EROS
Вопросов: 58 Ответов: 4255
|
Профиль | | #22
|
Добавлено: 28.06.06 22:35
|
' VS 2005
Imports System.IO
Public Class Form1
'// Массив искомых цифр
Private sourceLines() As String
Private Sub Form1_Load( ByVal sender As System. Object, ByVal e As System.EventArgs) Handles MyBase.Load
'// ------------------- ЗАГЛУШКИ -------------------
'// Реальные данные будешь брать из файлов
sourceLines = New String() {"7", _
"12", _
"57"}
'// Массив строк в котором осуществляется поиск ( WITH DUPLICATES )
Dim dataLines() As String = New String() {"9 вал", _
"Али-баба и 40 разбойников", _
"12 обезьян", _
"1001 ночь", _
"7 красавиц и чудовище ZXC", _
"Белоснежка и 7 гномов", _
"12 обезьян", _
"9 вал", _
"12 обезьян", _
"1001 ночь", _
"7 красавиц и чудовище ZXC", _
"Белоснежка и 7 гномов", _
"12 обезьян", _
"9 вал", "12 обезьян", _
"1001 ночь", _
"7 красавиц и чудовище ZXC", _
"Белоснежка и 7 гномов", _
"12 обезьян", _
"9 вал", _
"7 красавиц и чудовище ZXC"}
'// ------------------- ОСНОВНОЙ КОД -------------------
'// Удаляем дубликаты
Dim arrayData As New ArrayList(dataLines)
Dim currentIndex As Int32 = 0
Do
Dim startSearch As Int32 = currentIndex + 1
Dim searchIndex As Int32
Dim searchLine As String = dataLines(currentIndex)
Do
searchIndex = arrayData.IndexOf(searchLine, startSearch)
If searchIndex <> -1 Then
arrayData.RemoveAt(searchIndex)
startSearch = searchIndex
End If
Loop While searchIndex >= 0
currentIndex += 1
Loop While currentIndex < arrayData.Count
'// Смотрим что осталось в коллекции
PrintResult(arrayData) '// MUST BE DELETE !!!
'// 9 вал
'// Али-баба и 40 разбойников
'// 12 обезьян
'// 1001 ночь
'// 7 красавиц и чудовище ZXC
'// Белоснежка и 7 гномов
'// ДУБЛИКАТОВ НЕТ
'// Возвращаем данные в исходный массив строк
dataLines = arrayData.ToArray( GetType( String))
'// Через делегата ищем все строки содержащие любое из значений sourceLines
dataLines = Array.FindAll(dataLines, AddressOf ExistsWord)
'// Смотрим что из всего этого получилось
PrintResult(dataLines) '// MUST BE DELETE !!!
'// 12 обезьян
'// 7 красавиц и чудовище ZXC
'// Белоснежка и 7 гномов
'// Теперь в массиве dataLines содержаться строки,
'// удовлетворяющие твоему условию
'// МОЖЕШЬ ПИСАТЬ ИХ НА HDD
'// Задаем путь к файлу
Dim filePath As String = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, _
"Results.txt"
Try
File.WriteAllLines(filePath, dataLines, System.Text.Encoding.Default)
Catch ex As Exception
'// Обрабатываем ошибки
MessageBox.Show(ex.Message, "ZXC", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End Sub
'// ByVal match As System.Predicate(Of T)
Private Function ExistsWord( ByVal Line As String) As Boolean
For Each searchWord As String In sourceLines
If Line.Contains(searchWord) Then Return True
Next
Return False
End Function
Private Sub PrintResult( ByVal Lines As System.Collections.ICollection)
'// MUST BE DELETE !!!
'// Вспомогательная процедура для контроля данных
'// Выводит содержимое ICollection в окно Output
'//
For Each Line As String In Lines
Console.WriteLine(" '// " & Line)
Next
Console.WriteLine( String.Empty)
End Sub
End Class
Ответить
|
Страница: 1 | 2 |
Поиск по форуму