2012-07-27 17 views
8

Potrzebuję znaleźć pierwszą wielokrotność numeru zaczynającego się od numeru bazowego. Na przykład: Pierwszy wielokrotnością 3 z 7 9. Moja pierwsza próba była to zrobić:Szybki sposób na znalezienie następnej wielokrotności numeru

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

Na koniec, „stwardnienie” będzie miał pierwszy wielokrotność number po baseNumber. Problem polega na tym, że gdy number staje się zbyt duży, liczba iteracji staje się zbyt duża. Moje pytanie brzmi: czy istnieje szybszy sposób na zrobienie tego?

+1

Możesz być lepiej pytaniem to na Matematyki Stos Exchange. Możesz również chcieć zapewnić jaśniejszą lub bardziej rygorystyczną definicję tego, co masz na myśli przez wielokrotność liczby. – Jim

Odpowiedz

19

Jeśli wszystko jest gwarancją pozytywny, spróbuj

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

Że robi to w czasie stałym.

Najpierw dodajemy number - 1, aby upewnić się, że mamy numer co najmniej tak duży jak kolejny numer, ale mniejszy niż kolejny. Następnie odejmujemy resztę podziału przez number, aby upewnić się, że mamy pożądaną wielokrotność.

Jeśli baseNumber może być ujemna (ale number nadal dodatnia), możemy zmierzyć się z problemem, że multiple % number mogą być ujemne, jeśli multiple < 0, więc powyższe mógł pominąć wielokrotność number. Aby tego uniknąć, możemy użyć np.

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

Jeżeli rozgałęzienie jest zbyt kosztowne, możemy uniknąć if kosztem dwóch dywizji zamiast jednego,

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

Generalnie if wydaje korzystne, choć.

Jeśli wartość number może być ujemna, należy najpierw zastąpić ją wartością bezwzględną.

Uwaga: Powyższe zwraca, tak jak oryginalny kod, baseNumber, jeśli jest to już wielokrotność number. Jeśli nie jest to pożądane, usuń - 1 w pierwszym wierszu.

+0

Nie sądzę, aby to było prawidłowe, zakładając, że wymagana jest następna wielokrotność większa od "baseNumber". Weź pod uwagę 'baseNumber = 6, number = 3'; dostaniesz 6. Bardziej ogólnie, myślę, że to się nie powiedzie, gdy 'liczba' dzieli" numer_podstawy ". – DSM

+0

Poszedłem przez kod OP, który zwraca również wartość "numer_podstawy", jeśli jest to już wielokrotność. Ale dodam notatkę na ten temat, dziękuję. –

+0

@DSM Jeśli tak jest, to wszystko co musisz zrobić, to usunąć "-1" i powinieneś być w porządku. –

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

tak dla baseNumber = 3, liczba = 7, twoja wielokrotność to 3;

Jednak coś mi mówi, że bignums już się tu pojawią.

+1

Mam wrażenie, że ma to ten sam problem, co OP. Załóżmy, że 'liczba' ma wartość 2, a wartość podstawowa to 1 miliard. Nie musisz sprawdzać wszystkich wielokrotności od 2 do 1 miliarda. –

+0

w takim przypadku jest to więcej pytań matematycznych niż ... wiem, że istnieje na to formuła. Muszę przejrzeć moje stare notatki kryptograficzne, chyba ... – Shark

4

spróbować (Wymaga dzielenia całkowitego)

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

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

Trzeba to przypadku krawędź, gdzie jest już baseNumber wielokrotność number, którą będziesz musiał przetestować używając operacji modulus.

+0

Doh. Ja prawie powtórzę twoją odpowiedź. Ale czy nie potrzebujesz funkcji podłogi po podstawie/liczbie? – bigbenbt

+1

Podział całkowity: D –

+0

Ah. A więc istnieje POWAŁANIE, w którym słowa są pogrubione. – bigbenbt

3

Dlaczego potrzebujesz pętli?

wielokrotność = (piętro (liczba/baseNumber) +1) * baseNumber

Powiązane problemy