сравнение строк в txt с отсевом

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

сравнение строк в txt с отсевом

Сообщение Invader » 06.08.2012 (Пн) 21:09

имеется текстовый файл с набором ссылок, пример строк
photos/83/999/87947/821713_740x550.jpg
photos/83/999/87947/821712_740x550.jpg
photos/83/999/87947/821711_740x550.jpg
photos/83/999/87947/821710_740x550.jpg
photos/83/999/87947/821709_740x550.jpg
photos/83/999/87947/821708_740x550.jpg
photos/83/15/88868/829347_740x550.jpg
photos/83/15/88868/829346_740x550.jpg
photos/83/15/88868/829345_740x550.jpg
photos/83/15/88868/829344_740x550.jpg

цель перебрать строки со сравнением (жирным отмечено) части строк, если найдено сходство отмечаем строку маркером добавляем в начало определённый символ и переходим к поиску следующего сходства и при 4ёх совпадениях останавливаемся, и проверяем сходство по следующему индексу - photos/83/999/87947/ индексов от 0 до 88868.
ну должно получиться так
* photos/83/999/87947/821713_740x550.jpg
* photos/83/999/87947/821712_740x550.jpg
* photos/83/999/87947/821711_740x550.jpg
* photos/83/999/87947/821710_740x550.jpg
photos/83/999/87947/821709_740x550.jpg
photos/83/999/87947/821708_740x550.jpg
* photos/83/15/88868/829347_740x550.jpg
* photos/83/15/88868/829346_740x550.jpg
* photos/83/15/88868/829345_740x550.jpg
* photos/83/15/88868/829344_740x550.jpg

я записал маску обрезав строку
Код: Выделить всё
Dim str1 As String
Dim str2 As String

         
        str1 = "photos/83/15/88868/829338_740x550.jpg" 'ну сюда мы отправляем строку из текст. документа
        str2 = Regex.Match(str1, "(photos/\d+/\d+/\d+/)", RegexOptions.IgnoreCase).Value 'photos/83/15/88868/ - результат для сравнения

понимаю что надо условие проверки кинуть в цикл от 1 до 4, а его в свою очередь поместить в цикл от 0 до 88868
у меня проблема с не пониманием как организовать проверку ?
тут ещё один момент photos/83- здесь может быть 4 значения 100, 83, 71, 12 а
в этом регистре photos/83/15 - от 0 до 9999 как бы упростить задачу, без перебора всех вариантов, да и ещё как правило похожие идут последовательно может как то метить строки вроде первые четыре пометили и переходим к следующей не похожей строке сразу метим её и три последующих и повторяем до конца документа
умён и жаден,
характер отсуствует

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 06.08.2012 (Пн) 22:30

А если нужная строка встречается менее 4х раз - то что с ней надо делать?

Зачем перебирать "ключи" по отдельности, если ты всё равно в итоге сравниваешь всю сроку до последнего слэша? ("photos/83/999/87947/")

Invader писал(а):как правило похожие идут последовательно

"Как правило", или "Так и только так"? Если "как правило" - то этот момент в построении алгоритма учитывать нельзя.

Я бы построчно шёл по файлу, и считал вхождения ключевых частей строк. Например, при помощи словаря (но, возможно, есть и более эффективные решения - я не слишком хорошо знаю .net). Это если нужно маркировать строки даже если их менее 4х. Если нет, то всё немного сложнее, но принцип примерно тот же. Только действовать в два прохода по файлу, например. А если файл не слишком большой, и спокойно помещается в памяти, то можно в один проход, просто дополнительно запоминать номера строк для каждого ключа.
label:
cli
jmp label

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: сравнение строк в txt с отсевом

Сообщение Invader » 06.08.2012 (Пн) 22:49

файл содержит 64047 строк,
какого словаря можно подробнее
строки идут "Так и только так!"
умён и жаден,
характер отсуствует

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 06.08.2012 (Пн) 23:26

http://www.dotnetperls.com/dictionary-vbnet

Соответственно, для случая когда нужно маркировать все строки включая четвёртую (даже если их меньше 4х):
Код: Выделить всё
'Где-то в начале:
Dim dict As New Dictionary(Of String, Integer)
Dim cnt As Integer

'Для каждой строки, key - та часть, по которой нужно сравнивать строки:
If dict.ContainsKey(key) Then cnt = dict.Item(key) + 1 Else cnt = 1
dict.Item(key) = cnt

If cnt <= 4 Then
'маркируем строку
End If

Код писал прямо тут, VB.NET под рукой не имею.

Впрочем, если строки действительно идут "так и только так", и в файле никогда не может встретиться двух "несоседних" строк с одинаковым ключом, то можно написать и более оптимальный алгоритм, который не будет хранить все строки в памяти.
Тогда нужен счётчик и сохранённый "текущий ключ". Отмечаем первую строку, запоминаем ключ, далее для каждой следующей строки получаем ключ, сравниваем с сохранённым, если совпадает - увеличиваем счётчик, проверяем значение счётчика и маркируем строку, если он меньше или равен 4. Если не совпадают - сбрасываем счётчик в 1 и сохраняем новый ключ. И так до конца файла.текущий ключ

Если нужно маркировать только "повторяющиеся" строки, и при этом оставлять немаркированными одиночные, то почти то же самое, только перед тем как маркировать первую строку с новым ключом, забегаем вперёд, проверяя несколько следующих.
label:
cli
jmp label

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: сравнение строк в txt с отсевом

Сообщение Invader » 07.08.2012 (Вт) 1:03

iGrok писал(а):Сообщение iGrok » 06.08.2012 (Пн) 22:26
http://www.dotnetperls.com/dictionary-vbnet

Соответственно, для случая когда нужно маркировать все строки включая четвёртую (даже если их меньше 4х):

Благодарю, сработало как нельзя лучше, я так накрутил, что сначала вышел говн :oops: код ! Но постепенно всё стало так как было нужно
Код: Выделить всё
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions

Public Class Form1
   

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Где-то в начале:
        Dim dict As New Dictionary(Of String, Integer)
        Dim cnt As Integer
        Dim s As String
        Dim o As New System.IO.StreamReader("C:\download\silkfoto.txt")
        Dim key As String
        s = o.ReadLine() 'первое значение для кей
        For i As Integer = 0 To 50 'тут пробегаемся только по первым 50 строчкам
5:          s = o.ReadLine()' здесь подбрасываем новое значение для кей
            key = Regex.Match(s, "(photos/\d+/\d+/\d+/)", RegexOptions.IgnoreCase).Value
            For k As Integer = 1 To 4
                'Для каждой строки, key - та часть, по которой нужно сравнивать строки:
                If dict.ContainsKey(key) Then cnt = dict.Item(key) + 1 Else cnt = 1
                dict.Item(key) = cnt

                If cnt < 5 Then 'тут выдает нужные четыре значения
                    TextBox1.Text += "*" + o.ReadLine() + Chr(13) + Chr(10) 'маркируем строку
                End If
            Next
        Next
        o.Close()
    End Sub
End Class

да, на форму бросаем текстбокс мультилайн и кнопку
умён и жаден,
характер отсуствует

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: сравнение строк в txt с отсевом

Сообщение Invader » 07.08.2012 (Вт) 1:15

да, вот вопрос: сколько строк может сохранить или правильнее отобразить текстбокс, и строковая переменная
умён и жаден,
характер отсуствует

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: сравнение строк в txt с отсевом

Сообщение FireFenix » 07.08.2012 (Вт) 1:49

http://msdn.microsoft.com/en-us/library ... 71%29.aspx

0 to approximately 2 billion Unicode characters.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 07.08.2012 (Вт) 2:23

Ерунда у тебя тут какая-то:
Код: Выделить всё
s = o.ReadLine() ' эту строку ты, по сути, просто пропускаешь, т.к.

For i As Integer = 0 To 50
   
    s = o.ReadLine()    ' вот тут ты сразу же читаешь следующую

    key = Regex.Match(s, "(photos/\d+/\d+/\d+/)", RegexOptions.IgnoreCase).Value
   
    For k As Integer = 1 To 4    ' зачем тут этот цикл?! По сути, ты крутишь следующий цикл 4 раза с одной и той же строкой
        ' в итоге у тебя для любой строки в словаре будет значение не меньше 4.
       
        If dict.ContainsKey(key) Then cnt = dict.Item(key) + 1 Else cnt = 1
        dict.Item(key) = cnt

        If cnt < 5 Then
            TextBox1.Text += "*" + o.ReadLine() + Chr(13) + Chr(10) ' а тут ты просто маркируешь и сразу же выводишь следующие строки даже не проверяя их
        End If
    Next
Next


Как это должно выглядеть (если я правильно понимаю суть задачи):
Код: Выделить всё
's = o.ReadLine() ' эту строка не нужна, закомментируем её.

For i As Integer = 0 To 50
    'читаем строку
    s = o.ReadLine()
                             
    'получаем ключ из строки
    key = Regex.Match(s, "(photos/\d+/\d+/\d+/)", RegexOptions.IgnoreCase).Value   
   
    'увеличиваем значение в словаре (количество совпадений) по ключу и получаем текущее количество
    If dict.ContainsKey(key) Then cnt = dict.Item(key) + 1 Else cnt = 1
    dict.Item(key) = cnt

    'если совпадений менее 5:
    If cnt < 5 Then
        TextBox1.Text += "*" 'добавляем маркер
    End If

    TextBox1.Text += s + Chr(13) + Chr(10) 'добавляем саму строку
Next
label:
cli
jmp label

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.08.2012 (Вт) 7:33

FireFenix писал(а):
0 to approximately 2 billion Unicode characters.

Это для строки. А для TextBox'а - только до 65530, если не ошибаюсь.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.08.2012 (Вт) 9:00

Invader & iGrok писал(а):key = Regex.Match(s, "(photos/\d+/\d+/\d+/)", RegexOptions.IgnoreCase).Value

UPDATE: Не проверяется, что совпадение вообще есть.

Invader писал(а):TextBox1.Text += "*" + o.ReadLine() + Chr(13) + Chr(10)

Маркер ставится не на текущую строку, а на следующию, которая вообще не обрабатывается.

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: сравнение строк в txt с отсевом

Сообщение Invader » 07.08.2012 (Вт) 13:38

Так ну я жертвую первыми двумя строчками это не беда там похожих 13 шт
Qwertiy писал(а): Invader писал(а):TextBox1.Text += "*" + o.ReadLine() + Chr(13) + Chr(10)


Маркер ставится не на текущую строку, а на следующию, которая вообще не обрабатывается.

всё верно в последствии было исправлено на s
iGrok писал(а):Ерунда у тебя тут какая-то:

без цикла он мне выдавал одну строку, подчеркиваю на выходе у меня формируется текстовый фай после проверки которого, я доволен найденными совпадениями , из 10450 идентификаторов в новом документе остаётся 36780 строк
что является подтверждением один индефикатор -четыре строки совпадения, ну а то что их меньше 40 000 говорит о том что не все индефикаторы имеют 4 некоторые 2 или 3 -что визуально подтверждалось.
умён и жаден,
характер отсуствует

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.08.2012 (Вт) 14:30

Invader писал(а):Так ну я жертвую первыми двумя строчками это не беда там похожих 13 шт

???

Invader писал(а):что является подтверждением ...

Если одну и ту же строку повторить 4 раза, то их станет ровно в 4 раза больше. Это очень сложно опровергнуть.
iGrok прав.

PS: Пиши понятно хотя бы вопросы.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 07.08.2012 (Вт) 15:19

Qwertiy писал(а):Маркер ставится...

Я там его кусок кода прокомментировал примерно так же. :)

Invader писал(а):Так...

Просто замени свой кусок кода на мой, и посмотри, что получится.
Конечно, желательно ещё добавить проверки на наличие ключа в строке, о которых пишет Qwertiy.
label:
cli
jmp label

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.08.2012 (Вт) 15:33

iGrok писал(а):Просто замени свой кусок кода на мой, и посмотри, что получится.

Немного не то. Он выводит только помеченные строки, а ты - все :)

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 07.08.2012 (Вт) 16:44

Ну, у меня сделано так, как показано в стартпосте. В любом случае, поправить не долго. :)
label:
cli
jmp label

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re: сравнение строк в txt с отсевом

Сообщение Invader » 07.08.2012 (Вт) 18:06

это похоже на одинаковые строки?:
hotel_photos/12/4/103/271322_740x550.jpg
hotel_photos/12/4/103/271321_740x550.jpg
hotel_photos/12/4/103/271320_740x550.jpg
hotel_photos/12/4/103/271319_740x550.jpg
hotel_photos/12/4/106/293636_740x550.jpg
hotel_photos/12/4/106/293635_740x550.jpg
hotel_photos/12/4/106/293634_740x550.jpg
hotel_photos/12/4/106/293633_740x550.jpg
hotel_photos/12/4/107/630913_740x550.jpg

по маске конечно да, но посмотрите на окончание ссылок
умён и жаден,
характер отсуствует

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.08.2012 (Вт) 18:14

Invader, раз уж у тебя не получается нормальный код, хотя бы посты пиши так, чтобы тебя можно было понять... Я уже вообще не понимаю, чего ты хочешь :(

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: сравнение строк в txt с отсевом

Сообщение iGrok » 07.08.2012 (Вт) 21:07

Invader писал(а):это похоже на одинаковые строки?

Значит ты изменил в коде не только то, о чём тут пишешь. Тогда прекрати вводить народ в заблуждение.
label:
cli
jmp label

Invader
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 285
Зарегистрирован: 18.01.2005 (Вт) 4:22
Откуда: Молдавия, Виноград

Re:

Сообщение Invader » 07.08.2012 (Вт) 21:39

Qwertiy писал(а):Invader, раз уж у тебя не получается нормальный код, хотя бы посты пиши так, чтобы тебя можно было понять... Я уже вообще не понимаю, чего ты хочешь :(

ну за что такое не понимание - в начале я же указал принцип, маркером отмечать первые 4 похожие по индексу , только для того чтоб потом удалить не помеченные , код сработал лучше лишнее сам "отмел" в маркере нужда отпала
суть же проста, в базе выводится только четыре картинки на один уникальный индекс, не зачем из оригинального документа качать 100 картинок на один индекс. я сейчас имею документ на один индекс четыре ссылки фото, мне ещё их надо будет обработать. 30 000 легче, чем с не нужными суммарно 64 000?
тем не менее большое спасибо всем.
умён и жаден,
характер отсуствует


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 37

    TopList