霍納法則和二進制冪

首先說一下霍納法則,這對於屢次冪來講,減小乘法是很重要的,由於相比加法,乘法的執行效率更低java


咱們先看一下這樣一個多項式算法

             p(x)  =  2*x^4 - 1*x^3 - 3*x^2 + 1*x^1 - 5數組

                     = x ( x ( x ( 2x - 1 ) + 3 ) + 1 ) - 5ui


再看一下霍納法則執行過程:spa

 

係數 2 -1 3 1 -5
x=3 2 3 * 2 +(-1)= 5 3 * 5 + 3 = 18 3 * 18 + 1 = 55 3 * 55 + (-5)= 160

 


因此咱們再看他的實現代碼code

 

/**
 * 霍納法則
 * 
 * @author chenxuegui
 */
public class HornerRule
{
	public static void main(String[] args)
	{
		int[] a = new int[] { 2, -1, 3, 1, -5 };

		int x = 3;

		System.out.println(Horner(a, x));

	}

	/**
	 * 霍納法則的核心
	 * 
	 * 若是 p(x) = 2*x^4 + x^3 - 3*x^2 + x -5 = x(x(x(2x-1)+3)+1)-5
	 * 
	 * 則數組  2 -1 3 1 -5 (次序冪告到低)
	 * 
	 * @param a
	 * @param x
	 * @return
	 */
	private static int Horner(int[] a, int x)
	{
		int result = a[0];

		for (int i = 1; i < a.length; i++)
		{
			result = result * x + a[i];
		}

		return result;
	}
}

 



同時霍納法則還長生一種副產品,計算p(x) 在某點上的值x0時所產生的中間數,剛好能夠做爲p(x)除以x-x0的商的係數,而算法的最後結果,除了等於p(x0)之外,還等於這個除法的餘數,對本例,  p(x)  =  2*x^4 - 1*x^3 - 3*x^2 + 1*x^1 - 5 除以 x - 3 的商爲  p(x)  =  2*x^3 + 5*x^2 + 18*x^1 + 55,餘數爲160 ,這方法逼長除法方便ci



接下來看一下二進制冪產品

二進制冪他是一種霍納法則在冪上的應用 io

                  a^n = a^p(2) = a^( bi * 2 ^ i + ....+ b1 * 2 ^ 1)table


二進制冪運算有兩種實現,一種是從左到右,一種是從右到左

看一下計算a^13從左到右的二進制冪運行過程

 

n的二進制位 1 1 0 1
累加器 a a^2*a=a^3 (a^3)^2=a^6 (a^6)^2*a=a^13

 

 

實現代碼在下面

再看一下計算a^13從左到右的二進制冪運行過程

 

1 1 0 1 n的二進制位
a^8 a^4 a^2 a 項a^2
a^5 * a^8 = a ^13 a * a^4 = a^5   a 累加器

 

 

 

/**
 * 二進制冪 其實核心仍是使用霍納法則的變形
 * 
 * @author chenxuegui
 * 
 */
public class BinaryExponentiation
{
	public static void main(String[] args)
	{
		// 計算3^13次

		System.out.println(leftRightBinaryExponentiation(3, new int[] { 1, 1,
				0, 1 }));
		
		/*System.out.println(rightLeftBinaryExponentiation(3, new int[] { 1, 1,
				0, 1 }));*/

	}

	/**
	 * 
	 * 如 a^13 = a^(1*2^3 + 1*2^2 + 0*2^1 + 1*2^0)
	 * 
	 * @param a
	 *            底數
	 * @param b
	 *            冪二進制霍納表達式(數組順序冪次高到底)
	 */
	private static int leftRightBinaryExponentiation(int a, int[] b)
	{
		int product = a;

		// b[0]必定爲1(要麼爲1,要麼爲0),由於它是最高位係數,最高位係數只能是1
		for (int i = 1; i < b.length; i++)
		{
			product = product * product;

			if (b[i] == 1)
				product *= a;
		}

		return product;

	}

	/**
	 * 
	 * 如 a^13 = a^(1*2^3 + 1*2^2 + 0*2^1 + 1*2^0)
	 * 
	 * @param a
	 *            底數
	 * @param b
	 *            冪二進制霍納表達式(數組順序冪次高到底)
	 * @return
	 */
	private static int rightLeftBinaryExponentiation(int a, int[] b)
	{
		int product = 1;

		int term = a;

		for (int i = b.length-1; i >=0 ; i--)
		{
			if(b[i] == 1)product *=term;

			term *= term;
		}
		
		return product;
	}
}



 

該算法效率O(logn),但因爲二進制冪算法依賴指數n的二進制形式,因此他們的有效性被削弱了,但在某種場合下,他們仍是一種頗有效的算法的

相關文章
相關標籤/搜索