У меня есть несколько имен файлов в списке под названием данных. Я хочу прочитать содержимое файла и проверить, появляется ли данный файл (пример - оранжевый) в файле. Мои имена файлов добавляются в список в последовательном порядке, т. Е. Если данный текст «оранжевый» появляется в файле pi.txt (индекс 2), он будет присутствовать во всех файлах и после индекса 2, и конечно же, я хочу получить индекс или имя файла, где текст «оранжевый» появился первым.

У меня есть более тысячи файлов в списке, поэтому я хочу использовать бинарный поиск.

data = ['ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt']
target = "orange"

def binary_search(a, x):
    lo = 0
    hi = len(a)

    while lo < hi:
        mid = (lo + hi) // 2

        if not x in open(a[mid]).read():
            lo = mid + 1
        elif x in open(a[mid]).read():
            hi = mid
        elif mid > 0 and x in open(a[mid-1]).read():
            hi = mid
        else:
            return mid

    return -1

print(binary_search(data, target))



$ cat ae.txt
papaya
guava

$ cat ac.txt 
mango
durian
papaya
guava

$ cat pi.txt 
orange
papaya
guava

$ cat ad.txt 
orange
papaya
guava

$ cat mm.txt 
orange
papaya
guava

$ cat ab.txt 
orange
papaya
guava
1
Sun 26 Июн 2019 в 14:16

3 ответа

Лучший ответ

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

data = ['ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt']
target = "orange"

def binary_search(a, x):
    lo = 0
    hi = len(a)

    while lo < hi:
        mid = (lo + hi) // 2
        print(mid)
        if not x in open(a[mid]).read():
            lo = mid + 1

        elif x in open(a[mid]).read():
            hi = mid
        if lo == hi:
            return lo

        print("low : {}; high : {}".format(lo,hi))

    return -1
index = binary_search(data, target)
print("The index where we first found the word orange is {}, the file name is {}".format(index,data[index]))

The index where we first found the word orange is 2, the file name is pi.txt
1
vlemaistre 26 Июн 2019 в 12:05

Ваш бинарный поиск на самом деле не ищет равенства, поэтому его можно немного упростить:

def binary_search(files, string):
    lo,hi  = 0,len(files)-1
    while hi>=lo:
        mid     = (hi+lo)//2
        if string in open(files[mid]).read(): 
            hi = mid-1
        else: 
            lo = mid+1
    return lo

Поскольку проверка равенства не выполняется, hi и lo выполнят условие остановки (hi>=lo), в котором точка lo будет указана в индексе первого совпадения или в { {X4}} если совпадений нет.

1
Alain T. 26 Июн 2019 в 12:41

Бинарный поиск по файлам работает только в том случае, если ваши файлы уже отсортированы по ключу поиска, который вы используете, а это означает, что файл X [n + 1] не должен иметь данных, лексикографически меньших, чем файл X [n]. В этом случае вам придется вручную просматривать каждый файл до тех пор, пока вы не пройдете тщательный анализ всех файлов ... или не создадите файл словаря следующим образом:

'ae.txt', 'ac.txt', 'pi.txt', 'ad.txt', 'mm.txt', 'ab.txt'
durian 1
guava 0-5
mango 1
orange 2-5
papaya 0-5

Первая строка обозначает включенные файлы и дает им индексы посредством позиционирования (например, «ae.txt» находится в позиции 0). Другие строки обозначают индексы файлов, которые включают каждое слово.

Отсюда вы можете прочитать первую строку для имен файлов, выполнить двоичный поиск по строкам, чтобы найти слово, которое вы ищете (хотя вы, вероятно, должны найти способ прочитать определенную строку в O (1) - или поместите их в отдельные файлы словаря, например, для отдельных букв, если их слишком много). Затем определите, обозначен ли индекс имени файла (его расположение в первой строке) в строке слова.

Создание кода, который записывает исходный файл и, соответственно, обновляет его, кажется достаточно простым, но я могу помочь вам в этом, если хотите.

0
Dorijan Cirkveni 26 Июн 2019 в 12:04