ARTS Week 3
Nov 11,2019 ~ Nov 17,2019
Algorithm
本周来介绍快速求一个数字n次方的余数。
理论基础
我们先定义运算$ x \bmod p = r \(与\) x \equiv r \pmod p \(的含义是一样的。若\) p = 5 $,则可以将所有整数划分到5个不相交的集合里,具体如下:
& \{\dots -10, -5, 0, 5, 10 \dots \} \bmod 5 = 0 & \\
& \{\dots -9, -4, 1, 6, 11 \dots \} \bmod 5 = 1 & \\
& \{\dots -8, -3, 2, 7, 12 \dots \} \bmod 5 = 2 & \\
& \{\dots -7, -2, 3, 8, 13 \dots \} \bmod 5 = 3 & \\
& \{\dots -6, -1, 4, 9, 14 \dots \} \bmod 5 = 4 & \\
\end{matrix}\right.
\]
可能有人不懂为什么\(-4 \bmod 5 = 1\),我来解释一下,因为$ -4 = 5 \times (-1) + 1 \(,故\) -4 \div 5 = -0.8 = -1 \cdots 1 \(。因此\)-4 \bmod 5 = 1$
那么根据上面的描述,就可以将数之间的运算通过取余映射在有限个集合内。那么,有如下两条基本性质,可以更加方便我们进行求解
- 若存在 $ a \equiv b \pmod p, c \equiv d \pmod p $ ,则 $ a+c \equiv b+d \pmod p $ 。
- 若存在 $ a \equiv b \pmod p, c \equiv d \pmod p $ ,则 $ ac \equiv bd \pmod p $
通过这样的性质就很容易求解一个大数的对某个数字取余的结果。以计算\((2^{32} + 5)\bmod 7 = ?\)为例
- $ 2 \bmod 7 = 2 $
- $ 2^2 \bmod 7 = (2 \times 2) \bmod 7 = 4$
- $ 2^4 \bmod 7 = (2^2 \times 2^2) \bmod 7 = 4 \times 4 \bmod 7 = 2 $
- $ 2^8 \bmod 7 = {2^4 \times 2^4} \bmod 7 = [(2^4 \bmod 7) \times (2^4 \bmod 7)] \bmod 7 = (2 \times 2) \bmod 7 = 4 $
- $ 2^{16} \bmod 7 = {2^8 \times 2^8} \bmod 7 = [(2^8 \bmod 7) \times (2^8 \bmod 7)] \bmod 7 = (4 \times 4) \bmod 7 = 2 $
- $ 2^{32} \bmod 7 = (2^{16} \times 2^{16}) \bmod 7 = [(2^{16} \bmod 7) \times (2^{16} \bmod 7)] \bmod 7 = (2 \times 2) \bmod 7 = 4 $
- $ (2^{32}+5) \bmod 7 = [(2^{32} \bmod 7) + (5 \bmod 7)] \bmod 7 = (4 + 5) \bmod 7 = 2 $
具体实现
设问题为:求解$ a^x \bmod b = ? \(。因此问题的关键在于如何分解\)x$,具体有两种基本思路,分别是按照2和10进行分解。当然也可以按照其他数进行分解,但实现起来较复杂。
- 按数字2来分解,分解的基本原理如下:
& x = x // 2 + x // 2,\quad a^x = a^{x//2} \times a^{x//2} \quad \text{ if } x \bmod 2 = 0 \\
& x = x // 2 + x // 2 + 1,\quad a^x = a^{x//2} \times a^{x//2} \times a \quad \text{ if } x \bmod 2 = 1
\end{cases}
\]
根据上述公式不难写出代码:
def my_mod(a, x, b):
if x == 1:
return a % b
else:
tmp = my_mod(a, x//2, b)
if x % 2 == 0:
return ( tmp * tmp ) % b
else:
return ( tmp * tmp * my_mod(a, 1, b) ) % b
- 按数字
10来分解,分解的基本原理如下,因为是递归的,为了方便理解,使用数字123为例:
$ 123 = (1 \times 10 + 2) \times 10 + 3 \(
\) a^{123} = ({3^1} ** 3^{10} \times 3^2 ) ** 3^{10} \times 3^3 $
实现代码如下:
def my_mod(a, x, b):
def cal_mod(a, b):
L = []
for i in range(11):
L.append( (a**i) % b )
return L
def recursive(x):
if 0 <= x <= 9:
return L[x]
else:
return ( recursive(x//10) ** L[10] * recursive(x%10) ) % b
if 0 <= x <= 10:
return (a**x) % b
L = cal_mod(a, b)
return recursive(x)
Review
Why is the gets function so dangerous that it should not be used?
在一个比较早的代码时,运行总会出错,后面通过查找资料,发现是gets函数的问题。
当我查阅gets函数时发现,在DESCRIPTION部分直接写道Never use this function.
在阅读了一些关于gets英文文章后,我明白了为什么gets会带来问题。
简单地说,带来隐患的根源在于gets函数不会控制读入的量,而只是以\n或\0作为读入的终止。例如下面这个代码:
#include<stdio.h>
int main()
{
char str1[] = "hello";
char str2[] = "world";
char *str = gets(str1);
return 0;
}
程序开始运行后,输入任意个字符,点击回车将会直接带来段错误从而终结程序。
Tips
根据上述的描述,凡要涉及到gets函数,都可以使用fgets函数进行代替
fgets函数原型如下
char *fgets(char *s, int size, FILE *stream);
从标准输入的读取方法如下:
char buffer[100];
while (fgets(buffer, sizeof(buffer), stdin))
{
// operations
}
Share
本周分享一个关于vim配置的项目——VimPlus
不少vim用户都喜欢安装或多或少的插件以增强原生vim的功能,但不少新手第一次安装插件时可能会遇到某些问题,同时也未必会一次安装配置好需要的插件。而这个项目就是为了方便新手可以通过简单的运行命令就可以安装许多常用的插件,进而配置出一个像IDE似的vim。
其中可以一键安装的插件包括vim-plug、You Complete Me等
目前项目的作者的维护也比较及时。希望未来可以越做越好!
更多内容可去上述项目链接中进行查看。
(注:我与作者没有任何联系,只是发现了这个项目并且个人尝试后觉得不错,所以分享在这里)
ARTS Week 3的更多相关文章
- KDE声音服务器 arts
KDE声音服务器 arts arts介绍arts是KDE的核心声音系统,支持多音频流.全双工.网络声音请求.ALSA与OSS驱动后端.JACK声音服务器后端等扩展,它既是声音服务器,也 提供一套音频软 ...
- 【ARTS】01_21_左耳听风-201900401~201900407
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_20_左耳听风-20190325~20190331
zz## ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 ...
- 【ARTS】01_19_左耳听风-20190318~20190324
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_18_左耳听风-20190311~20190317
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_17_左耳听风-20190304~20190310
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_16_左耳听风-20190225~20190303
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_15_左耳听风-20190218~20190224
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_14_左耳听风-20190211~20190217
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- 【ARTS】01_13_左耳听风-20190204~20190210
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
随机推荐
- 小小知识点(二十六)关于5G发展的28个核心问题,来自华为内部的深度解读
本文来自微信公众号“腾讯深网”(ID:qqshenwang),作者 马关夏.36氪经授权转载. 一.5G先进性与行业应用 1.5G到底是什么?和4G比有什么不一样? 从国际电信联盟(ITU)的定义来看 ...
- 22.Python安装和卸载第三方模块方法
安装和卸载第三方开源模块的步骤:下例,安装urllib3模块的步骤. 1.安装开源模块步骤: 按键盘windows键+r键,输出cmd回车.或开始->windows系统->命令提示符: 输 ...
- Theia APIs——通过JSON-RPC进行通信
上一篇:Theia APIs——事件 通过JSON-PRC进行通信 在本节中,我将讲解如何创建后端服务并通过JSON-PRC来连接它. 我将使用debug logging system作为例子来进行讲 ...
- 【记】VM VirtualBox 网络地址转换(NAT)使用详解
1. 查看虚拟机Centos6的ip 但是这个IP地址并不能直接连接,因为本地VBox网络连接方式采用的是“网络地址转换(NAT)”(如上上图所示),也就是说 10.0.2.15 这地址是转换的. 2 ...
- python线性数据结构
1.栈(Stack)(后进先出) 栈的实现: class Stack: def __init__(self): self.items = [] def isEmpty(self): return se ...
- wannafly camp day4
2088: 电音之王 描述 题目描述: 终于活成了自己讨厌的样子. 听说多听电音能加快程序运行的速度. 定义一个数列,告诉你a0,a1,m0,m1,ca\_0,a\_1,m\_0,m\_1,ca0, ...
- CAS是什么
CAS是什么? 比较并交换 例子1: public class ABADemo1 { public static void main(String[] args) { AtomicInteger at ...
- margin和 padding 以及 float :left和float :right的介绍
1.margin和padding的介绍 margin是外边距,padding是内边距,用CSS时首先要做的就是把所有标签的margin和padding清空.这样更容易控制布局和兼容浏览器. p li等 ...
- 如何选择kmeans中的k值——肘部法则–Elbow Method和轮廓系数–Silhouette Coefficient
肘部法则–Elbow Method 我们知道k-means是以最小化样本与质点平方误差作为目标函数,将每个簇的质点与簇内样本点的平方距离误差和称为畸变程度(distortions),那么,对于一个簇, ...
- java 自增/减运算符
注意:python中没有 一.自增运算符 1.单独使用时,目的获取变量的值,前++和后++没有区别,使用后值都会递增一. 2.混合使用时,才有区别.前++,先加后用.后++,先用后加 二.自减运算符 ...