今天完善成的c++大整数乘法和除法,算了一个最小公约数。
是VIJOS-p1047,希望大家支持。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 200
void StringToLargeInt(char *stra, char *strb, int *inta, int *intb, int *la, int *lb)
{
*la = (int)strlen(stra);
*lb = (int)strlen(strb);
for(int i=0;i<*la;i++)
{
inta[i]=stra[*la-i-1]-'0';
}
for(int i=0;i<*lb;i++)
{
intb[i]=strb[*lb-i-1]-'0';
}
}
void LargeIntAdd(int *inta, int la, int *intb, int lb, int *intc,int *lc)
{
int min, max, i;
int *temp;
memset(intc,0, *lc * sizeof(int));
if(la>lb)
{
max = la;
min = lb;
temp = inta;
}
else
{
max = lb;
min = lb;
temp = intb;
}
for(i=0;i<min;i++)
{
intc[i] += inta[i] + intb[i];
if(intc[i] >= 10)
{
intc[i+1]++;
intc[i]-=10;
}
}
while(i < max) {
intc[i] += temp[i];
if(intc[i] >= 10)
{
intc[i+1]++;
intc[i]-=10;
}
i++;
}
if(intc[max] == 0)
*lc = max ;
else
*lc = max + 1;
}
int LargeIntCompare(int *inta, int la, int *intb, int lb)
{
if(la > lb)
return 1;
else if (la < lb)
return -1;
else
{
for(int i = la-1;i >= 0;i--)
{
if(inta[i] > intb[i])
return 1;
else if (inta[i] < intb[i])
return -1;
}
return 0;
}
}
void LargeIntSubtract(int *inta, int *la, int *intb, int lb)
{
int i;
for(i=0;i<*la;i++)
{
if(i<lb)
{
inta[i]=inta[i]-intb[i];
if(inta[i]<0)
{
inta[i+1]--;
inta[i]+=10;
}
}
else
{
if(inta[i]<0)
{
inta[i+1]--;
inta[i]+=10;
}
}
}
for(i = *la -1; i > 0 && inta[i] == 0; i--);
*la= i + 1;
}
int AllignLargeInt(int *intb, int la, int *lb)
{
int x = la - *lb;
if(x == 0)
return 0;
else
{
for(int i = la-1; i >= 0; i--)
{
if(i>=x)
intb[i] = intb[i-x];
else
intb[i]=0;
}
}
*lb=la;
return x;
}
int InvertAllignLargeInt(int *intb, int *lb, int nZeros)
{
if(nZeros == 0) return 0;
for(int i = nZeros; i <= *lb - 1; i++)
intb[i - nZeros] = intb[i];
*lb -= nZeros;
return 1;
}
void LargeIntDevide(int *inta, int *la, int *intb, int *lb, int *intc, int *lc, int *intd,int *ld)
{
int nAddZeros = AllignLargeInt(intb, *la, lb);
int i,j;
memset(intc,0,*lc *sizeof(int));
memset(intd,0,*ld *sizeof(int));
for(i = 0; i <= nAddZeros; i++)
{
j = 0;
while(LargeIntCompare(inta, *la, intb + i, *lb - i) >= 0)
{
LargeIntSubtract(inta, la, intb + i, *lb - i);
j++;
}
if (j > 0)
intc[nAddZeros - i] = j;
}
for(i = nAddZeros; i > 0 && intc[i] == 0; i--);
*lc = i + 1;
for(i = *la - 1; i >= 0 && inta[i] == 0; i--);
for(j = 0; j <= i ; j++)
intd[j] = inta[j];
*ld = i + 1;
}
void LargeIntMode(int *inta, int *la, int *intb, int *lb)
{
int nAddZeros = AllignLargeInt(intb, *la, lb);
int i;
for(i = 0; i <= nAddZeros; i++)
{
while(LargeIntCompare(inta, *la, intb + i, *lb - i) >= 0)
LargeIntSubtract(inta, la, intb + i, *lb - i);
}
for(i = *la - 1; i >= 0 && inta[i] == 0; i--);
*la = i + 1;
InvertAllignLargeInt(intb, lb, nAddZeros);
}
int LargeIntCommonDivisor(int *inta, int *la, int *intb, int *lb)
{
int *largeInt, *smallInt;
int *largeIntLen, *smallIntLen;
int *tempInt, *tempIntLen;
int res;
res = LargeIntCompare(inta, *la, intb, *lb);
if (res == 0) return 0;
if (res > 0) {
largeInt = inta;
smallInt = intb;
largeIntLen = la;
smallIntLen = lb;
}
else
{
largeInt = intb;
smallInt = inta;
largeIntLen = lb;
smallIntLen = la;
}
while (res != 0) {
LargeIntMode(largeInt, largeIntLen, smallInt, smallIntLen);
if (*largeIntLen == 0) break;
tempInt = largeInt;
largeInt = smallInt;
smallInt = tempInt;
tempIntLen = largeIntLen;
largeIntLen = smallIntLen;
smallIntLen = tempIntLen;
res = LargeIntCompare(largeInt, *largeIntLen, smallInt, *smallIntLen);
}
for(int i = 0; i < *smallIntLen; i++)
inta[i] = smallInt[i];
*la = *smallIntLen;
return 0;
}
void LargeIntMultiply(int *inta, int *la, int *intb, int *lb, int *intc, int *lc)
{
int i,j,k;
i = j = k = 0;
memset(intc,0,sizeof(int) * (*lc + 1));
for(i = 0; i < *la; i++)
for(j = 0; j < *lb; j++)
{
intc[i+j] += inta[i] * intb[j];
}
for (k = 0; k < *la + *lb - 1; k++ )
if(intc[k] >= 10) {
intc[k+1] += intc[k] / 10;
intc[k] = intc[k] % 10;
}
if (intc[k] != 0)
*lc = k + 1;
else
*lc = k;
}
char* LargeIntPrint(int *inta, int la){
char *temp = (char *)malloc(la +1);
int i,j;
for (i = la - 1,j = 0; i >= 0; i--,j++)
sprintf(temp + j , "%1d",inta[i]);
temp[j] = 0;
return temp;
}
int main()
{
char stra[MAXLEN+1];
char strb[MAXLEN+1];
int inta[MAXLEN+1];
int intb[MAXLEN+1];
int intc[MAXLEN+1];
int intd[MAXLEN+1];
int la = 0;
int lb = 0;
int lc = 0;
int ld = 0;
char *res;
memset(stra,0,MAXLEN+1);
memset(strb,0,MAXLEN+1);
memset(inta,0,(MAXLEN+1) * sizeof(int));
memset(intb,0,(MAXLEN+1) * sizeof(int));
memset(intc,0,(MAXLEN+1) * sizeof(int));
memset(intd,0,(MAXLEN+1) * sizeof(int));
scanf("%s",stra);
scanf("%s",strb);
StringToLargeInt(stra, strb, inta, intb, &la, &lb);
LargeIntMultiply(inta, &la, intb, &lb, intc, &lc);
LargeIntCommonDivisor(inta, &la, intb, &lb);
LargeIntDevide(intc, &lc, inta, &la, intd, &ld, intb, &lb);
res = LargeIntPrint(intd, ld);
printf("%s", res);
free(res);
return 0;
}