C++
#include <stdio.h>
#include <stdlib.h>
class CPrefixSorting
{
public:
CPrefixSorting()
{
m_nCakeCnt = 0;
m_nMaxSwap = 0;
}
~CPrefixSorting()
{
if(m_CakeArray != NULL)
{
delete m_CakeArray;
}
if(m_SwapArray != NULL)
{
delete m_SwapArray;
}
if(m_ReverseCakeArray != NULL)
{
delete m_ReverseCakeArray;
}
if(m_ReverseCakeArraySwap != NULL)
{
delete m_ReverseCakeArraySwap;
}
}
//计算烙饼翻转信息
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\t",m_SwapArray[i]);
}
printf("\n | Search Times | :%d\n", m_nSearch);
printf("Total Swap times = %d\n", m_nMaxSwap);
}
private:
//初始化
void Init(int * pCakeArray, int nCakeCnt)
{
assert(pCakeArray != NULL);
assert(nCakeCnt > 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 = UpperBound(m_nCakeCnt);
//初始化交换结果数组
m_SwapArray = new int[m_nMaxSwap +1];
assert(m_SwapArray != NULL);
//初始化中间交换结果信息
m_ReverseCakeArray = new int[m_nCakeCnt];
for(int i = 0; i < m_nCakeCnt; i++)
{
m_ReverseCakeArray[i] = m_CakeArray[i];
}
m_ReverseCakeArraySwap = new int[m_nMaxSwap];
}
//寻找当前翻转的上界
int UpperBound(int nCakeCnt)
{
return nCakeCnt * 2;
}
//寻找当前翻转的下界
int LowerBound(int * pCakeArray, int nCakeCnt)
{
int t, ret = 0;
for(int i = 0; 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++;
//估算这次搜索所需的最小交换次数
nEstimate = LowerBound(m_ReverseCakeArray, m_nCakeCnt);
if(step + nEstimate >= m_nMaxSwap)
{
return;
}
//如果排序完成,输出结果
if(IsSorted(m_ReverseCakeArray, m_nCakeCnt))
{
if(step < m_nMaxSwap)
{
m_nMaxSwap = step;
for(i = 0; i < m_nMaxSwap; i++)
{
m_SwapArray[i] = m_ReverseCakeArraySwap[i];
}
}
return;
}
//递归进行翻转
for(i = 1; i < m_nCakeCnt; i++)
{
Reverse(0,i);
m_ReverseCakeArraySwap[step] = i;
Search(step + 1);
Reverse(0,i);
}
}
//排序
bool IsSorted(int * pCakeArray, int nCakeCnt)
{
for(int i = 0; i < nCakeCnt; i++)
{
if(pCakeArray[i - 1] > pCakeArray[i])
{
return false;
}
}
return true;
}
//翻转烙饼信息
void Reverse(int nBegin, int nEnd)
{
assert(nEnd > nBegin);
int i, j, t;
for(i = nBegin,j = nEnd; i < j; i++, j--)
{
t = m_ReverseCakeArray[i];
m_ReverseCakeArray[i] = m_ReverseCakeArray[j];
m_ReverseCakeArray[j] = t;
}
}
void assert(int n)
{
if(n == 1)
{
}
else
{
exit(1);
}
}
private:
int * m_CakeArray;
int m_nCakeCnt;
int m_nMaxSwap;
int * m_SwapArray;
int * m_ReverseCakeArray;
int * m_ReverseCakeArraySwap;
int m_nSearch;
};
int main()
{
int a[10] = {2,9,8,45,21,18,36,85,4,1};
CPrefixSorting problem = /*new */CPrefixSorting();
for(int i = 2;i < 11;i++)
{
printf("number = %d\n",i);
problem.Run(a,i);
problem.Output();
printf("\n");
}
system("pause");
return 0;
}