高精度计算(三)压位

高精压位

继承咱们(一)上的例题…A+B+C 链接

有兴趣的可以用上一篇的内容做一下这道神题

不出意外的话会出现下面的字样 Time Limit Exceeded ……

我们需要用一种特殊的技巧对上算法进行处理


压位思想

还记得我们存储数字的方式?

举个栗子:1234 + 1234这是之前的存储方式

实际上我们一个数组空间(int)是可以储存 2147483647 以下的数字 这样非常浪费 而且以上存储方式需要按位相加最后的计算次数是4

现在考虑这样的存储方式

这样相对上面的存储方式来说利用度较高 

理解方式:考虑二进制 十进制 十六进制 的计算方式 满2进1 满10进1 满16进1

那么以上的存储方式请理解为100进制的计算 也就是满100进1

按照这样储存 按照(二)的规则计算 就是把1和2 3和4压到了同一个数组空间里 叫做压位

这样存储的数字计算次数就变成了2 很厉害的优化……

那我们为什么不这样呢

没错这是10000进制……

计算次数变成了1 其实仔细看一下就知道压位的思想就是把本来不用高精的计算尽量的扩大

来达到减少计算次数的目的

特殊的输出

在最后的输出答案部分 需要一些处理(下面假设写压P位的高精(也就是把P个数压到同一个数组空间里))

一句话概括:除最高位外,一切不足P位的数字输出时需要在前面补上0使得满足P位

比如压2位 2 + 99 为例 最后会用到两个数组空间(一个放1,一个放1…)但是这两个一代表的意义不同,

第二个可以原样输出因为这是最高位(即整个数的长度modP后得到的剩余部分 这一部分是独立于其他部分的 如果补上0 最后就是0101 是不对的),第一个就需要补上一个0来使得输出101而不是11

那么怎么实现呢 下面代码

代码实现

习惯写很多注释 在这里不多做解释

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>

#define p 8//要压的位数 
#define carry 100000000//相应的10的P次方 用于进位 
//这样如果要改变压位的位数只要改这里就可以 
using namespace std;

const int Maxn=50001;

char s1[Maxn],s2[Maxn];
int a[Maxn],b[Maxn],ans[Maxn];

int change(char s[],int n[])//压位的核心部分 
{
	char temp[Maxn];//中间变量 记录每p位的数 
	int len=strlen(s+1),cur=0;
	while(len/p){//如果len大于等于p 
		strncpy(temp,s+len-p+1,p);//从后面截出来p位数 
		n[++cur]=atoi(temp);//把temp搞成数字 
		len-=p;//继续下p位 
	}
	if(len){//如果最后len不是正好p的倍数 也就是还剩下点不够p位的 
		memset(temp,0,sizeof(temp));
		strncpy(temp,s+1,len);//全截下来 
		n[++cur]=atoi(temp);//赋上 
	}
	return cur;//返回一个位数 
}
//这里就是(二)中的内容了 计算正常计算就行 
int add(int a[],int b[],int c[],int l1,int l2)
{
	int x=0,l3=max(l1,l2);
	for(int i=1;i<=l3;i++){
		c[i]=a[i]+b[i]+x;
		x=c[i]/carry;//进位 
		c[i]%=carry;
	}
	while(x>0){c[++l3]=x%10;x/=10;}
	return l3;//返回答案的位数 
}

void print(int a[],int len)
{ 
	printf("%d",a[len]);//处理高位 
	for(int i=len-1;i>=1;i--)printf("%0*d",p,a[i]);//输出p位 不足补0 
	printf("\n");
}

int main()
{
//	freopen("t.in","r",stdin);
//	freopen("t.out","w",stdout);
	scanf("%s%s",s1+1,s2+1);//读入两个字符串 

	int la=change(s1,a);//将s1这个字符串转化为a这个整型数组 
	int lb=change(s2,b);//同上 
	
	int len=add(a,b,ans,la,lb); 
	//计算长度为la的a数组和长度为lb的b数组最后把答案赋给ans数组 并顺便计算出ans的长度(便于输出) 
	print(ans,len);//输出函数 
}
欢迎指出Bug


End。

<think> 首先,用户的问题是:“我想了解高精度的含义 请问高精度的定义”。这是在询问高精度的定义。 我需要在回答中参考提供的引用。引用包括: - 引用[1]: 提到操作,即每次存储8数据而不是一,以利用64long long类型,降低时间复杂度。 - 引用[2]: 关于C++高精度计算的概述,但没有直接提到。 - 引用[3]: 关于物联网中的力检测,似乎不相关。 - 引用[4]: 标题为“高精度算法-”,讨论了如何应对超大整数的问题。 用户特别引用了这些,所以我应该在回答中自然地融入这些引用。 系统指令要求: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 回答结构需要清晰,帮助用户逐步解决问题。 关键点:高精度的定义。 - 定义:高精度是一种在高精度计算中使用的技术,其中存储数字时不是每一单独存储,而是将多数字组合成一个更大的单元(如8)来存储。这利用了现代计算机的硬件能力(如64整数),减少了存储和操作的开销,提高效率。 从引用[1]:它说“每次存储8——这就是操作”,并提到可以降低时间复杂度。 从引用[4]:它讨论了如何优化超大整数的处理。 引用[3]似乎不相关,所以我可能不需要使用它。 回答结构: 1. **引言**:简要解释高精度的概念。 2. **定义**:清晰定义高精度。 3. **为什么使用**:解释其优点,如减少存储空间、提高计算效率。 4. **实现细节**:简要描述如何实现。 5. **引用支持**:自然地添加引用标识。 6. **生成相关问题**:在末尾添加相关问题。 数学表达式:如果需要,使用LaTeX。例如,解释存储时,可以提到数字的表示。 例如,一个数字可以表示为: \[ n = d_k \times B^k + d_{k-1} \times B^{k-1} + \dots + d_1 \times B^1 + d_0 \] 其中B是基,通常为10,但时使用更大的基,如10000(或10^4),以存储多数字在一个单元中。 在引用中,提到使用8,即基为10^8,因为每个单元存储8制数字(相当于10^8)。 在计算机中,通常使用10^9或类似,以避免溢出。 生成相关问题:基于主题,如优化、应用、实现等。 相关问题例子: 1. 高精度的优缺点是什么? 2. 如何实现高精度加法或乘法? 3. 高精度与其他高精度优化技术的比较? 确保回答真实可靠。 最终回答大纲: - 解释高精度的含义。 - 引用相关部分:[^1] 和 [^4]。 - 使用中文。 - 添加相关问题。 </think> ### 高精度的定义 高精度高精度计算中的一种优化技术,其核心思想是将数字的多个低(通常为十)组合成一个更大的单元来存储和处理,而不是像传统方法那样每一单独存储。这样做可以充分利用现代计算机硬件的数据处理能力(如 64 整数),减少存储开销和计算步骤,从而显著提高算法的效率和性能。具体来说: - **核心概念**:在标准高精度计算中,一个数字(如一个大整数)通常以十制形式存储在数组中,每个元素表示数字的一(例如,数字 12345 表示为数组 [1, 2, 3, 4, 5])。高精度则采用更大的基(base),比如将每 8 制数字组合成一个单独的“单元”(unit),存储在更大的数据类型中(如 `long long` 类型)。例如: - 如果基 $B = 10^8$(即 100,000,000),那么一个单元可以表示 0 到 99,999,999 之间的值。 - 数字的数学表示为: \[ n = d_k \times B^k + d_{k-1} \times B^{k-1} + \dots + d_1 \times B^1 + d_0 \] 其中 $d_i$ 是每个单元的值,$B$ 是基(通常为 $10^8$),$k$ 是单元索引。 - **为什么使用**:传统的逐位存储方式在操作超大整数(如百万或更大)时,效率低下: - **存储浪费**:每次只存储一制数字(占用 1 个字节或更少),但现代计算机支持 64 整数(可存储高达 $2^{64} \approx 1.8 \times 10^{19}$ 的值),利用了这一优势,减少了数组大小和内存占用[^1]。 - **性能提升**:运算(如加法和乘法)的复杂度从 $O(n^2)$ 降低到 $O(n)$ 或更低,因为每次操作单更大,减少了循环次数。例如,乘法运算中,可将处理次数降到最低,避免溢出问题[^1][^4]。 - **典型实现**:在编程中,高精度通常使用整数数组实现,每个元素存储多数字。例如,在 C++ 中,可以使用 `long long` 数组,每个元素存储 8 制数字(基 $10^8$),以确保乘法时不会溢出(因为 $10^8 \times 10^8 = 10^{16} < 2^{64}$)[^1]。算法在模板库中常见,适用于大整数运算(如阶乘或斐波那契数列计算),尤其在处理超大规模数据时(如 $10000^{10000}$ 整数),避免数组大小限制[^4]。 总之,高精度是一种高效的高精度算法策略,通过“缩”数字来优化时间和空间复杂度,特别适合处理科学计算、密码学或大数据场景中的超大整数问题[^1][^4]。
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值