2014-02-11 3 views
0

У меня есть список стран в отдельном файле (countries.txt), и мне нужно сделать двоичный поиск, чтобы найти страну, и для этого указать информацию, предоставленную на ней.Двоичный поиск имени

Мой файл:

Afghanistan, 647500.0, 25500100 

Albania, 28748.0, 2821977 

Algeria, 2381740.0, 38700000 

American Samoa, 199.0, 55519 

Andorra, 468.0, 76246 

Angola, 1246700.0, 20609294 

Если бы я хотел, чтобы найти площадь и население для Албании, и я поставил getCountry(Albania) в раковине, как бы я это утверждать предоставленную информацию?

меня это до сих пор ...

def getCountry(key): 

    start = "%s" #index 
    end = len("%s")-1 #index 
    while start<=end: 
     mid = (start + end)/2 
     if '%s'[mid] == key: #found it! 
      return True 
     elif "%s"[mid] > key: 
      end = mid -1 
     else: 
      start = mid + 1 
    #end < start 
    return False 
+2

Это можно сделать в 'O (1)' время, если вы храните данные в словаре и используете имя страны в качестве ключа. –

+0

Im новое к этому. Как сохранить файл в словаре, а затем использовать его – user3207521

+0

Я подозреваю, что его для назначения, которое требует двоичного поиска ... –

ответ

0

Как Ashwini предложил в своем комментарии, вы можете использовать словарь в Python. Это будет выглядеть примерно так:

countries = {'Afghanistan': (647500.0, 25500100), 

    'Albania': (28748.0, 2821977), 

    'Algeria': (2381740.0, 38700000), 

    'American Samoa': (199.0, 55519), 

    'Andorra': (468.0, 76246), 

    'Angola': (1246700.0, 20609294)} 

print countries['Angola'][0] 

Вы можете узнать больше о dictionary и tuple от this python documentation

+0

Я бы +1, в биении, если вы построили Dict из текстового файла: P –

0

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

with open("countries.txt") as f: 
    #filter(none,a_list) will remove all falsey values (empty strings/lists/etc) 
    #map(some_function,a_list) will apply a function to all elements in a list and return the results as a new list 
    #in this case the iterable we are handing in as a_list is an open file handle and we are spliting each line on "," 
    country_list = filter(None,map(lambda x:x.split(","),f)) 

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

для того, чтобы сделать бинарный поиск вы сделать что-то вроде (рекурсивную версию)

def bin_search(a_sorted_list,target): 
    mid_pt = len(a_sorted_list) // 2 
    if target < a_sorted_list[mid_pt]: 
     return bin_search(a_sorted_list[:mid_pt], target) 
    elif target > a_sorted_list[mid_pt]: 
     return bin_search(a_sorted_list[mid_pt:], target) 
    elif target == a_sorted_list[mid_pt]: 
     return mid_pt 

в вашем случае вам потребуются некоторые незначительные изменения

+0

У меня есть этот скрипт: Защиту getCountry (ключ): \t с открытым («countries.txt»), а е: \t \t COUNTRY_LIST = фильтр (Отсутствует, карта (лямбда х: x.split (», "), е)) \t \t старт = "% s" #index \t \t конец = Len (" % s ") -1 #index \t \t в то время как начало <= конец: \t \t \t середине = (начало + конец)/2 \t \t \t если '% s' [средний] == ключ: #found его! \t \t \t \t возвращающие \t \t \t Элиф "% s" [середина]> ключ: \t \t \t \t конец = середина -1 \t \t \t еще: \t \t \t \t старт = середина + 1 \t \t #end user3207521

+0

, который не вышел правильно – user3207521

+0

Да почему бы не использовать кододелат или что-то еще? –

1

Я хотел бы использовать словарь:

def get_countries(filename): 
    with open(filename) as f: 
     country_iter = (line.strip().split(',') for line in f) 
     return { 
      country: {"area": area, "population": population} 
      for country, area, population in country_iter 
     } 

if __name__ == '__main__': 
    d = get_countries("countries.csv") 
    print(d) 

Если у вас действительно есть ваше сердце, установленное на двоичном поиске, это выглядит примерно так:

def get_countries(filename): 
    with open(filename) as f: 
     return [line.strip().split(',') for line in f] 

def get_country_by_name(countries, name): 
    lo, hi = 0, len(countries) - 1 
    while lo <= hi: 
     mid = lo + (hi - lo) // 2 
     country = countries[mid] 
     test_name = country[0] 
     if name > test_name: 
      lo = mid + 1 
     elif name < test_name: 
      hi = mid - 1 
     else: 
      return country 
    return countries[lo] if countries[lo][0] == name else None 

if __name__ == '__main__': 
    a = get_countries("countries.csv") 
    print(a) 
    c = get_country_by_name(a, "Albania") 
    print(c) 

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

from bisect import bisect_left 

def get_country_by_name(countries, name): 
    country_names = [country[0] for country in countries] 
    i = bisect_left(country_names, name) 
    return countries[i] 
+0

Спасибо за бинарный поиск, можете ли вы объяснить все о вашем заявлении if в конце? если __name__ == '__main__': а = get_countries ("countries.csv") печати (а) с = get_country_by_name (а, "Албания") печать (с) – user3207521

+0

Это тестовый драйвер для кода , Он вызывает код и показывает, как он работает. Документация здесь: http://docs.python.org/2/library/__main__.html – hughdbrown

+0

okay и для def getcountry (страны, имя): что бы я поставил для переменной «страны»? Извините, что я действительно начинающий – user3207521

1

властвуй эту проблему поэтапно.

  1. Начните с сортированного списка и реализуйте двоичный поиск в списке в функции.
  2. Удостоверьтесь, что он работает для пустых списков, списков одного элемента и т. Д.
  3. Напишите функцию, чтобы взять несортированный список, отсортировать его и вернуть результат на нем из первой функции.
  4. Напишите функцию, которая берет список кортежей со строкой в ​​качестве ключа и других строк в качестве данных. Он должен сортировать данные на вашем ключе и возвращать то, что вы хотите.
  5. Напишите функцию, которая считывает файл и создает данные, совместимые с 4, и возвращает выбранный элемент.

Окунитесь на спину для решения вашей более сложной проблемы в удобоваримых шагах.

Примечание: Это явно задание, чтобы узнать, как реализовать алгоритм. Если бы было действительно найти информацию из файла, использование словаря было бы просто ошибкой. Правильно было бы читать каждую строку до тех пор, пока страна не была найдена, чтобы сделать одно сравнение в среднем по половине записей в файле. Никакое нерациональное хранение, не потраченное время в сравнении или хеширование.

Смежные вопросы