原书中的代码有几处错误,纠正如下:
P23 Output()函数中的
P24 Init()函数中
P25 Search()函数中的
原书中的代码如下:
P23 Output()函数中的
printf("%d",m_arrSwap[i]);
应为
printf("%d",m_SwapArray[i]);
P24 Init()函数中
m_nCakeCnt=n;
应为
m_nCakeCnt=nCakeCnt;
P25 Search()函数中的
<pre name="code" class="html">m_arrSwap[i]=m_ReserveCakeArray[i];
应为
m_SwapArray[i]=m_ReserveCakeArray[i];
原书中的代码如下:
#include <stdio.h>
#include <assert.h>
/***************************************************************************/
//
//烙饼排序问题实现
//
/***************************************************************************/
class CPrefixSorting
{
public:
CPrefixSorting()
{
m_nCakeCnt=0;
m_nMaxSwap=0;
}
//
//计算烙饼翻转信息
//
//pCakeArray 存储烙饼索引数组
//nCakeCnt 烙饼个数
void Run(int* pCakeArray, int nCakeCnt)
{
Init(pCakeArray,nCakeCnt);
m_nSearch=0;
Search(0);
}
//
//输出烙饼具体翻转的次数
//
void Output()
{
for(int i=0;i<m_nMaxSwap;i++)
printf("%d",m_SwapArray[i]);
printf("\n | Search Times | : %d\n",m_nSearch);
printf("Total Swap Time = %d\n",m_nMaxSwap);
}
private:
//
//初始化数组信息
//
//pCakeArray 存储烙饼索引数组
//nCakeCnt 烙饼个数
//
void Init(int* pCakeArray, int nCakeCnt)
{
assert(pCakeArray!=NULL); //断言:若烙饼索引数组为空,则退出程序
assert(nCakeCnt>0); //断言:若烙饼个数为0,则退出程序
m_nCakeCnt=nCakeCnt; //??????
//初始化烙饼数组
m_CakeArray=new int[m_nCakeCnt];
assert(m_CakeArray!=NULL);
for(int i=0;i<m_nCakeCnt;i++)
m_CakeArray[i]=pCakeArray[i];
//设置最多交换次数信息
m_nMaxSwap=UpBound(m_nCakeCnt);
//初始化交换结果数组
m_SwapArray=new int[m_nMaxSwap];
assert(m_SwapArray!=NULL);
//初始化中间结果交换信息
m_ReserveCakeArray=new int[m_nMaxSwap];
for(i=0;i<m_nMaxSwap;i++)
m_ReserveCakeArray[i]=m_CakeArray[i];
m_ReserveCakeArraySwap=new int[m_nMaxSwap];
}
//
//返回当前翻转次数的上界
//
int UpBound(int nCakeCnt)
{
return nCakeCnt*2;
}
//
//返回当前翻转次数的下界
//
int LowerBound(int* pCakeArray,int nCakeCnt)
{
int t,ret=0;
//根据当前数组的排序信息情况来判断最少需要交换多少次
for(int i=1;i<nCakeCnt;i++)
{
//判断位置相邻的两个烙饼,是否在尺寸上是相邻的
t=pCakeArray[i]-pCakeArray[i-1];
if((t==1)||(t==-1))
{}
else
ret++;
}
return ret;
}
//
//排序的主函数
//
void Search(int step)
{
int i,nEstimate;
m_nSearch++; //当前搜索次数加1
//估算这次搜索所需要的最小交换次数
nEstimate=LowerBound(m_ReserveCakeArray,m_nCakeCnt);
if(step+nEstimate>m_nMaxSwap)
return;
//如果已经排好序,即翻转完成,输出结果
if(IsSorted(m_ReserveCakeArray,m_nCakeCnt))
{
if(step<m_nMaxSwap)
{
m_nMaxSwap=step;
for(i=0;i<m_nCakeCnt;i++)
m_SwapArray[i]=m_ReserveCakeArray[i];
//????????????????????????
}
return;
}
//
//递归,进行翻转
//
for(i=1;i<m_nCakeCnt;i++)
{
Revert(0,i);
m_ReserveCakeArraySwap[step]=i;
Search(step+1);
Revert(0,i);
}
}
//
//判断是否已经排好序
//true:已经排好序
//false:未排好序
//
bool IsSorted(int* pCakeArray,int nCakeCnt)
{
for(int i=1;i<nCakeCnt;i++)
if(pCakeArray[i]<pCakeArray[i-1])
return false;
return true;
}
//
//翻转烙饼信息
//
void Revert(int nBegin,int nEnd)
{
assert(nEnd>nBegin);
int i,j,t;
//翻转烙饼信息
for(i=nBegin,j=nEnd;i<j;i++,j--)
{
t=m_ReserveCakeArray[i];
m_ReserveCakeArray[i]=m_ReserveCakeArray[j];
m_ReserveCakeArray[j]=t;
}
}
private:
int* m_CakeArray; //烙饼信息数组
int m_nCakeCnt; //烙饼个数
int m_nMaxSwap; //最多交换次数,根据前面的推断,这里最多为m_nCakeCnt * 2
int* m_SwapArray; //交换结果数组
int* m_ReserveCakeArray; //当前翻转烙饼信息数组
int* m_ReserveCakeArraySwap;//当前翻转烙饼交换结果
int m_nSearch; //当前搜索次数信息
};
int main()
{
CPrefixSorting Problem;
//int[] cakeArray = {3,2,1,6,5,4,9,8,7,0};
int cakeArray[10] = {3,2,1,6,5,4,9,8,7,0};
Problem.Run(cakeArray,10);
Problem.Output();
return 0;
}