2009-04-23 8 views
3

Quelqu'un peut-il aider à la complexité temporelle de cet algorithme, et pourquoi il est O (n^2). Une explication étape par étape serait utile, merci!Diviser algorithme - temps complexité

function divide(x,y) 
    Input: Two n-bit integers x and y, where y >= 1 
    Output: The quotient and remainder of x divided by y 

    if x = 0: 
     return (q,r) = (0,0) 

    (q,r) = divide(x/2, y) 
    q = 2q 
    r = 2r 

    if x is odd: 
     r = r + 1 

    if r >= y: 
     r = r - y 
     q = q + 1 

    return (q,r) 
+0

Pourriez-vous ajouter « le code formattage » à votre code? C'est plutôt difficile à lire maintenant. – Skurmedel

+0

Clarification nécessaire - les opérations arithmétiques fonctionnent-elles sur un type de données de base (par exemple, int) ou sur des tableaux (par exemple un tableau BigInt d'ints)? – paxdiablo

+0

non c'est pas, c'est une question d'examen passé et je suis en train de réviser pour un examen à venir. J'ai les solutions ici, mais je ne comprends pas ce: à chaque appel de l'algorithme, nous perdons un peu. Il y aura donc n + 1 appels. Chaque appel implique au plus 2 multiplications par 2 (décalages à gauche), deux additions par 1, et une soustraction par y, qui est tout O (n). D'où le total complexité est O (n2) – KP65

Répondre

2

En raison de la récursivité, divide() est appelée jusqu'à n fois.

Supposons que des opérations arithmétiques simples sur des nombres entiers de n bits prend O (n). (Cela est vrai dans toutes les grandes implémentations d'entiers que je connais - en Python, par exemple, ajouter 1 à un grand entier copie le tout.)

Puis nous avons un nombre fini d'opérations O (n) jusqu'à n fois. Cela prend O (n^n) heure.

def divide(x, y): 
    assert y >= 1 
    if x == 0: 
     return 0, 0 
    q, r = divide(x // 2, y) 
    q *= 2 
    r *= 2 
    if x & 1: 
     r += 1 
    if r >= y: 
     r -= y 
     q += 1 
    return q, r 
+0

Je pense que vous avez votre n confus. L'arithmétique sur un seul entier de n bits sera O (1), pas O (n), puisque je crois que le n dont on parle est la valeur de x passée à la fonction. divide() est JAMAIS appelé jusqu'à n fois. En passant en 1024, la division ne sera appelée que 10 fois. – paxdiablo

+0

Mais Pax, votre message dit que x et y sont "Deux entiers n bits". –

+0

Le N dans O (N) est la valeur de x ou le nombre de bits n - il ne peut pas être les deux. J'ai pris la question pour indiquer que c'était une seule unité entière (int), pas un tableau général d'entre eux (int []) qui rend le bigO dépendant de deux variables d'entrée. Besoin de clarification de l'interrogateur. – paxdiablo

1

Le pire des cas, où chaque bit dans x est égal à 1 (par exemple 0xffff), est O (n). L'astuce consiste à convertir la récursion en une itération.

+0

@splicer, je pense que le pire des cas, lorsque le * haut * bit est un , pas nécessairement tous les bits. Mais, maintenant nous avons établi que n est le nombre de bits, pas la valeur de x, O (n) est la bonne réponse, malgré la question. +1 et en supprimant ma réponse qui supposait n était la valeur de x plutôt que le bitcount. – paxdiablo

+0

@Pax - Oui, vous avez raison: le pire des cas est lorsque le MSB est défini. – splicer