取模操作(补充说明)
来源:互联网 发布:投稿软件 编辑:程序博客网 时间:2024/05/16 13:51
起源
在算法中,有时候要用到取模操作,为的是避免数据过大溢出,而有时候只需要验证算法的有效性,并关心实际的值,下面给出取模操作的性质以及一个简单的应用例子。
模运算性质
- ( a + b ) % c = ( ( a % c ) + ( b % c ) ) % c
- ( a * b ) % c = ( ( a % c ) * ( b % c ) ) % c
- ( a – b ) % c = ( ( a % c ) – ( b % c ) ) % c
- ( a / b ) % c NOT EQUAL TO ( ( a % c ) / ( b % c ) ) % c
(a / b ) % c = ( a * b^ -1 ) % c
the answer ( a % b) always be less than b.
基本上是要记住上面这几条的,基本够用。。而b经常取的数为一个比较大的素数。
为什么需要模运算性质
很显然,有的时候a + b的值越界(超过Integer.MAX_VALUE),有的时候a * b的值越界(超过Integer.MAX_VALUE)。所以需要相关的模运算性质,在越界之前及时处理。
最频繁的公式:
1.( a + b ) % c = ( ( a % c ) + ( b % c ) ) % c
2.( a * b ) % c = ( ( a % c ) * ( b % c ) ) % c
数据的范围
int的取值范围为(-2147483648~2147483647),占用4个字节(-2的31次方到2的31次方-1)
long的取值范围为(-9223372036854774808~9223372036854774807),占用8个字节(-2的63次方到2的63次方-1)
实际应用
取模运算用的最多的地方是哈希函数的实现,以及DP用于优化空间的滚动数组,再就是一些数论算法,以及避免中间过程的溢出。
阶乘程序
public static long factorial1(int n){ long fact = 1; for (int i = 1; i <= n; i++){ fact = fact * i; } return fact; } public static long factorial2(int n){ long fact = 1; int M = 1000000007; for (int i = 1; i <= n; i++){ fact = (fact * i) % M; } return fact; } public static long factorial3(int n){ long fact = 1; int M = 1000000007; for (int i = 1; i <= n; i++){ fact = fact * i; //WRONG APPROACH } return fact % M; }
这三个阶乘程序f1 f2 f3 分别代表不用模操作,正确使用模操作, 错误使用模操作。。。
f1和f3的程序会溢出,f3虽然使用模操作,但是是错误的示范,模操作应该应用到中间计算过程中。。
这里f2的M选了一个很大的素数,这样可以保证程序在小规模的n能够输出正确结果,同时又保证了大规模的n程序不会溢出出错。
参考:https://www.quora.com/What-exactly-is-print-it-modulo-10-9-+-7-in-competitive-programming-websites
- 取模操作(补充说明)
- Python 文件IO操作的补充说明
- 关于openwrt 中继 操作补充说明
- SessionIE的补充说明
- RAS补充说明
- SampleBrowserPlugin的补充说明
- 数字图像处理补充说明
- AsyncSocket使用补充说明
- SqlHelper类说明【补充】
- DWZ手册补充说明
- 关于CRF++补充说明
- DXI补充说明
- gitosis安装补充说明
- gcd补充说明
- IOCP原理补充说明!
- (总结)数据结构之链表的基本操作说明和示例(待补充)
- 基于proteus的51单片机仿真实例八、关于proteus常用操作的补充说明
- boost序列化补充说明
- LeetCode_452. Minimum Number of Arrows to Burst Balloons
- 袁芳的学习笔记(5)基于PredixUI的前端工程搭建
- [gif] 基于gif.h的gif文件生成
- java this关键字
- traing 3 暴力 SCU4440 Rectangle
- 取模操作(补充说明)
- 数据包、着色规则和提示
- 【统计学习方法】第2章 感知机(Perceptron)
- JavaScript字符集编码与解码
- 使用<ViewStub>实现view的延迟加载
- 提高AFL的fuzz速度
- 用正则表示式,取中文中所有中括号[]的内容
- Struts2 源码分析——Result类实例
- Android自定义控件