1. 程式人生 > >1074 宇宙無敵加法器 ——c++實現

1074 宇宙無敵加法器 ——c++實現

題目

1074 宇宙無敵加法器 (20 分)

地球人習慣使用十進位制數,並且預設一個數字的每一位都是十進位制的。而在 PAT 星人開掛的世界裡,每個數字的每一位都是不同進位制的,這種神奇的數字稱為“PAT數”。每個 PAT 星人都必須熟記各位數字的進製表,例如“……0527”就表示最低位是 7 進位制數、第 2 位是 2 進位制數、第 3 位是 5 進位制數、第 4 位是 10 進位制數,等等。每一位的進位制 d 或者是 0(表示十進位制)、或者是 [2,9] 區間內的整數。理論上這個進製表應該包含無窮多位數字,但從實際應用出發,PAT 星人通常只需要記住前 20 位就夠用了,以後各位預設為 10 進位制。

在這樣的數字系統中,即使是簡單的加法運算也變得不簡單。例如對應進製表“0527”,該如何計算“6203 + 415”呢?我們得首先計算最低位:3 + 5 = 8;因為最低位是 7 進位制的,所以我們得到 1 和 1 個進位。第 2 位是:0 + 1 + 1(進位)= 2;因為此位是 2 進位制的,所以我們得到 0 和 1 個進位。第 3 位是:2 + 4 + 1(進位)= 7;因為此位是 5 進位制的,所以我們得到 2 和 1 個進位。第 4 位是:6 + 1(進位)= 7;因為此位是 10 進位制的,所以我們就得到 7。最後我們得到:6203 + 415 = 7201。

輸入格式:

輸入首先在第一行給出一個 N 位的進製表(0 < N ≤ 20),以回車結束。 隨後兩行,每行給出一個不超過 N 位的非負的 PAT 數。

輸出格式:

在一行中輸出兩個 PAT 數之和。

輸入樣例:

30527
06203
415

輸出樣例:

7201

演算法

資料結構:用C語言程式設計由於無法定義字串型別,一般定義成字元陣列來儲存。字元陣列儲存時會預設在最後加上一個’\0‘,但是統計字元陣列長度的時候,不統計末尾的’\0‘。

無論是C/C++中,獲得字元陣列的長度可以使用strlen函式,如計算字元陣列a的長度的語句是i=strlen(a)。
標頭檔案:#include <string.h>;
功能:計算給定字串的(unsigned int型)長度,不包括'\0'在內;
引數說明:要計算長度的字串陣列的首地址


返回值說明:要計算字串的長度,不包括'\0'。

顯然sBase的長度比sA,sB大,因此在需要將sA,sB,sBase的各位數字取出來的時候就要注意,sA,sB不存在高位就要補零,同時sBase的0相當於10要注意,因此有下面的程式碼:

for(int i = 0; i < nBase; i++) { 
                /* Transform corresponding digit to integers */ 
		a = nA <= i ? 0 : sA[nA - i - 1] - '0'; 
		b = nB <= i ? 0 : sB[nB - i - 1] - '0'; 
		base = sBase[nBase - i - 1] - '0'; 
		base = base == 0 ? 10 : base; 

後面就需要計算sA,sB對應位的數字之和,同時將計算結果儲存在sSum,要注意可能會有進位。這裡運算的都是整數,因此後面需要將其轉換為字元。

/* Calculate ith digit A + B, temperately store integers here */ 
		sSum[nS - i - 1] += a + b; 
		sSum[nS - i - 2] += sSum[nS - i - 1] / base; 
		sSum[nS - i - 1] = sSum[nS - i - 1] % base; 

將計算的sSum中的數字字元讀出來可以採用將數字與‘0’相加的形式,就可以得到對應的數字字元(ASCII碼)。在輸出時,找到第一個非零位開始輸出,注意puts()函式時輸出字串的,只要指明這個字串的首地址即可。

在輸出的時候,puts()函式會自動將字串結尾的‘\0'轉化成回車換行。輸出之後return 0,就會退出主函式main()。如果一直沒有找到非零位,則說明sA+sB=0,因此只需要輸出0即可。如果不寫這個條件,就會遺漏和為0的情況。

程式碼

#include <stdio.h> 
#include <string.h> 
int main() { 
	int nBase, nA, nB, nS = 21, base, a, b; 
	char sBase[21] = {0}, sA[21] = {0}, sB[21] = {0}, sSum[22] = {0}; 
	/* Read base table, number A and B into strings */ 
	scanf("%s %s %s", sBase, sA, sB); 
	nBase = strlen(sBase); 
	nA = strlen(sA); 
	nB = strlen(sB); 
	for(int i = 0; i < nBase; i++) { 
                /* Transform corresponding digit to integers */ 
		a = nA <= i ? 0 : sA[nA - i - 1] - '0'; 
		b = nB <= i ? 0 : sB[nB - i - 1] - '0'; 
		base = sBase[nBase - i - 1] - '0'; 
		base = base == 0 ? 10 : base; 
		/* Calculate ith digit A + B, temperately store integers here */ 
		sSum[nS - i - 1] += a + b; 
		sSum[nS - i - 2] += sSum[nS - i - 1] / base; 
		sSum[nS - i - 1] = sSum[nS - i - 1] % base; 
	} 
        /* Change to char type */ 
	for(int i = 0; i < 21; i++) sSum[i] += '0'; 
        /* find the first non-zero bit */ 
	for(int first = 0; first < 21; first++) 
		if(sSum[first] != 0 && sSum[first] != '0') { 
			puts(sSum + first); 
                        return 0; 
		} 
        /* If A + B = 0, then all bits are zero */ 
	printf("0"); 
	return 0; 
}

注意:

1如果往string變數中輸入一個數字輸出也是一個數字

2如果往string變數中輸入一個數字,但需要進行計算的時候需要-'0'

3通過兩個數字相加得到的第三個數字存入string中的時候,需要+'0'