高精算法
对于高精算法其实我很 不 喜欢,
算法题没事搞这么大数据干嘛,不是为难人吗???
吐槽归吐槽下面我们进入正题。
高精算法的思想,我们由小学列式计算的方法很容易得出
首先我们定义三个数组来储存数据
注意:
以下算法 ~[0]储存高精数位数
数字需使用倒序存储
int sum1[MAXN];//用于计算的高精数1
int sum2[MAXN];//用于计算的高精数2
int result[MAXN];//用于记录答案的高精数
进行计算前别忘了将result初始化,不然可能计算错误哦!
sum1,sum2只需要保证sum[0]相应位数的数字正确即可,其他位是否为零无影响。
#include<cstring>
memset(result,0,sizeof(result));
高精加
高精加低精
void add1(int *sum1,int sum2,int *result)
{
int i;
for (i = 1; i <= sum1[0]; i++)
{
result[i] = sum1[i];
}
result[1] += sum2;
result[0] = sum1[0];
for (i = 1; i <= result[0]; i++) //对每一位进行处理,使其大小位于0~9
{
result[i + 1] += result[i] / 10;
result[i] %= 10;
if (i == result[0]) //达到初始位最高长度后,后一位若不为零,位长度加一,继续处理
if(result[i+1]>0)
result[0] += 1;
}
}
高精加高精
void add2(int *sum1,int *sum2,int *result)
{
int i;
int max_len,min_len;
min_len = sum1[0] < sum2[0] ? sum1[0] : sum2[0];
max_len = sum1[0] > sum2[0] ? sum1[0] : sum2[0];
for (i = 1; i <= min_len; i++)//先将每一位相加再进行处理
{
result[i] = sum1[i] + sum2[i];
}
if(sum1[0]>sum2[0])
for (i = min_len+1; i <= max_len; i++)
{
result[i] = sum1[i];
}
else
for (i = min_len+1; i <= max_len; i++)
{
result[i] = sum2[i];
}
result[0] = max_len;
for (i = 1; i <= result[0]; i++)//原理与上面相同
{
result[i + 1] += result[i] / 10;
result[i] %= 10;
if (i == result[0])
if(result[i+1]>0)
result[0] += 1;
}
}
高精减
注意要使sum1>sum2
高精减低精
void sub1(int* sum1, int sum2, int* result)
{
int i,j;
for (i = 1; i <= sum1[0]; i++)
{
result[i] = sum1[i];
}
result[1] -= sum2;
result[0] = sum1[0];
for (i = 1; i <= result[0]; i++)
{
if (result[i] < 0) //对每一位进行处理,使其大小位于0~9
{
result[i + 1] -= (result[i] + 1) / (-10) + 1;
if (result[i] % 10 != 0)
result[i] = result[i] % 10 + 10;
else
result[i] = 0;
}
}
for (i = result[0]; i >= 2; i--) //最高位长判断
if (result[i] == 0)
{
result[0] --;
}
else
break;
}
高精减高精
void sub2(int* sum1, int* sum2, int* result)
{
int i,j;
for (i = 1; i <= sum2[0]; i++) //先将每一位相减再进行处理
{
result[i] = sum1[i] - sum2[i];
}
for (i = sum2[0]+1; i <= sum1[0]; i++)
{
result[i] = sum1[i];
}
result[0] = sum1[0];
////原理与上面相同
for (i = 1; i <= result[0]; i++)
{
if (result[i] < 0)
{
result[i + 1] -= (result[i] + 1) / (-10) + 1;
if (result[i] % 10 != 0)
result[i] = result[i] % 10 + 10;
else
result[i] = 0;
}
}
for (i = result[0]; i >= 2; i--)
if (result[i] == 0)
{
result[0] --;
}
else
break;
}
高精乘
高精乘低精
void mult1(int *sum1,int sum2,int *result)
{
int i;
for (i = 1; i <= sum1[0]; i++)//将sum1每一位与sum2相乘,之后进行处理
{
result[i] = sum1[i]*sum2;
}
result[0] = sum1[0];
for (i = 1; i <= result[0]; i++)//处理原理与高精加一致
{
result[i + 1] += result[i] / 10;
result[i] %= 10;
if (i == result[0])
if(result[i+1]>0)
result[0] += 1;
}
}
高精乘高精
void mult2(int* sum1, int* sum2, int* result)
{
int i,j;
for (i = 1; i <= sum1[0]; i++)//参考一下小学的列示计算???
{
for (j = 1; j <= sum2[0]; j++)
result[j+i-1] += sum1[i] * sum2[j];
}
result[0] = sum1[0] < sum2[0] ? sum1[0] : sum2[0];
for (i = 1; i <= result[0]; i++)
{
result[i + 1] += result[i] / 10;
result[i] %= 10;
if (i == result[0])
if (result[i + 1] > 0)
result[0] += 1;
}
}
高精除
高精除低精
void div1(int* sum1, int sum2, int* result)
{
int i;
for (i = sum1[0]; i >= 2; i--)//根据小学列式相除而来
{
result[i - 1] = (sum1[i] + result[i]) % sum2 * 10;//使result[i - 1]中保存上一位的余数
//与sum1[i-1]相加便可得目前所处位的被除数
result[i] = (sum1[i] + result[i])/sum2;//保存相除结果
}
result[1] = (sum1[1] + result[1]) / sum2;
result[0] = sum1[0];
for (i = result[0]; i >= 2; i--)//最高位判断
if (result[i] == 0)
{
result[0] --;
}
else
break;
}
高精除高精
写这个代码的时候调bug调了好久。。。。
思想还是挺简单的
void sumCpy(int* sum2, int* divSum, int place)//用于对除法进行减法模拟,
//对于除数按照其相对应的位进行扩大,储存在divSum中
{
int i;
for (i = place; i < place + sum2[0]; i++)
{
divSum[i] = sum2[i - place + 1];
}
divSum[0] = place + sum2[0] - 1;
}
int sumCmp(int* sum1, int* sum2)//对 divSum 与 原数字被减后剩余的数字 进行比较的算法
//从高位到地位对比
{
int i;
if (sum1[0] > sum2[0])
{
return 1;
}
else
if (sum1[0] == sum2[0])
{
for (i = sum1[0]; i >= 2; i--)
if (sum1[i] > sum2[i])
return 1;
else
if(sum1[i] < sum2[i])
return 0;
if (sum1[1] >= sum2[1])
return 1;
}
return 0;
}
void sub2(int* sum1, int* sum2, int* result)//前面写过的高精减高精算法,用于减法计算
{
int i, j;
for (i = 1; i <= sum2[0]; i++)
{
result[i] = sum1[i] - sum2[i];
}
for (i = sum2[0] + 1; i <= sum1[0]; i++)
{
result[i] = sum1[i];
}
result[0] = sum1[0];
for (i = 1; i <= result[0]; i++)
{
if (result[i] < 0)
{
result[i + 1] -= (result[i] + 1) / (-10) + 1;
if (result[i] % 10 != 0)
result[i] = result[i] % 10 + 10;
else
result[i] = 0;
}
}
for (i = result[0]; i >= 2; i--)
if (result[i] == 0)
{
result[0] --;
}
else
break;
}
void div2(int* sum1, int* sum2, int* result)
{
int i, j;
int rem[100];
int divSum[100];
void sumCpy(int* sum2, int* divSum, int place);
int sumCmp(int* sum1, int* sum2);
void sub2(int* sum1, int* sum2, int* result);
memset(divSum, 0, sizeof(divSum));
memset(rem, 0, sizeof(rem));
for (i = 0; i <= sum1[0]; i++)//将被除数储存到rem中用于计算,rem代表剩余数字大小
{
rem[i] = sum1[i];
}
for (i = sum1[0]; i >= 1; i--)//主体,从高位到地位进行模拟
{
sumCpy(sum2, divSum, i);
while (sumCmp(rem, divSum))//如果rem>divSum则进行一次减法计算
{
sub2(rem, divSum, rem);//观察sub2算法,其实可以将第三个数组写为rem,
//将结果输出到rem中,省去了再次赋值
result[i] += 1;//在所处位每进行一次减法计算,该位的sum便加一
}
}
result[0] = sum1[0];
for (i = result[0]; i >= 2; i--)//最高位判断
if (result[i] == 0)
{
result[0] --;
}
else
break;
}

浙公网安备 33010602011771号