2014-05-03 3 views
0

Я написал программу, которая находит наименьшее число, которое имеет каждое число от 1 до 20 как несколько. Мой код в C++ прекрасно работает и находит правильный ответ:Python застревает при компиляции

#include <iostream> 

using namespace std; 

int main(){ 

    for(int i = 1; i < 300000000; i++){ 

     int check = 1; 

     for(int j = 6; j <= 20; j++){ 

      if(i % j == 0){ 

       continue; 

      } else { 

       check = 0; 
       break; 

      } 

     } 

     if(check == 1){ 

      cout << i << endl; 
      break; 

     } 

    } 

} 

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

for i in range(1, 300000000): 

    check = 1 

    for j in range(6, 21): 
     if i % j == 0: 
      continue 
     else: 
      check = 0 
      break 

    if check == 1: 
     print i 
     break 

Я использую Mac OS X Mavericks, если это уместно.

Редактировать: Я попытался переключиться на xrange, но это, к сожалению, не имеет значения.

Edit2: Я оставил его на заднем плане - на самом деле это заняло всего около 14 минут! Прошу прощения, я должен был сделать это в первую очередь.

+0

какая версия python это? – shuttle87

+0

Специально '' for'' lops. Они ужасно медленны. Используйте '' map'', * list comprehensions * или инструменты, такие как '' itertools'', чтобы получить значительно лучшую производительность. '' for'' следует использовать только для небольших итераций или когда это действительно единственный вариант. И '' xrange'' вместо '' range'', если вы находитесь в python 2.x, как указано ниже. – aruisdante

+0

Я только что сделал скамью простого '' for i in xrange (300000000): z = i% 10'', и это заняло 20 секунд. Серьезно, ваша программа просто медленно, как написано. Это не так. – aruisdante

ответ

2

Я думаю, вы используете Python 2.

Ваша задача заключается в следующем:

range(1, 300000000) 

Вы строите список 300000000 Python Int объектов. Если предположить, что ints в Python составляют 4 байта (это чрезвычайно false), то вы выделяете 300000000 × 4 = 1200000000 байт = 1 ГБ.

Вы должны заменить его следующим:

xrange(1, 300000000) 

Преимущество xrange является то, что он не предварительно выделить все Интс Python заранее. Смотрите документацию xrange для получения дополнительной информации:

Преимущество xrange() по диапазону() является минимальным [...] кроме случаев, когда очень большой диапазон используется в памяти голодали машины [... ]

с Python 3 эта проблема уже больше не существует, потому что диапазон был удален и xrange был переименован в диапазоне.

Обратите внимание, что это решит любую ошибку памяти, с которой вы столкнулись. Это не решит проблему использования плохого медленного алгоритма. Python не очень быстрый при работе с номерами (но и другие языки будут медленно работать при использовании огромных чисел).

+0

Это не предлагает решение проблемы OP. – Luigi

+0

Это происходит, если он заменяет диск, что сделает медленный цикл python '' for'' еще медленнее. – aruisdante

+0

@ Луис: почему бы и нет? –

0

Если это python 2, то вам действительно нужно изменить range на xrange. range работает, создавая список указанного размера, который вы затем выполняете по элементу по позиции. Однако в этом случае вам не нужен сам список, только индексы, которые содержались в этом списке. Поэтому вы должны предпочесть xrange, потому что это генератор, который означает, что он может выполнять итерацию без создания списка в памяти. Это избавит вашу программу от необходимости создавать действительно большой список, который займет много памяти.

Обратите внимание, что в Python 3 range имеет такое же поведение, что и у Python 2 xrange.

for i in xrange(1, 300000000): 

    check = 1 

    for j in xrange(6, 21): 
     if i % j == 0: 
      continue 
     else: 
      check = 0 
      break 

    if check == 1: 
     print i 
     break 

Также Python является интерпретируемым языком, не существует этапа компиляции, как в C++. То, что вы видите, - это просто медленное время работы.

1

Что значит «скомпилировать»? Как вы компилируете код Python?

Попробуйте использовать xrange()

+1

Многие люди, по-видимому, взаимозаменяемо используют '' compile'' и '' execute'', к сожалению. Особенно с интерпретируемыми языками. – aruisdante

+2

Python _is_ скомпилирован в байт-код, но OP явно означает выполнение. –

0

Ваша программа Python не неправильно, это просто очень-очень медленно, потому что вы используете очень плохой алгоритм.

Попробуйте вместо этого:

def gcd(a, b): 
    while b: 
     a, b = b, a%b 
    return a 

def lcm(a, b): 
    return (a // gcd(a, b)) * b 

res = 1 
for i in range(2, 21): 
    res = lcm(res, i) 
print("Least common multiple of 1..20 is {}".format(res)) 

Edit: в качестве альтернативы, вы можете использовать свой алгоритм (но сделать это о 400x быстрее), понимая, что 19 и 20 взаимно просты, поэтому любое решение должно быть кратна 19 * 20:

UPTO = 300000000 
STEP = 19 * 20 

for i in xrange(STEP, UPTO, STEP): 
    if any(i % div for div in xrange(6, 19)): 
     continue 
    else: 
     print("Solution: {}".format(i)) 
     break 

который проходит примерно 0,94 с на моей машине (против 0.0000249 сек для «хорошего» алгоритма == около 37000 раз быстрее снова!).

+4

Я предполагаю, что мы все предположили, что это было домашнее задание, и он не хотел его решать для ОП. Мы уже сказали им, что это было просто медленно. – aruisdante

+0

@aruisdante: смешно, как «найти лучший алгоритм» неоднократно выражается как «use xrange». Я бы никогда не стал первым со второго. –

+0

Использование '' range'' на машине с низкой памятью приведет к обмену, что сделает медленный алгоритм еще медленнее. И если вы заметите мой первый комментарий к фактическому вопросу OP, то его алгоритм был медленным. В стороне, просто выполнение распределения для '' range (300000000) '' занимает почти 20 секунд. – aruisdante

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