- 例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;
}