2015-04-22 4 views
2

поэтому у меня есть вопрос об алгоритме, который я должен «изобрести»/«найти». Это алгоритм, который вычисляет 2^(n) - 1 для Ө (n^n) и Ө (1) и Ө (n).Существует ли даже алгоритм для 2^(n) - 1, который лежит в Theta Ө (1)?

Я думал несколько часов, но не смог найти решения для обеих задач (первые, в то время как последний был easist imo, я разместил алгоритм ниже). Но я недостаточно квалифицирован, чтобы «изобретать»/«находить» один для очень медленного и очень быстрого алгоритма.

До сих пор мои алгоритмы (в псевдокод):

Один для Ө (п)

int f(int n) { 

    int number = 2 
    if(n = 0) then return 0 
    if(n==1) then return 1 

    while(n > 1) 
    number = number * 2 
    n-- 

number = number - 1 
return number 

Простой один и любопытное очевидно, один, который использует рекурсию, хотя я не знаю, как быстро это (было бы неплохо, если бы кто-то может сказать мне, что):

int f(int n) { 
    if(n==0) then return 0 
    if(n==1) then return 1 
    return 3*f(n-1) - 2*f(n-2) 
} 
+0

Какого вопрос именно? – amit

+0

Вопрос в том, способен ли кто-нибудь найти алгоритм для 2^(n) - 1, который лежит в тете Ө (n^n) или тета Ө (1), так как, к сожалению, я недостаточно компетентен. И если не существует одного для этого имени Тетас, тогда это тоже хорошо, так как тогда я буду знать, что бессмысленно тратить больше времени на это. – Kaseop

+1

Псст. Слышал о '' 'операторе? 'int Theta1 (int n) {return (1 << n) -1;}'. –

ответ

1

что-то вроде:

HugeInt h = 1; 

h = h << n; 
h = h - 1; 

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

=====

Посмотрите на ответ Amit вместо!

+0

Это работает для ** очень ** ограниченного размера 'n'. На самом деле вы не можете сделать алгоритм 'Ө (1)' для решения этой проблемы, так как сам размер вывода равен 'Ө (log (n))'. – amit

+0

@ У вас есть отличный ответ, за исключением того, что вы должны переключить 'h = 2' на' h = 1'. '1 << n' == 2^n. –

+1

@IwillnotexistIdonotexist Если вы хотите узнать о сложности, вы не должны ограничивать себя смехотворно низкими значениями 'n', так как Ө обозначения сохраняются только тогда, когда значения' n' достаточно велики. Это значение * асимптотической * сложности. – amit

3
  1. Предполагая n не ограничена какой-либо постоянной (и выход не должен быть простым int, но тип данных, которые могут содержать большие целые числа, чтобы позволить его) - нет алгоритма с получением 2^n -1 в Ө(1), так размером самого выхода является Ө(log(n)), поэтому, если мы предположим, есть такой алгоритм, и пусть это работать в постоянное время и составляют менее C операций, для n = 2^(C+1), вам потребуется только C+1 операции для печати вывода, который противоречит предположению, что C - верхняя граница, поэтому такого алгоритма нет.
  2. Для Ө(n^n), если у вас более эффективный алгоритм (например, Ө(n)), вы можете сделать бессмысленный цикл, который выполняет дополнительные итерации n^n и ничего не делает, это сделает ваш алгоритм Ө(n^n).
  3. Существует также алгоритм Ө(log(n)*M(logn)), используя exponent by squaring, а затем просто уменьшая 1 от этого значения. Здесь M(x) - это сложность вашего оператора умножения для числа, содержащего цифры x.
  4. Как прокомментировал @kajacx, вы можете даже улучшить (3) путем применения Fourier transform
+0

Хороший ответ! Не думал об этом так, как раньше ... – Tim

+0

Если я правильно понимаю, алгоритм в 3. делает «log (n)» умножения, однако при работе с произвольно большими числами вы больше не можете умножаться в постоянное время. Лучшее, что я знаю, вовремя 'm log (m)' где 'm' - это количество бит обоих чисел, используя [Дискретное преобразование Фурье] (http://en.wikipedia.org/wiki/Discrete_Fourier_transform) – kajacx

+0

@kajacx вы поднимаете хороший момент. Editted. – amit

0

в Ө (п^п) слишком сложно для меня, но реальный Ө (1) алгоритм на любой «двоичный "архитектура будет:

return n-1 bits filled with 1 

(при условии, ваша архитектура может выделить и заполнить п-1 бит в постоянная время) ;)

+0

Что заставляет вас думать, что 'Math.pow' работает в' Ө (1) 'time? – amit

+0

[this] (http://stackoverflow.com/a/13418265/592355), @amit :-) – xerx593

+0

также http://stackoverflow.com/a/8404191/592355 ... так что это примерно Ө (#bits_of_your_computer), где #bits_of_your_computer можно считать постоянным, и для этого == Ө (1) – xerx593