手工實現整除除法的比較
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> int test(int(*p)(int,int),const char s[],int a,int b) { int t=clock(); int c=p(a,b); printf("%s %ld ms\n",s,clock()-t); fflush(stdout); return c; } int divide(int a,int b) { int s=1; while((a-(s)*b)>=0) s++; return s-1; } int divide2(int a,int b) { int s=0; char ca[20]; char cb[20]; itoa(a,ca,10); itoa(b,cb,10); int t=strlen(ca)-strlen(cb); s=1; while(t-->1)s=10*s; printf("s=%d\n",s); while((a-(s)*b)>=0) s++; return s-1; } int divide3(int a,int b) { int s=0; char ca[20]; char cb[20]; itoa(a,ca,10); itoa(b,cb,10); int t=strlen(ca)-strlen(cb); s=1; while(t-->1)s=10*s; printf("s=%d\n",s); int s0=s; while(a-s*b>=0)s=s+s0; s-=s0; printf("s=%d\n",s); while((a-(s)*b)>=0) s++; return s-1; } int main() { int a=20e8,b=7; int c1=test(divide,"method 1",a,b); int c2=test(divide2,"method 2",a,b); int c3=test(divide3,"method 3",a,b); int c=a/b; printf("%d %d %d %d %d %d",a,b,c,c1,c2,c3); return 0; } --- D:\>a method 1 4118 ms s=100000000 method 2 3760 ms s=100000000 s=1000000000 method 3 202 ms 2100000000 2 1050000000 1050000000 1050000000 1050000000 D:\>g++ divide.c D:\>a method 1 1107 ms s=100000000 method 2 733 ms s=100000000 s=200000000 method 3 328 ms 2000000000 7 285714285 285714285 285714285 285714285
方法1直接減去除數,方法2好一些,方法3再好一些。
int divide4(int a,int b) { int s=1; char ca[20]; char cb[20]; int x[20]; itoa(a,ca,10); itoa(b,cb,10); int t=strlen(ca)-strlen(cb); x[0]=1; for(int i=1;i<t;i++) { x[i]=10*x[i-1]; } t--; while(t>=0) { a-=x[t]*b; s+=x[t]; if(a<b) { a+=x[t]*b; s-=x[t]; t--; } } return s; } --- D:\>g++ divide.c D:\>a method 1 470 ms s=10000000 method 2 430 ms s=10000000 s=110000000 method 3 30 ms method 4 0 ms 2000000000 17 117647058 117647058 117647058 117647058 117647058 D:\>g++ divide.c D:\>a method 1 1150 ms s=100000000 method 2 740 ms s=100000000 s=200000000 method 3 330 ms method 4 0 ms 2000000000 7 285714285 285714285 285714285 285714285 285714285
下面是https://github.com/soulmachine/acm-cheat-sheet 中提供的大數除法程式,思路與方法4類似.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BIGINT_RADIX 10000 #define RADIX_LEN 4 #define MAX_LEN (100/RADIX_LEN+1) char a[MAX_LEN * RADIX_LEN], b[MAX_LEN * RADIX_LEN]; int x[MAX_LEN], y[MAX_LEN], z[MAX_LEN]; void bigint_print(const int x[], const int n) { int i; int start_output = 0; for (i = n - 1; i >= 0; --i) { if (start_output) { printf("%04d", x[i]); } else if (x[i] > 0) { printf("%d", x[i]); start_output = 1; } } if(!start_output) printf("0"); } void bigint_input(const char s[], int x[]) { int i, j = 0; const int len = strlen(s); for (i = 0; i < MAX_LEN; i++) x[i] = 0; // for (i = len - 1; i >= 0; i--) a[j++] = s[i] - '0'; for (i = len; i > 0; i -= RADIX_LEN) /* [i-RADIX_LEN, i) */ { int temp = 0; int k; const int low = i-RADIX_LEN > 0 ? i-RADIX_LEN : 0; for (k = low; k < i; k++) { temp = temp * 10 + s[k] - '0'; } x[j++] = temp; } } static int length(const int x[]) { int i; int result = 0; for (i = MAX_LEN - 1; i >= 0; i--) if (x[i] > 0) { result = i + 1; break; } return result; } static int bigint_sub(int x[], const int y[]) { int i; const int lenx = length(x); const int leny = length(y); if (lenx < leny) return -1; else if (lenx == leny) { int larger = 0; for (i = lenx - 1; i >= 0; i--) { if (x[i] > y[i]) { larger = 1; } else if (x[i] < y[i]) { if (!larger) return -1; } } } for (i = 0; i < MAX_LEN; i++) { x[i] -= y[i]; if (x[i] < 0) { x[i] += BIGINT_RADIX; x[i+1] --; } } return 1; } void bigint_div(int x[], const int y[], int z[]) { int i; int *yy; const int xlen = length(x); int ylen = length(y); const int times = xlen - ylen; for (i = 0; i < MAX_LEN; i++) z[i] = 0; if (times < 0) return; yy = (int*)malloc(sizeof(int) * MAX_LEN); memcpy(yy, y, sizeof(int) * MAX_LEN); for (i = xlen - 1; i >= 0; i--) { if (i >= times) yy[i] = yy[i - times]; else yy[i] = 0; } ylen = xlen; for (i = 0; i <= times; i++) { int j; while (bigint_sub(x, yy) >= 0) { z[times - i]++; } for (j = 1; j < ylen; j++) { yy[j - 1] = yy[j]; } yy[--ylen] = 0; } for (i = 0; i < MAX_LEN - 1; i++) { if (z[i] >= BIGINT_RADIX) { z[i+1] += z[i] / BIGINT_RADIX; z[i] %= BIGINT_RADIX; } } free(yy); } int main() { int T; scanf("%d", &T); while (T-- > 0) { scanf("%s%s",a,b); bigint_input(a, x); bigint_input(b, y); bigint_div(x, y, z); bigint_print(z, MAX_LEN); printf("\n"); } return 0; } ---- D:\>g++ bigdiv.cpp D:\>a 3 1 2 0 1000000000000000000000 7 142857142857142857142 976000094000000000000000000000 563493904 1732050847527890913971
相關文章
- PostgreSQL與Rust的聚合實現比較SQLRust
- 前端動畫效果實現的簡單比較前端動畫
- 如何實現不完全字典比較的 helper
- ISAPI 與CGI 的 比 較 及 其 實 現 (轉)API
- 實現saas多租戶方案比較
- 如何比較版本號--Python實現Python
- Java中不同的併發實現的效能比較Java
- jmeter混合場景的多種實現方式比較JMeter
- 通過Comparable來實現對自身的比較
- 簡單介紹Go 字串比較的實現示例Go字串
- SQL Server相似比較演算法實現SQLServer演算法
- 前端比較實用的CSS前端CSS
- Java動態代理 jdk和cglib的實現比較JavaJDKCGLib
- 實現 UML 模型的自動化比較及合併模型
- linux防火牆實現技術比較(轉)Linux防火牆
- 比較實用的js集錦JS
- 比較實用的選股技巧
- LVS和Nginx實現負載均衡功能的比較Nginx負載
- 幾種任務排程的 Java 實現方法與比較Java
- Oracle中spool命令實現的兩種方法比較-入門Oracle
- 單點登入原理與技術實現比較
- 資料結構-棧&佇列&Deque實現比較資料結構佇列
- linux防火牆實現技術比較(1)(轉)Linux防火牆
- Python解惑:整數比較 is ==的比較Python
- 【前端詞典】4 種滾動吸頂實現方式的比較前端
- C# 實現一個基於值相等性比較的字典C#
- 實現比較通用的DOM事件掛載、事件解除安裝(相容)事件
- 幾種分散式呼叫鏈監控元件的實踐與比較(二)比較分散式元件
- 如何實現“比較兩張圖片的相似度”,或者說“比較兩張圖片是否基本一致”的演算法?演算法
- Integer的比較
- BST查詢結構與折半查詢方法的實現與實驗比較
- js 深比較和淺比較JS
- 單點登入的原理、實現、及技術方案比較詳解
- PHP的壓縮函式實現:gzencode、gzdeflate和gzcompress比較PHP函式
- 有哪些比較實用的全球http代理HTTP
- Linux運維比較實用的工具Linux運維
- 求最大公約數不同演算法的時間比較(輾轉相除法,更相減損術等)演算法
- Go和Python比較的話,哪個比較好?GoPython