[英]Best way to store large base B numbers?
存儲大型基本B編號的最佳方法是什么,以便能夠有效地完成右移和檢查最低有效位等操作?
實際上,我遇到了一個面試問題
Given two numbers N and K such that 0<=N<=1000 and 0<=K<=1000^1000. I need
to check that whether N^N = K or not. For example:
if N=2 and K=4 , 2^2 = 4 so return true;
if N=3 and K=26 , 3^3 != 26 so return false
我在想的是,如果我考慮base N number system
,那么N^N
將等於1 followed by N zero
。 例如 - 對於N = 2,2 ^ 2 = 100(在基數2中),對於N = 3,3 ^ 3 = 1000(在基數3中)。 然后,我可以輕松編寫一個函數來判斷K = N^N
是否。
int check(unsigned long int N, unsigned long int K)
{
unsigned long int i;
for (i=0; i<N; i++)
{
if (K%N != 0) //checking whether LSB is 0 or not in base N number system
return 0;
K = K/N; //right shift K by one.
}
return (K==1);
}
現在這個功能有兩個主要問題:
1) An unsigned long int is not sufficient to store large numbers of range 0
to 1000^1000.
2) The modulus and the division operations makes it every less efficient.
為了使其高效,我正在尋找一些方法來表示大的基數N數,以便我可以執行右移並有效地檢查最低有效位操作。 以前有人遇到過這樣的事嗎? 或者有誰知道有效解決這個問題的任何其他方法?
要檢查相等性,您實際上不必進行高精度算術 - 您可以使用http://en.wikipedia.org/wiki/Chinese_remainder_theorem 。 找到足夠的質數以確保它們的乘積大於N ^ N,然后依次檢查N ^ N對K的每個質數的模數。
在實踐中,我可能會使用Java BigInteger包進行簡單的計算。
根據面試官的不同,可以接受一些答案。 如果其中任何一項都不被接受,那么希望面試官能夠迅速推動您提出其他建議。
gmp
,或者使用mpz_t
而不是unsigned long
來執行除法和模數,或者只計算N^N
並將其與K
進行比較。 這是最簡單的方法。 K
在N^N
附近時很多工作。 例如,測試log(K) / N
是否近似等於log(N)
,在任何基數中采用的日志對於輸入最方便。 或測試多少次K
和N
是整除的數字方便像2
或10
:如果K
是不能分開的正是N
次很多次N
,那么它顯然是錯誤的。 或者測試它們是否等於一些小數,例如ULONG_MAX
或1000000
。 不幸的是,這種事情只能加速某些不平等的情況,它會減慢其他一切,包括它們的情況。 所以它可能適得其反,取決於你期望的輸入。 mcdowella的回答可能是也可能不是最好的,我不知道。 特別有希望的是,您只需要生成一次素數(當您編寫程序時),並且在100 N <= 1000
從1009開始的1000個素數就足夠了。 較大的素數意味着需要的更少,因此工作量更少,特別是如果它們不超過ULONG_MAX
平方根。 通過平方或等效使用取冪來得到N^N
模數每個素數,並且對於K
,無論輸入是什么基礎,每次都做幾個數字。
要真正閃存,對於每個預先選擇的素數p
您可以編寫(或讓編譯器為您編寫)模運算操作,該操作比適用於任何除數的一般整數模運算更快。 也就是說,一個體面的編譯器i % 1009
可能會快於i % j
其中的價值j
是在編譯時未知,但原來在運行時是1009。但要注意,在速度上的差異可能收不回(比如)通過函數指針調用它的成本。 因此,利用它可能需要一些丑陋的重復代碼。
為什么要將數字轉換為基數N?
你可以繼續除以N.如果你在N之后得到1這樣的除數那么它就是N ^ N. 否則它不是。
您必須將K存儲為字符串並執行divison操作。
divide(k,n):
c = ''
a = ''
for i in k:
c = c+i
a = a+ str(int(c)/ int(n))
c = str(int(c) % int(n))
return a
這是在python中,你可以在C中實現類似的東西
給定兩個數字N和K,使得0 <= N <= 1000且0 <= K <= 1000 ^ 1000。 我需要檢查是否N ^ N = K.
很大程度上取決於提供給代碼時這些數字的存儲方式。 假設它們是文本格式,我只是保持這種方式,並創建一個包含N ^ N值的1001個字符串數組。 您可以使用任意精度算術命令行程序(如bc
來一次性創建這些字符串,並在循環中調用它。
由於1000 ^ 1000中只有1000個“好”值(並且它們將彼此相距很遠),因此可以先使用一些對數近似來猜測N. 在那之后,您最多只需要一次精確檢查(例如,使用一些bignum庫)。
這個對數不必是精確的,即使strlen()可以足夠近似。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.