2012-07-27 24 views
8

Ho bisogno di trovare il primo multiplo per un numero a partire da un numero base. Per esempio: il primo multiplo di 3 da 7 è 9. Il mio primo tentativo è stato quello di fare questo:Modo rapido per trovare il prossimo multiplo di un numero

multiple = baseNumber 
while(multiple%number !=0) 
    multiple++ 

Alla fine, "multipla" avrà il primo multiplo di number dopo baseNumber. Il problema è che quando number diventa troppo grande, il numero di iterazioni diventa eccessivo. Quindi la mia domanda è: c'è un modo più veloce per farlo?

+1

Si potrebbe essere meglio chiedere questo al Matematica Stack Exchange. Potresti anche voler fornire una definizione più chiara o più rigorosa di cosa intendi per multiplo di un numero. – Jim

risposta

19

Se tutto è garantito per essere positivo, provare

multiple = baseNumber + number - 1; 
multiple -= (multiple % number); 

che lo fa in tempo costante.

Prima di tutto, aggiungiamo number - 1 per assicurarci di avere un numero almeno grande come il prossimo multiplo ma più piccolo di quello successivo. Quindi sottraiamo il resto della divisione per number per assicurarci di avere il multiplo desiderato.

Se baseNumber può essere negativo (ma number ancora positiva), si affronta il problema che multiple % number può essere negativo se multiple < 0, la suddetta potrebbe saltare un multiplo di number. Per evitare ciò, possiamo usare per es.

remainder = multiple % number; 
if (remainder < 0) remainder += number; 
multiple -= remainder; 

Se ramificazione è troppo costoso, siamo in grado di evitare la if al costo di due divisioni invece di uno,

multiple -= (number + (multiple % number)) % number; 

In generale, il if sembra preferibile, però.

Se number può essere negativo, sostituirlo prima con il suo valore assoluto.

Nota: quanto sopra riportato, come fa il codice originale, baseNumber se questo è già un multiplo di number. Se ciò non è desiderato, rimuovere - 1 nella prima riga.

+0

Non penso che sia giusto, supponendo che sia richiesto il multiplo successivo maggiore di 'baseNumber'. Considera 'baseNumber = 6, number = 3'; otterrete 6. Più in generale, penso che questo fallirà ogni volta che 'number' divide' baseNumber'. – DSM

+0

Sono passato al codice OP che restituisce anche 'baseNumber' se questo è già un multiplo. Ma aggiungerò una nota a riguardo, grazie. –

+0

@DSM Se questo è il caso, tutto ciò che devi fare è rimuovere il "-1", e dovresti stare bene. –

0
while(multiple * number < baseNumber) 
     multiple++; 

quindi per baseNumero = 3, numero = 7, il tuo multiplo è 3;

però, qualcosa mi dice che i bignum stanno per apparire qui.

+1

Mi sembra che questo abbia lo stesso problema di quello che l'OP aveva. Supponiamo che 'number' assomigli a 2 e baseNumber sia 1 miliardo. Non vuoi dover controllare tutti i multipli di 2 fino a 1 miliardo. –

+0

in questo caso è più una questione di matematica ... so che c'è una formula per questo. devo cercare le mie vecchie note crittografiche immagino ... – Shark

4

provare questo (Richiede divisione intera):

multiple = ((base/number) + 1) * number; 

7/3 = 2. 3 * (2 + 1) = 9.

Hai un caso limite in cui la baseNumber è già multiplo di number, che sarà necessario testare utilizzando l'operazione modulo.

+0

Doh. Ho praticamente ripetuto la tua risposta. Ma non hai bisogno di una funzione di piano dopo base/numero? – bigbenbt

+1

divisione intera: D –

+0

Ah. Quindi c'è una RAGIONE che hai messo le parole in grassetto. – bigbenbt

3

Perché è necessario un ciclo?

multipla = (piano (numero/baseNumber) +1) * baseNumber

Problemi correlati