【算法学习——高精度】①补充了如何将一个字符串存入到一个字符数组里②当字符‘0’‘1’‘2’....等转化为整型变量时易错知识点③高精度运算模拟④将整型变量转化为字符型变量 ⑤String类的各种操作

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值