今天花了一天的時間在Linux 系統上完成了歐拉計劃第13題的Larger Sum編程(花費的時間有點長啊)。既然耗了這麼長的時間,那就要好好的總結一下,不然也對不起這一天的時間。這次主要是在ubantu 上編程,簡單的設計到了編譯、調試、鏈接和簡單的編寫Makefile。 Larger Sum 中 ...
今天花了一天的時間在Linux 系統上完成了歐拉計劃第13題的Larger Sum編程(花費的時間有點長啊)。既然耗了這麼長的時間,那就要好好的總結一下,不然也對不起這一天的時間。這次主要是在ubantu 上編程,簡單的設計到了編譯、調試、鏈接和簡單的編寫Makefile。
Larger Sum 中涉及到了超大數(50位)的計算,在C編譯語言中,int 為32位,最大的整數long long int也只有pow(2,64)大約19位,這樣完全不能用簡單的四和運算來求和。於是代碼中,我使用字元串的每位累加來求和。代碼中最主要的幾點如下:
1、 怎樣獲取100*50 個數:
對於100個50位的整數,代碼中採用文本的的方式,使用read讀取每行的文本到二維數組string[100][51]中。代碼中使用了open創建Larger_sum.txt的文件描述符,使用creat 創建不存在的cc.txt文本(用於判斷是否能夠正常的讀取文本中的100個50位數)。
2、求和100個50位數的演算法:
對於100個50位的數,代碼中採用二維數組的方式,從低位依次對100個數進行求和,如string[i][0]+string[i][1]+...+srting[i][49]+ 商值,再進行取餘、求商。每次運算的餘數保存在int NewStr[51]的整型數組中,最後一次運算的商值則保持在NewStr[50]中。
3、簡單編寫Make file:
all:main.o
gcc -o all main.c
clean:
rm all main.o
註意:1、在代碼運行過程中,出現了warning:function returns address of local variable, 翻譯過來為 “警告:本地函數返回的地址”。這是由於Cal_Digit函數中,代碼沒有給返回的指針數值分配固定的地址,而該函數中的局部變數在執行完後,會自動釋放分配的記憶體。導致在主函數中調用失敗。代碼中使用malloc分配固定的記憶體,再在代碼執行完之前釋放記憶體。
2、warning: incompatible implicit declaration of built -in function [ enable by default], 這是用於調用了公共函數沒有聲明頭文件 string.h 和stdlib.h。
3、在Linux 下怎樣精確的計算程式執行的時間。可以通過三個函數來實現:
1)clock()函數;其聲明的定義在time.h 頭文件中
2)time()函數;
3)gettimeofday()函數;
1 #include <string.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 int *Cal_Digit(char *string); 6 int main() 7 { 8 //read 100*50 digit into string 9 int fp, fp1; 10 static int i = 0; 11 static int j = 0; 12 char string[100][51]= {0}; 13 int *result; 14 clock_t time1,time2; 15 time1 = clock(); 16 if((fp=open("//home//yb//test//Project_Euler//13.Larger_sum//Larger_sum.txt", 0, 0)) == -1) 17 { 18 printf("OPEN FILE ERROR\n"); 19 } 20 creat("//home//yb//test//Project_Euler//13.Larger_sum//cc.txt"); 21 if((fp1=open("//home//yb//test//Project_Euler//13.Larger_sum//cc.txt", 2, 0)) == -1) 22 { 23 printf("OPEN FILE ERROR\n"); 24 } 25 while( read(fp, string[i], 51) > 0) 26 { 27 write(fp1, string[i], 51); 28 i++; 29 } 30 close(fp); 31 close(fp1); 32 33 //calculate 100*50 digit 34 printf("Calcutate:\n"); 35 result = Cal_Digit(&string[0][0]); 36 37 //printf result 38 for(i=50; i>=0;i--) 39 { 40 printf("%d", *(result+i)); 41 } 42 free(result); 43 time2 = clock(); 44 printf("\nRun Time:%fs \n", (double)(time2-time1)/CLOCKS_PER_SEC); 45 return 0; 46 } 47 int *Cal_Digit(char *string) 48 { 49 int *NewStr; 50 int i =0 , j=0; 51 int z =0; 52 int temp =0; 53 int CarryBit = 0; 54 NewStr = (int*)malloc(sizeof(int)*50); 55 56 for(i=49; i>=0; i--) 57 { 58 temp = CarryBit; 59 for(j=0; j<100; j++) 60 { 61 temp += *(string + j*51 + i) - 48; 62 } 63 NewStr[49-i]= temp%10; 64 CarryBit = temp/10; 65 if(i == 0) 66 { 67 NewStr[50] = CarryBit; 68 } 69 } 70 return NewStr; 71 }