多项式求值

  1. 例2-8   [多项式求值] 考察多项式P (x)= 

n                 

Σ cix^i

i=0

 

如果cn≠0,则P 是一个n 维多项式。下面程序可用来计算对于给定的值x,P(x)的实际取值。假定根据f o r循环内部所执行的加和乘的次数来估算时间复杂性。可以使用维数n 作为实例特征。进入f o r循环的总次数为n,每次循环执行1次加法和2次乘法(这种操作计数不包含循环控制变量i 每次递增所执行的加法) 。加法的次数为n,乘法的次数为2n。

程序2-3:

template <class T>
T PolyEval(T coeff[], int n, const T& x)
{ 
	//计算n次多项式的值,c o e ff [ 0 : n ]为多项式的系数
	T y=1, value= coeff [ 0 ] ;
	for ( int i = 1; i <= n; i++)
	{
		//累加下一项
		y *= x;
		value += y * coeff [ i ] ;
	}
	return value;
}


Horner 法则采用如下的分解式计算一个多项式:P (x) = (…(cn* x +cn -1 ) * x +cn -2 ) * x +cn -3 ) * x + …) * x + c0
相应的C + +函数见程序2 - 4。采用与程序2 - 3相同的方法,可以估算出该程序的时间复杂性为n 次加法和n 次乘法由于函数PolyEval 所执行的加法数与Horner 相同,而乘法数是H o r n e r的两倍,因此,函数Horner 应该更快。

程序2-4:

template<class T>
T Horner( T coeff[], int n, const T& x)
{
	//计算n次多项式的值,c o e ff [ 0 : n ]为多项式的系数
	T value = coeff[n];
	for ( int i = 1; i <= n; i ++)
	{
		value = value*x + coeff[n-i];
	}
	return value;
}


 

int ChessDataCheck( ChessData& cdata,int chess,int posx,int posy )
{
	//是否已经结束
	static int nResult = 0;
	if ( nResult == CM_BLACK || nResult == CM_WHITE)
	{
		return -1;
	}
	//棋子的正确性
	if (CheckSafe(cdata,chess,posx,posy) == -1)
	{
		return -1;
	}
	//可以下棋
	cdata.data[posx][posy] = chess;
	
	//黑棋要判断禁手
	if ( CM_BLACK == chess && -1 == forbid(cdata,posx,posy))
	{
		nResult = CM_WHITE;
		PrintChessData(cdata);
		return nResult;
	}

	nResult = IsOver(cdata,chess,posx,posy);

	
	PrintChessData(cdata);
	return nResult;
}


 

//判断是否是长连
//返回1 没有构成禁手;返回-1 表示构成禁手
int forbidLine( ChessData& cdata,int posx,int posy )
{
	//纵向判断
	int posxx = posx -5;
	if ( posxx < 0)
	{
		posxx = 0;
	}

	int i = 0;
	for( i = 0; i < 6; i ++)
	{
		posxx += i;
		if ( posxx > 9)
		{
			break;
		}
		if (cdata.data[posxx][posy] == CM_BLACK && cdata.data[posxx+1][posy] == CM_BLACK && cdata.data[posxx+2][posy] == CM_BLACK
			&& cdata.data[posxx+3][posy]  == CM_BLACK && cdata.data[posxx+4][posy] == CM_BLACK && cdata.data[posxx+5][posy] == CM_BLACK)
		{
			return -1;
		}
	}

	//横向判断
	int posyy = posy - 5;
	if ( posyy <0)
	{
		posyy = 0;
	}
	for( i = 0; i < 6; i ++)
	{
		posyy += i;
		if ( posyy > 9)
		{
			break;
		}

		if (cdata.data[posx][posyy] == CM_BLACK && cdata.data[posx][posyy+1] == CM_BLACK && cdata.data[posx][posyy+2] == CM_BLACK
			&& cdata.data[posx][posyy+3] == CM_BLACK && cdata.data[posx][posyy+4] == CM_BLACK && cdata.data[posx][posyy+5] == CM_BLACK)
		{
			return -1;
		}
	}

	//右下判断
	if ( posx > posy)
	{
		if ( 0 == posyy)
		{
			posxx = posx - posy;
		}
	}
	else
	{
		if ( 0 == posxx)
		{
			posyy = posy - posx;
		}
	}

	for( i = 0; i < 6; i ++)
	{
		posxx += i;
		posyy += i;
		//向右下延伸最多只能放四个,肯定不会赢
		if (posxx  >9 || posyy > 9)
		{
			break;
		}
		if (cdata.data[posxx][posyy] == CM_BLACK && cdata.data[posxx+1][posyy+1]  == CM_BLACK&& cdata.data[posxx+2][posyy+2] == CM_BLACK
			&& cdata.data[posxx+3][posyy+3]  == CM_BLACK&& cdata.data[posxx+4][posyy+4] == CM_BLACK && cdata.data[posxx+5][posyy+5] == CM_BLACK)
		{
			return -1;
		}
	}

	//左下判断
	if ( (posx+posy) >14 )
	{
		if ( posy > 8)
		{
			posyy = 14;
			posxx = (posx + posy - 14);
		}
		else
		{
			posxx = posx - 4;
			posyy = posy + 4;
		}
	}
	else
	{
		if ( posx < 6)
		{
			posxx = 0;
			posyy = posx + posy;
		}
		else
		{
			posxx = posx - 4;
			posyy = posy + 4;
		}
	}

	for( i = 0; i < 6; i ++)
	{
		posxx += i;
		posyy -= i;
		//向右下延伸最多只能放四个,肯定不会赢
		if (posyy  <5 || posxx > 9)
		{
			break;
		}
		if (cdata.data[posxx][posyy] == CM_BLACK && cdata.data[posxx+1][posyy-1]  == CM_BLACK&& cdata.data[posxx+2][posyy-2] == CM_BLACK
			&& cdata.data[posxx+3][posyy-3]  == CM_BLACK&& cdata.data[posxx+4][posyy-4] == CM_BLACK && cdata.data[posxx+5][posyy+5] == CM_BLACK)
		{
			return -1;
		}
	}
	return 1;
}


//判断黑棋禁手
//返回1 没有禁手; 返回-1 表示黑棋禁手失败了
int forbid(ChessData& cdata,int posx,int posy)
{
	return forbidLine(cdata,posx,posy);
}


//判断是否结束,不考虑禁手的情况
//返回chess 胜利;0 都没胜利
int IsOver(ChessData& cdata,int chess,int posx,int posy)
{
	//纵向判断
	int posxx = posx -4;
	if ( posxx < 0)
	{
		posxx = 0;
	}

	int i = 0;
	for( i = 0; i < 5; i ++)
	{
		posxx += i;
		if ( posxx > 10)
		{
			break;
		}
		if (cdata.data[posxx][posy] == chess && cdata.data[posxx+1][posy] == chess && cdata.data[posxx+2][posy] == chess
			&& cdata.data[posxx+3][posy]  == chess && cdata.data[posxx+4][posy] == chess)
		{
			return chess;
		}
	}

	//横向判断
	int posyy = posy - 4;
	if ( posyy <0)
	{
		posyy = 0;
	}
	for( i = 0; i < 5; i ++)
	{
		posyy += i;
		if ( posyy > 10)
		{
			break;
		}

		if (cdata.data[posx][posyy] == chess && cdata.data[posx][posyy+1] == chess && cdata.data[posx][posyy+2] == chess
			&& cdata.data[posx][posyy+3] == chess && cdata.data[posx][posyy+4] == chess)
		{
			return chess;
		}
	}

	//右下判断
	if ( posx > posy)
	{
		if ( 0 == posyy)
		{
			posxx = posx - posy;
		}
	}
	else
	{
		if ( 0 == posxx)
		{
			posyy = posy - posx;
		}
	}

	for( i = 0; i < 5; i ++)
	{
		posxx += i;
		posyy += i;
		//向右下延伸最多只能放四个,肯定不会赢
		if (posxx  >10 || posyy > 10)
		{
			break;
		}
		if (cdata.data[posxx][posyy] == chess && cdata.data[posxx+1][posyy+1]  == chess&& cdata.data[posxx+2][posyy+2] == chess
		&& cdata.data[posxx+3][posyy+3]  == chess&& cdata.data[posxx+4][posyy+4] == chess)
		{
			return chess;
		}
	}

	//左下判断
	if ( (posx+posy) >14 )
	{
		if ( posy > 9)
		{
			posyy = 14;
			posxx = (posx + posy - 14);
		}
		else
		{
			posxx = posx - 4;
			posyy = posy + 4;
		}
	}
	else
	{
		if ( posx < 5)
		{
			posxx = 0;
			posyy = posx + posy;
		}
		else
		{
			posxx = posx - 4;
			posyy = posy + 4;
		}
	}

	for( i = 0; i < 5; i ++)
	{
		posxx += i;
		posyy -= i;
		//向右下延伸最多只能放四个,肯定不会赢
		if (posyy  <4 || posxx > 10)
		{
			break;
		}
		if (cdata.data[posxx][posyy] == chess && cdata.data[posxx+1][posyy-1]  == chess&& cdata.data[posxx+2][posyy-2] == chess
			&& cdata.data[posxx+3][posyy-3]  == chess&& cdata.data[posxx+4][posyy-4] == chess)
		{
			return chess;
		}
	}

	return 0;
}


//检查棋子下的正确性,比如下了两次白棋
int CheckSafe(ChessData& cdata,int chess,int posx,int posy)
{
	//检查棋子位置
	if ( posx <0 || posx > 14 || posy < 0 || posy > 14)
	{
		return -1;
	}
	//必须黑棋先下,并且偶数次为黑棋,奇数为白棋
	static int nType = -1;
	nType ++;
	//本该下黑棋结果下了白棋
	if ( nType%2 ==0 && chess != CM_BLACK)
	{
		return -1;
	}
	//本该下白棋结果下了黑棋
	if ( nType%2 ==1 && chess == CM_BLACK)
	{
		return -1;
	}
	//判断该位置是否有棋子
	if (cdata.data[posx][posy] == CM_BLACK || cdata.data[posx][posy]  == CM_WHITE )
	{
		return -1;
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值