1.高精度描述
高精度大数就是指利用已有的类型无法进行保存和运算的数字。
2.高精度大数模拟运算的步骤
①先将高精度大数存入到一个字符数组中
②针对字符数组取模拟加减乘除的运算
3.将高精度存入一个字符数组的方法
①方法介绍
利用string 类,先定义一个string s,然后输入这个字符串,注意,在这个string类中,其实也是把字符串一个一个字符地存入到字符数组中,所以,我们可以像 C 语言中一样,将 string 对象当做一个数组,然后使用数组下标的方式来访问字符串中的元素(索引号从 0 开始)
②实现代码如下
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
string s="1234567";
int a[100];
int len=s.lengrh();//求出这个字符串的长度
for(int i=0;i<s;i++)//把字符串一一对应存入字符数组中
{
a[i]=s[i]-'0';
}
for(int j=0;j<s;j++)//输出字符数组
{
cout<<a[i];
}
}
③易错点
易错!!!因为字符1,2,3对应的ASCII码不是1,2,3,而是60几,所以要减去‘0’字符的ASCII码,才能够得到字符1,2,3对应的整型量1,2,3
④string类的各个操作详解
https://www.cnblogs.com/tongye/archive/2019/04/24/10760154.html
⑤如何将一个整型变量转化为一个字符型变量
只需要在整型变量基础上加上48即可
具体请看:https://jingyan.baidu.com/article/59a015e30f12b0f7948865f8.html
⑥将整型数据转化成字符串的方法
可以先将整型数据一个一个存进字符数组,然后再将字符数组转化为字符串就行了,因为字符串转化为字符数组很容易,字符数组可以直接赋值给字符串变量。字符串类其实就是一个字符数组,字符数组转化为字符串的代码如下:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char a[5]="Hello";
string b;
for(int i=0;i<4;i++)
{
b[i]=a[i];
}
}
也可以使用C语言的库函数itoa()
具体使用链接请看:
<1>https://www.cnblogs.com/ralap7/p/9171613.html
<2>https://blog.csdn.net/lwj103862095/article/details/12005105
<3>https://blog.csdn.net/skyereeee/article/details/7059565
C++的话就要用_itoa_s函数,其实是和itoa()函数一样的
链接请看:https://www.cnblogs.com/ylwn817/archive/2011/03/22/1991633.html
⑦String类的各种操作函数,包括获取长度,字符串比较等
https://www.cnblogs.com/tongye/archive/2019/04/24/10760154.html
注意:
在用字符串比较的时候,它自带的比较方法是从待比较的两个字符串的第一个字符开始比,然后一直找到这两个字符串不同的字符,然后比较这两个字符的大小分胜负。所以,当如果字符串为数值型字符串时,比较大小要限制长度
string min = a[left];
for (int i = left; i <= right; i++)
{
if (a[i].length() < min.length())//限制长度
{
min = a[i];
}
if (a[i].length() == min.length())//通过长度来先第一步比较
{
if (a[i] < min)
{
min = a[i];
}
}
}
cout << min << endl;
4.针对字符数组模拟加减乘除的运算
详细讲解网站,请看
https://blog.csdn.net/weixin_45761327/article/details/107579618.
大数相加易错点:
①注意!由于这个网址上的例题是用字符串的读入输入的数据的,所以两个数位数会出现不一样的情况,因此,当要把两个字符串存入到整型数组中时,先要计算两个字符串的长度(调用.length()),然后分别存入整型数组中,另外用来存这两个数组相加后的结果的数组的长度可以适当在max上+1,防止进位溢出
②最后模拟计算完之后要清楚多余的0,此时要注意有一个特殊情况就是当两个数输入的都为0时,结果也为0,所以此时不能把这个0清走,所以要注意分类
③大数相加
<1>思想:
先用一个字符串读取两个输入,然后再将其字符串分别逐个字符存入到整型数组中(要减去‘0’,低下标从两数的最低位开始存,方便模拟运算),最后对这两个数组进行一个相加模拟,然后存入到另一个整型数组中
<2>代码:
#include <iostream>
#include <string>
#include <istream>
using namespace std;
int a[5050]={0};
int b[5050]={0};
int c[5050]={0};
int main ()
{
string num1,number;
cin>>num1>>number;
int n=num1.length(),m=number.length();
int max=m>n?m:n+1;//多一位防止进位
for(int i=0,j=n-1;i<n;i++,j--)
{
a[i]=num1[j]-'0';
}
for(int i=0,j=m-1;i<m;i++,j--)
{
b[i]=number[j]-'0';
}
for(int z=0;z<max;z++)
{
c[z]=c[z]+a[z]+b[z];
if(c[z]>=10)
{
c[z]=c[z]%10;
c[z+1]=c[z+1]+1;
}
}
int k=max;
while(c[k]==0&&k>0)//限制k》0是保证输入全为0时,数组不溢出 ,防止把唯一的零清掉
{
k--;
}
while(k>=0)
{
cout<<c[k--];
}
}
大数相乘易错点
①注意,大数相乘其中最重要的代码是c[i+j]+=a[i]*b[j];,意思是a的第i位乘以b的第j位要存在c的第i+j位上,可以自己画一个乘法的列式,确实如此。
②先在第三个数组里面存入全部没有处理进位的数,模拟完乘法之后再去处理进位
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
//用字符串读入两个大数
string num1 ,num2;
cin>>num1>>num2;
//获取两个大数的位数
int n=num1.length(),m=num2.length();
int a[n],b[m];//定义两个整形数组用于待会存储这两个大数的每一位
int i,j;
//用整形数组从低位到高位存储这两个大数
for(i=0,j=n-1;i<n;i++,j--)
a[i]=num1[j]-'0';
for(i=0,j=m-1;i<m;i++,j--)
b[i]=num2[j]-'0';
/*******到此为止以上都是大数的保存,下面将模拟大数乘法的运算***********/
//定义第三个数组来存储结果
int c[3000]={0};
for(i=0;i<n;i++)
for(j=0;j<m;j++){
c[i+j]+=a[i]*b[j];
}
//处理进位的情况
for(i=0;i<n+m;i++){
if(c[i]>=10){
c[i+1]+=c[i]/10;
c[i]%=10;
}
}
//打印结果
for(j=2999;j>0;j--){
if(c[j]!=0)
break;
}
for(i=j;i>=0;i--)
printf("%d",c[i]);
printf("\n");
return 0;
}
例题:
用高精度实现代码如下:
#include <stdio.h>
#include <cstdlib>
#include<algorithm>
#include <iostream>
#include <stdlib.h>
#include "string"
using namespace std;
string a[100006];
void exchange(int flag, int left, int right, string a[], int n)
{
if (flag == 1)
{
for (int i = left; i <= right; i++)
{
string q = a[i];
int len = a[i].length();
int number = 0;
for (int i = 0; i < len; i++)
{
number = number + (q[i] - '0');
}
char str[200] = { '0' };
int count2 = 0;
while (number != 0)
{
int a = number % 10;
char c = a + '0';
str[count2] = c;
number = number / 10;
count2++;
}
char str3[200] = { '0' };
for (int k = count2 - 1,g=0; k >= 0; k--,g++)
{
str3[g]=str[k];
}
string p = str3;
a[i] = p;
}
}
if (flag == 2)
{
string min = a[left];
for (int i = left; i <= right; i++)
{
if (a[i].length() < min.length())
{
min = a[i];
}
if (a[i].length() == min.length())
{
if (a[i] < min)
{
min = a[i];
}
}
}
cout << min << endl;
}
}
int main()
{
int count, b, c, d, e;
scanf("%d %d", &count, &b);
for (int i = 1; i <= count; i++)
{
cin >> a[i];
}
while (b != 0)
{
scanf("%d %d %d", &c, &d, &e);
exchange(c, d, e, a, count);
b--;
}
return 0;
}