嘗試實現了下大數運算的代碼。
原理就是用int型數組模擬一個大數的每個位。
數組的[0]對應的大數的個位。
具體代碼如下,主要考慮大於10的元素要進位,負數要借位。
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> using namespace std; #define MAX_DIGIT 500 //大數運算:加法 int Multiply(int *a,int *b,int *&result); //大數運算:乘法 int Add(int *a,int *b,int *&result); //大數運算:減法 int Sub(int *a,int *b,int *&result); //逐位調整大數,如result爲11 9 22 -3 -2調整爲:1 0 3 9 -3,然後再對符號提升到最高位: 9 9 6 0 2... ... -1 //表示大數的值爲-20699 void AjustEncodeArray(int *&result,unsigned int iMaxNum); //輸出大數 void PrintBigNum(int *result); //把個位在高位的字符數組轉爲個位在低位(下標0)的整型數組 void CArray2revDigitArray(char *cArray,int *DigitArray,unsigned int iNum); //大數運算:加法 int Add(int *a,int *b,int *&result) { if(a==NULL || b==NULL || result==NULL) { printf("multiply:input error/n"); return -1; } int i=0,j=0; //初始化result數組 for(i=0;i<MAX_DIGIT*2;++i) { result[i]=0; } for(i=0;i<MAX_DIGIT;++i) { result[i] += (a[i]+b[i]); } AjustEncodeArray(result,MAX_DIGIT*2); return 0; } //大數運算:減法 int Sub(int *a,int *b,int *&result) { if(a==NULL || b==NULL || result==NULL) { printf("multiply:input error/n"); return -1; } int i=0,j=0; //初始化result數組 for(i=0;i<MAX_DIGIT*2;++i) { result[i]=0; } for(i=0;i<MAX_DIGIT;++i) { result[i] += (a[i]-b[i]); //result裏可以爲負數 } AjustEncodeArray(result,MAX_DIGIT*2); return 0; } //大數乘法 int Multiply(int *a,int *b,int *&result) { if(a==NULL || b==NULL || result==NULL) { printf("multiply:input error/n"); return -1; } int i=0,j=0; //初始化result數組 for(i=0;i<MAX_DIGIT*2;++i) { result[i]=0; } //a[0]爲個位起算,結果的偏移位爲i+j, //如個位*十位,則運算結果的偏移爲0+1即1 //例子:a[0]爲9,b[1]爲7,則result[1]加63 for(i=0;i<MAX_DIGIT;++i) { for(j=0;j<MAX_DIGIT;++j) { result[i+j] += a[i]*b[j]; } } AjustEncodeArray(result,MAX_DIGIT*2); return 0; } //逐位調整大數,如result爲11 9 22 -3 -2調整爲:1 0 3 9 -3,然後再對符號提升到最高位: 9 9 6 0 2... ... -1 //表示大數的值爲-20699 void AjustEncodeArray(int *&result,unsigned int iMaxNum) { int i = 0; unsigned int iNumFlag = 0; unsigned int iWeight = 0; //有效最高位的權值 //遍歷找出有效數據的最高位的下標(正負都有可能) for(i=iMaxNum-1;i>=0;--i) { if(result[i]!=0) { iNumFlag=i; break; } } //從低位開始往上調整,規則:大於10的正數要進位,負數要借位 for(i=0;i<iNumFlag;++i) { //進位 if(result[i]>0) { result[i+1] += result[i]/10; //十位以上都要進位 result[i] = result[i]%10; //調整進位後的當前位 } else if(result[i]<0) { result[i+1] -= 1; //忽略高位是否可借位,強行借位 result[i] = 10+result[i]; } } //若有效最高位爲負數,需要對負號進行提升,就是對高位與餘下低位進行一次減法 if(result[iNumFlag]<0) { iWeight = -result[iNumFlag]; int iMinuend[2*MAX_DIGIT]={0}; iMinuend[iNumFlag] = iWeight; //被減數 result[iNumFlag] = 0; //構造減數 for(i=0;i<iNumFlag+1;++i) { result[i] = (iMinuend[i]-result[i]); } //調整借位 for(i=0;i<iNumFlag;++i) { if(result[i]<0) { result[i+1] -= 1; result[i] = 10+result[i]; } } result[iMaxNum-1] = -1; } } void PrintBigNum(int *result) { int index = MAX_DIGIT*2-1; bool bNegative = false; //從最高位找到第一個不爲負的位,從此位開始爲有效值 while(result[index]<=0) { if(result[index]<0) { bNegative = true; } index--; } if(bNegative) { printf("-"); } for(int i=index;i>=0;--i) { printf("%d",result[i]); } printf("/n"); } void CArray2revDigitArray(char *cArray,int *DigitArray,unsigned int iNum) { int i = 0; unsigned int iLen = strlen(cArray); //初始化DigitArray for(i=0; i<iNum; ++i) { DigitArray[i] = 0; } for(i=0; i<iLen; ++i) { DigitArray[iLen-1-i] = cArray[i]-'0'; } } int main() { int a[MAX_DIGIT],b[MAX_DIGIT],resultArray[2*MAX_DIGIT]; char cArray1[MAX_DIGIT],cArray2[MAX_DIGIT]; int ret = 0; int *result = (int *)resultArray; printf("Input multiplier:/n"); scanf("%s",cArray1); printf("Input multiplicand:/n"); scanf("%s",cArray2); CArray2revDigitArray(cArray1,a,MAX_DIGIT); CArray2revDigitArray(cArray2,b,MAX_DIGIT); ret=Multiply(a,b,result); if(ret!=0) { printf("Multiply error,ret:%d/n",ret); return -1; } PrintBigNum(result); ret=Add(a,b,result); if(ret!=0) { printf("Multiply error,ret:%d/n",ret); return -1; } PrintBigNum(result); ret=Sub(a,b,result); if(ret!=0) { printf("Multiply error,ret:%d/n",ret); return -1; } PrintBigNum(result); return 0; }
覺得對減法的處理有點繁瑣,希望可以簡化。
時間平復了一時的衝動,卻加深了挫敗感。
每當我看着大海的時候,我總想找人談談。但當我和人交談時,我又總想去看看大海。 —— 村上
黃昏時偷來你的肋骨釀酒 百年後醉的有血有肉 目錄 原理 舉例 代碼實現 原理 快速排序是冒泡排序的改進,思想是分治法。也是通過不斷比較和交換元素實現排序(每次邏輯取一個基準元素,每個基準元素參與多次循環和其他元素的交
篳路藍縷,以啓山林。撫有蠻夷,以屬華夏。不鳴則已,一鳴驚人。
某同學在網上留的筆試題如下: 函數實現將網址進行如下操作www.google.com轉成com.google.www 及mail.netease.com轉成com.netease.mail不允許用STL,空間爲0(1) 思路如下: 1.先
使用0元素數據來實現變長的TLV數據結構,這種實現方法巧妙,使用方便,但注意老版本C不支持這種定義,C99支持。 如下結構體: struct pkt { UINT16 pkt_type; UINT16 pkt_len;
目錄 爲什麼數組要從 0 開始編號,而不是從 1 開始呢? 數組是如何實現根據下標隨機訪問數組元素? 數組和鏈表的區別? 插入操作 刪除操作 數組是最基礎、最簡單的數據結構。 數組用一塊連續的內存空間,來存儲相同類型的一組數據,最大的特
有些同學可能會很困惑:時間複雜度的表示怎麼一會兒是 大O, 一會兒是(讀作Omega),一會兒又是(讀作Theta)? 這三個符號略有區別,要用數學語言才能描述,略顯枯燥,我們到後面再聊大O、、表示時間複雜度的區別,大家先記住,
數據結構指的是“一組數據的存儲結構”, 算法指的是“操作數據的一組方法”。 數據結構是爲算法服務的,算法是要作用再特定的數據結構上的。 效率和資源消耗的度量衡--複雜度分析。 數據結構和算法解決是“如何讓計算機更快時間、更省空間的解
刷力扣,不得不說每個簡單的題下面,騷操作都不少 ;簡直把時間&空間複雜度和代碼簡潔性玩到了極致;導致有些代碼對於我這菜雞太難讀懂了。 所以我在記錄自己的愚蠢的代碼同時,考慮了自己的理解能力,和力扣題目的評論區精華,選擇了而我能看得懂的較
有向圖的拓撲排序是它的頂點的線性排序,比如任意 邊 uv 對於 它的頂點 u 和 頂點 v, u v按照 u 在前 v在後的順序排序。 注意:只有 有向無環圖 (DAG) 纔有拓撲排序, 如果一個圖 是有環 的圖那麼它不存在拓撲排序。
現在的項目是在做的超大規模的矩陣的奇異值分解,其目的是對數據進行求特徵值,做爲聚類算法的輸入 因爲很久以前就想過聚類單詞,所以對聚類算法比較感興趣。目前只聽說了K-means算法,大概的思想就是,把每個數據看做向量空間中的點,然後進行
1月準備考數據結構;成天窩在家裏鼓搗這玩意.現在勉強弄出了個可以實用的樹和圖的庫.接下來是實現樹和圖的各種算法.說到算法必然就要有用來測試的數據.這幾天在弄樹.剛開始是從文件系統來構造.但是每次從硬盤文件系統構造
背景 震驚原因 今天在刷到藍橋杯算法題的時候,竟然遇到了這樣一道算法題(具體如下文),真是打破了我對算法的常規認知,怪我太單純? 看到題目可能莫名其妙,但是答案竟然只需要輸出一個yes即可通過。 …(心裏飄過無數) 題目 資源限制
矩陣簡介 矩陣加、減法 矩陣加法比較簡單,就是相同位置的數字加一下。 減法類似,比較簡單,略。 矩陣乘法 矩陣乘以常數 矩陣乘以一個常數,就是所有位置都乘以這個數(也比較簡單)。 矩陣乘以矩陣 矩陣乘以矩陣就有些複雜了 計算