檢測完全平方數
尤拉計劃的一些題目需要檢測完全平方數,最簡單的方法是使用以下 C 語言程式:
int isSquare(long n) { long x = (long)sqrt(n); return x * x == n; }
但是,也有更快的方法,即以下的 C 語言程式(exactSquareRoot.c):
#include <math.h>
char bad255[512] =
{0,0,1,1,0,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,0,1,1,1,0,1,1,1,1,0,1,
1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,0,1,1,1,
0,1,0,1,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,1,
1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,
1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,
1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,
1,0,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
0,0,1,1,0,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,0,1,1,1,0,1,1,1,1,0,1,
1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,0,1,1,1,
0,1,0,1,1,0,0,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,1,1,1,1,1,1,1,1,0,1,
1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,
1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,
1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,
1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,
1,0,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
0,0};
// return: < 0 if x is not a square, r if r*r == x and r >= 0
int exactSquareRoot(long x)
{
// Quickfail
if (x < 0 || (x & 2) || (x & 7) == 5 || (x & 11) == 8) return -1;
if (x == 0) return 0;
// Check mod 255 = 3 * 5 * 17, for fun
long y = x;
y = (y & 4294967295L) + (y >> 32);
y = (y & 65535) + (y >> 16);
y = (y & 255) + ((y >> 8) & 255) + (y >> 16);
if (bad255[y]) return -1;
// Divide out powers of 4 using binary search
y = x;
if ((y & 4294967295L) == 0) y >>= 32;
if ((y & 65535) == 0) y >>= 16;
if ((y & 255) == 0) y >>= 8;
if ((y & 15) == 0) y >>= 4;
if ((y & 3) == 0) y >>= 2;
if ((y & 7) != 1) return -1;
int r = (int)sqrt(x);
return (r * (long)r == x) ? r : -1;
}
我們來比較一下兩者的速度(a.c):
#include <stdio.h>
#include <math.h>
extern int exactSquareRoot(long x);
int isSquare1(long n) { long x = (long)sqrt(n); return x * x == n; }
int isSquare2(long n) { return exactSquareRoot(n) >= 0; }
int count(long a, long n, int (*f)(long))
{
int z = 0;
for (long i = 0; i < n; i++) if (f(a + i)) z++;
return z;
}
int main()
{
long a = 123456789; long n = 4987654321;
printf("%ld: %ld\n", a, n); fflush(stdout);
printf("%d\n", count(a, n, isSquare1)); fflush(stdout);
printf("%d\n", count(a, n, isSquare2)); fflush(stdout);
}
執行結果:
$ clang -O3 a.c exactSquareRoot.c -lm
$ ./a.out | gnomon -i
40.4646s | 123456789: 4987654321
24.9703s | 60381
0.0069s | 60381
|
Total | 65.4442s
這個比較程式統計從 123456789 開始的 4987654321 個整數,計算其中的完全平方數的個數,得到的結果是有 60381 個。前者用時 40.46 秒,後者用時 24.97 秒。
注:
參考資料
相關文章
- 完全平方數
- [Python手撕]完全平方數Python
- LeetCode-279-完全平方數LeetCode
- [Leetcode]279.完全平方數LeetCode
- (PAT)使用函式判斷完全平方數函式
- LeetCode-367-有效的完全平方數LeetCode
- python一個整數,它加上100後是一個完全平方數,再加上168又是一個完全平方數Python
- abc342D 乘積為完全平方數的對數
- Python例項之用Python求完全平方數Python
- Q5 LeetCode367 完全平方數LeetCode
- ALGO-201 大等於n的最小完全平方數Go
- P8754 [藍橋杯 2021 省 AB2] 完全平方數
- 山東省第六屆ACM大學生程式設計競賽-Square Number(完全平方數)ACM程式設計
- 程式碼隨想錄day 38 || 322 零錢兌換,279 完全平方數,139 單詞拆分
- JAVA 完全數Java
- PLSQL實現計算某數的平方SQL
- 檢測字串是否完全由大小寫字母組成正規表示式字串
- Miller-Rabin素數快速檢測
- Python求一個數的平方根Python
- 6周驗血檢測dna是女寶,和閨蜜完全不同的遭遇
- JavaScript變數型別檢測總結JavaScript變數型別
- aix變數的設定與檢測AI變數
- python中一個數的平方怎麼表示Python
- Oracle 同步、非同步完全檢查點Oracle非同步
- Oracle完全檢查點和增量檢查點詳解Oracle
- javascript檢測一個變數是否為數字或者數字字串JavaScript變數字串
- 程式碼隨想錄演算法訓練營 | 322. 零錢兌換,279.完全平方數,139.單詞拆分演算法
- Miller-Rabin素數檢測演算法演算法
- opencv——機器視覺檢測和計數OpenCV視覺
- C語言學習 兩個數的平方和C語言
- Android感測器完全解析Android
- 633. 平方數之和 ( 列舉 + 二分查詢 )
- 數字化變革探索:檢驗檢測行業轉型思路揭秘行業
- 檢測字串中數字和字母的數量程式碼例項字串
- OpenCV檢測篇(一)——貓臉檢測OpenCV
- 文章相似度檢測,相似度檢測工具,原創度檢測工具
- Web應用程式完全測試指南Web
- 網站漏洞檢測 滲透測試檢測手法網站