AcWing算法学习第三节---高精度问题.

简介: AcWing算法学习第三节---高精度问题.

# 系列文章目录

[第一节快速排序](https://blog.csdn.net/congfen214/article/details/127973670)

[第二节二分法](https://blog.csdn.net/congfen214/article/details/128078143)


---

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/0dead988b1f04c3bb7496eacff42e7a2.jpeg#pic_center)

**学习路上的风景,我陪你一起去看,编程路上的算法,我陪你一起去学,朋友们你们好,我是夏目浅石,蟹蟹你点开文章和我一同进步,加油!遇见更好的自己。**


@[TOC](文章目录)


---


# 前言


今天学了一些高精度问题的方法这里给大家分享一下,希望大家也可以学习并且掌握。


---


`提示:以下是本篇文章正文内容,下面案例可供参考`


# 一、高精度加法

**知识点如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/02f04340a01f49528e6173357e177b07.png)

这是我在AcWing打卡界面总结的一些我自己的想法和思路,希望大家可以看完,接下来就是题目的讲解和代码;


1.输入的scanf还是效率很高的.并且有时候gets函数没办法使用,所以scanf,是一个挺好用的办法

2.char类型的输入方便输入更高位数,然后再减去‘0’的ASCII码值就能转换成想要的了。

3.核心的高精度算法–>就是每一个位数相加再加进位,然后再去莫10就是这个位数的答案了,再把进位除去10就是下一位的进位,依次类推就行…

4.输出的时候就是按照人类的习惯输出就好,就是倒着输出.


**题目如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/b51a13431e1a453ea2c7e91ce85852f9.png)

>代码如下(示例):


```c

#include<stdio.h>

#include<string.h>

int main()

{

   char arr1[100010],arr2[100010];

   scanf("%s",arr1);

   scanf("%s",arr2);

   int a[100010],b[100010],c[100010],len1=strlen(arr1),len2=strlen(arr2),i,j,k=0,t=0;

   for(i=len1-1,j=0;i>=0;i--) a[j++]=arr1[i]-'0';

   for(i=len2-1,j=0;i>=0;i--) b[j++]=arr2[i]-'0';

   for(i=0;i<len1||i<len2;i++)

   {

       if(i<len1) t=t+a[i];

       if(i<len2) t=t+b[i];

       c[k++]=t%10;

       t=t/10;

   }

   if(t) c[k++]=1;

   for(i=k-1;i>=0;i--) printf("%d",c[i]);

   return 0;

}

```



# 二、高精度减法

**知识点如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/0a151f32f9b24bb8937dc170feb2be39.png)


之前看过许多博客关于这些高精度的,但是都是模棱两可,不是太理解,今天学了一下y总的高精度,大抵是懂了,这就来分享给大家让大家学习了。

总结:

1.我想就是拆分模块来写这一个算法,第一就是main函数,这里处理输入和调用函数的功能(作用),过多细节就看代码就行

2.讲解一下最先出现的cmp函数和后面出现的sub函数

@1.cmp函数就是比较这一串数字的长度以及大小这个功能,你先看俩字符串是否相同长度,不相同则长的一定大。

当长度相同时就需要比较两者的最高位是否相同(或者谁大谁小),依次类推直到找到不同则 return 1 or 0,这个函数尽量做到的是 c=a-b;a>=b。

@2.sub函数就是做减法对吧,根据cmp函数就是a-b这样,所以根据人的习惯啊,当3-5的时候人往往会变成-(5-3)这样去计算,所以就分成两种情况即:a开始就大于b,和a一开始小于b两种情况,所以一种需要先打印’-‘然后打印数字,另一种则不需要打印’-‘对吧?

3.高精度减法的核心算法:

两个数的低位相减然后看是否为负数,如果为负数则需要借10,则进位为1.

两个数的低位相减然后看是否为非负数,如果为非负数则不需要借10,且进位为0.

然后就是扫除前导零输出就可以了.


**题目如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/d8109df3283c41bdb0876f134be973d8.png)


>代码如下(示例):


```c

#include<stdio.h>

#include<string.h>

//c=a-b;a>=b;

int cmp(char arr1[],char arr2[],int len1,int len2)

{

   if(len1!=len2)

   {

       if(len1>len2) return 1;

       else return 0;

   }


   for(int i=0;i<len1;i++)

   {

       if(arr1[i]!=arr2[i])

       {

           if(arr1[i]>arr2[i]) return 1;

           else return 0;

       }

   }

}

void sub(int a[],int b[],int len1,int len2)

{

   int c[100010],t=0;

   for(int i=0;i<len1;i++)

   {

       t=a[i]-t;

       if(i<len2)

       {

           t=t-b[i];

       }

       c[i]=(t+10)%10;

       if(t<0) t=1;

       else t=0;

   }

   while(c[len1-1]==0&&len1-1>0) len1--;

   for(int i=len1-1;i>=0;i--)

   {

       printf("%d",c[i]);

   }

}


int main()

{

   //输入

   char arr1[100010],arr2[100010];

   int a[100010],b[100010];

   scanf("%s",arr1);

   scanf("%s",arr2);

   int len1=strlen(arr1),len2=strlen(arr2);


   for(int i=len1-1,j=0;i>=0;i--) a[j++]=arr1[i]-'0';

   for(int i=len2-1,j=0;i>=0;i--) b[j++]=arr2[i]-'0';


   if(cmp(arr1,arr2,len1,len2))

   {

       sub(a,b,len1,len2);

   }

   else

   {

       printf("-");

       sub(b,a,len2,len1);

   }

   return 0;

}

```

# 三、高精度乘法

**知识点如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/db2887f6f3a543a4aace586f5769b6ae.png)


类似于加法,会加法这个乘法真的非常简单。

总结:

1.输入的处理;

2.拿b去和数组a的每一位去乘,然后就是莫10放到c数组里面,然后让进位/10就是下一个数的进位了


**题目如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/7a88494de09b4984b899da7c4c3c8a81.png)



代码如下(示例):


```c

#include<stdio.h>

#include<string.h>

const int N=100010;

void cheng(int a[],int b,int len)

{

   int c[N],i,t=0;

   for(i=0;i<len||t;i++)

   {

       if(i<len)

       t=a[i]*b+t;

       c[i]=t%10;

       t/=10;

   }

   while(c[i]==0&&i>0) i--;

   for(int j=i;j>=0;j--) printf("%d",c[j]);

}

int main()

{

   char arr[N];

   scanf("%s",arr);

   int b,a[N],len=strlen(arr),i,j;

   scanf("%d",&b);

   for(i=strlen(arr)-1,j=0;i>=0;i--) a[j++]=arr[i]-'0';

   cheng(a,b,len);

   return 0;

}

```


该处使用的url网络请求的数据。


---

# 四、高精度除法

**知识点如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/5f6ad02223f0421582ddd387e001bd17.png)


高精度除法我感觉理解了这个过程其实这个题就不难,下main我来讲解一下吧hhh~

总结:

1.这里其实我想讲一讲最最重要的核心算法部分

这里其实就是理解t是除法做完商的余数,然后余数乘10+下一位数字就是新的被除数,依次类推,直到退出循环为止,下面只需要处理前导零,就可以输出啦!


**题目如下:**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/421963cd75334a269b93c05e046e5899.png)




代码如下(示例):

```c

#include<stdio.h>

#include<string.h>

void chu(int a[],int b,int len)

{

int c[100010],t=0;

for(int i=len-1;i>=0;i--)

{

 t=t*10+a[i];

 c[i]=t/b;

 t%=b;

}

while(c[len-1]==0&&len-1>0) len--;

for(int i=len-1;i>=0;i--) printf("%d",c[i]);

printf("\n"); printf("%d",t);

}

int main()

{

char arr[100010];

int b,a[100010],len;

scanf("%s",arr);

scanf("%d",&b);

len=strlen(arr);

for(int i=len-1,j=0;i>=0;i--) a[j++]=arr[i]-'0';

chu(a,b,len);

return 0;

}

```


# 总结

**自己的感想:**

这里为了大家方便大家复习我会给出我的acwing的地址想去看的话就去看看,当然也可以去acwng报名自己学然后再看我的博客这样会效果更好,不理解的咱们一起讨论学习,我觉得会很不错hhh~

知识点图片汇总

**思维导图**

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/a97bd4cfbe4f446eb2e77a4d7b8e9e47.png)

记住这里面我是没有把核心算法家里面的,因为这只是一个宏观的导图,最重要的还是把我在acwing上的知识总结好好理解消化一下,这样才能获得收获hhh~咱们下一期见吧!


## 下期预告


****前缀和与差分,欢迎来看哦hhh拜拜啦大家!****

相关文章
|
3天前
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
14 2
|
1月前
|
机器学习/深度学习 人工智能 资源调度
【博士每天一篇文献-算法】连续学习算法之HAT: Overcoming catastrophic forgetting with hard attention to the task
本文介绍了一种名为Hard Attention to the Task (HAT)的连续学习算法,通过学习几乎二值的注意力向量来克服灾难性遗忘问题,同时不影响当前任务的学习,并通过实验验证了其在减少遗忘方面的有效性。
48 12
|
1月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
1月前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
1月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之HNet:Continual learning with hypernetworks
本文提出了一种基于任务条件超网络(Hypernetworks)的持续学习模型,通过超网络生成目标网络权重并结合正则化技术减少灾难性遗忘,实现有效的任务顺序学习与长期记忆保持。
34 4
|
1月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-算法】连续学习算法之RWalk:Riemannian Walk for Incremental Learning Understanding
RWalk算法是一种增量学习框架,通过结合EWC++和修改版的Path Integral算法,并采用不同的采样策略存储先前任务的代表性子集,以量化和平衡遗忘和固执,实现在学习新任务的同时保留旧任务的知识。
74 3
|
1月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-综述】基于脑启发的连续学习算法有哪些?附思维导图
这篇博客文章总结了连续学习的分类,包括经典方法(重放、正则化和稀疏化方法)和脑启发方法(突触启发、双系统启发、睡眠启发和模块化启发方法),并讨论了它们在解决灾难性遗忘问题上的优势和局限性。
28 2
|
2月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机回归模型(SVR算法)项目实战
106 9
|
2月前
|
机器学习/深度学习 数据采集 算法
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机分类模型(SVC算法)项目实战
Python实现ISSA融合反向学习与Levy飞行策略的改进麻雀优化算法优化支持向量机分类模型(SVC算法)项目实战
|
2月前
|
机器学习/深度学习 数据采集 监控
算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient
**神经网络与AI学习概览** - 探讨神经网络设计,包括MLP、RNN、CNN,激活函数如ReLU,以及隐藏层设计,强调网络结构与任务匹配。 - 参数初始化与优化涉及Xavier/He初始化,权重和偏置初始化,优化算法如SGD、Adam,针对不同场景选择。 - 学习率调整与正则化,如动态学习率、L1/L2正则化、早停法和Dropout,以改善训练和泛化。
30 0
算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient