zoukankan      html  css  js  c++  java
  • 快速幂:循环&递归

    递归

    其实原理很简单,有初一的学历就好,你只需要知道(k为正整数):

    1. x2k = xk * xk
    2. x2k+1 = xk * xk * x
    3. 任何数的0次方都为1(除0外)
    4. 任何数的1次方都为它本身

    至于为什么,问数学老师去
    然后一直递归下去即可
    代码(计算xk)

    int poww(int x , int k){
    	if(k == 1)
    		return x;
    	int tmp = poww(x , k / 2);
    	if(k % 2 == 0)
    		return tmp * tmp;
    	else
    		return tmp * tmp * x;
    }
    

    循环(一般来讲循环会比递归快)

    这个稍微有亿一点点复杂
    你需要知道:

    1. 任何数都可以用2的次方(不重复)的和来表示(很简单的道理)在这里插入图片描述10 = 2 + 8 = 21 + 23
      15 = 1 + 2 + 4 + 8 = 20 + 21 + 22 +23
    2. xa1+a2+a3+...+an= xa1 * xa2 * xa3 * ... * xan
      不会的问初中数学老师去

    那就出来了系不系很简单
    再举个栗子:
    310 = 32+8 = 32 * 38
    把10在二进制下表示是(1010)2(这里想一想位权转换进制10 = 2 + 8 = 21 + 23 )

    是不是豁然开朗了

    具体实现(1<<i就是2的i次方):
    我们把指数k在二进制下一位一位地拆开,拆到第i位时顺便计算x(1<<i) 如果k的(右往左数,从0开始)第i位(注意是二进制)是1,就把x(1<<i)乘到结果里去

    代码:

    int poww_loop(int x,int k) 
    {
    	int res = 1;
    	while(k)
    	{
    		if(k&1 == 1)
    			res *= x;
    		x *= x;//注意现在的x已经不是原来的底数,而是原来的底数的(2的i次方)的次方 
    		k >>= 1;
    	}
    	return res;
    }
    

    附:位运算

    不详细讲,自己写代码试试,或者到网上搜

    移位(">>" & "<<")

    把二进制表示下把数字同时向左(右)移动,越界部分舍去,新增部分补0
    n << p = n * 2p
    n >>p = n / 2p
    10 << 1 = 20

    与运算(&)

    如果n&1 == 1,则n是奇数,否则n是偶数
    if(n & 1 == 0)等价于 if(n % 2 == 0),但是位运算的效率会更高

  • 相关阅读:
    讲解SQL Server危险扩展存储删除和恢复
    新生活
    邮件发送作业调度 创建操作员
    Linux 定时任务 crontab
    短信猫二次开发接口函数及规范
    Linux修改用户shell
    Linux里$等记得转义
    网页标题前出现的图标
    Linux读书笔记
    DataStage通过分析日志获取Job插入目标表的记录数
  • 原文地址:https://www.cnblogs.com/dream1024/p/13957517.html
Copyright © 2011-2022 走看看