2009年3月9日 星期一

Hex相乘

/*
輸入:兩個16進位的數(最多10位數)
輸出:十六進位的相乘結果
Sample input:
123456ABC
ABC123456
Sample output:
C36B1DC2784380B28

想法:因為以前教的乘法都是在10進位,但是學過二進位就知道,其實乘法都一樣,只是在不同的基底下
進位的門檻不一樣,例如10進位就是要10以上才進位,二進位是2以上進位,所以16進位要16以上進位。

Note:如果直接用電腦的計算機算會overflow,因為現在的compiler最多只支援到64bits
所以這題必須使用和大數乘法或者階層相同的概念去做。

Algo:
1.輸入16進位,把其當作字串
2.每個字元去轉換成整數陣列,每個位數存一格
3.乘法運算的實現(但每做完一個位數的乘法,就要檢查是否需要進位)
4.因為運算的結果都是0~15的數字,所以必須轉成十六進位

*/
#include <stdio.h>
#include <string.h>
#define N 10
int arr[N];
int arr2[N];
int sum[2*N];
char s1[N+1];
char s2[N+1];
int assign(char ch);
char trans(int n);

int main()
{
int n;
int len1, len2;
int i, j, k, m;
while (true)
{
gets(s1);
gets(s2);

len1 = strlen(s1);
len2 = strlen(s2);

for ( i = 0; i < N; i++)
arr[i] = arr2[i] = 0;

for ( i = 0; i < 2*N; i++)
sum[i] = 0;

for ( i = 0; i < len1; i++)
arr[i] = assign(s1[i]);

for ( i = 0; i < len2; i++)
arr2[i] = assign(s2[i]);

for ( i = len1-1, m = 0; i >= 0; i--, m++)
for ( j = len2-1, k = m; j >= 0; j--)
sum[k++] += arr[i]*arr2[j];


// 要從個位一直到最後一位
for ( j = 0; j < 2*N; j++)
{
// 從個位開始找是否 >= 16,要進位
if (sum[j] >= 16)
{
sum[j+1] += sum[j]/16;
sum[j] = sum[j]%16;
}
}

// 從大位數開始找到非零的!從2*N-1開始找
for ( i = 2*N-1; i >= 0; i--)
if (sum[i])
break;

for ( j = i; j >= 0; j--)
printf("%c", trans(sum[j]));

printf("\n");

}

return 0;
}

int assign(char ch)
{
if (ch >= '0' && ch <= '9')
return ch-'0';
else
return ch-'A'+10;
}

char trans(int n)
{
if (n >= 0 && n <= 9)
return n+'0';
else
return 'A' + n - 10;
}

沒有留言: