Chinaunix首页 | 论坛 | 博客
  • 博客访问: 78849
  • 博文数量: 20
  • 博客积分: 1481
  • 博客等级: 上尉
  • 技术积分: 452
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-11 11:01
文章存档

2011年(2)

2010年(18)

我的朋友

分类: LINUX

2010-11-22 20:23:27

/****************************************************************/
//

// 烙饼排序实现

//

/****************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <assert.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;
            }
            if(m_nCost!=NULL) delete m_nCost;
            if(m_flags!=NULL) delete m_flags;
        }

        //

        // 计算烙饼翻转信息

        // @param

        // 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 times = %d\n", m_nMaxSwap);
        }

    private:

        //

        // 初始化数组信息

        // @param

        // pCakeArray    存储烙饼索引数组

        // nCakeCnt    烙饼个数

        //

        void Init(int* pCakeArray, int nCakeCnt)
        {
            int i;
            assert(pCakeArray != NULL);
            assert(nCakeCnt > 0);

            m_nCakeCnt = nCakeCnt;

            // 初始化烙饼数组

            m_CakeArray = new int[m_nCakeCnt];
            assert(m_CakeArray != NULL);
            for(i = 0; i < m_nCakeCnt; i++)
            {
                m_CakeArray[i] = pCakeArray[i];
            }

            // 设置最多交换次数信息

            m_nMaxSwap = UpBound(m_nCakeCnt);

            // 初始化交换结果数组

            m_SwapArray = new int[m_nMaxSwap + 1];
            assert(m_SwapArray != NULL);

            //init cost info

            m_nCost = new int[nCakeCnt];
            assert(m_nCost != NULL);
            m_flags = new int[nCakeCnt];

            // 初始化中间交换结果信息

            m_ReverseCakeArray = new int[m_nCakeCnt];
            for(i = 0; i < m_nCakeCnt; i++)
            {
                m_ReverseCakeArray[i] = m_CakeArray[i];
            }
            m_ReverseCakeArraySwap = new int[m_nMaxSwap];
        }


        //

        // 寻找当前翻转的上界

        //

        //

        int UpBound(int nCakeCnt)
        {
            return 2*(nCakeCnt-1);
        }

        //

        // 寻找当前翻转的下界

        //

        //

        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;
            int j;
            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;
            }
            // 递归进行翻转

            //

            setFlags();
            for(i = 1; i < m_nCakeCnt; i++)
            {
                if(m_flags[i]==1){
                    Revert(0, i);//we must revert from the first cake.

                    m_ReverseCakeArraySwap[step] = i;
                    Search(step + 1);
                    Revert(0, i);
                }
            }
            clearFlags();
        }
        void clearFlags(){
            int i;
            for(i = 1; i < m_nCakeCnt; i++)
                m_flags[i]=1;
        }
        void setFlags()
        {
            int i;
            int min;
            for(i = 1; i < m_nCakeCnt; i++)
            {
                Revert(0, i);
                m_nCost[i] = calcCost(m_ReverseCakeArray,m_nCakeCnt);
                Revert(0, i);
            }

            min = m_nCost[1];

            for (i=1;i<m_nCakeCnt;i++){
                if(m_nCost[i]<min) min=m_nCost[i];
            }

            for(i=1;i<m_nCakeCnt;i++){
                if(m_nCost[i]==min)
                    m_flags[i]=1;
                else
                    m_flags[i]=0;
            }
        }

        //

        // true : 已经排好序

        // false : 未排序

        //

        bool IsSorted(int* pCakeArray, int nCakeCnt)
        {
            for(int i = 1; i < nCakeCnt; i++)
            {
                if(pCakeArray[i-1] > pCakeArray[i])
                {
                    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_ReverseCakeArray[i];
                m_ReverseCakeArray[i] = m_ReverseCakeArray[j];
                m_ReverseCakeArray[j] = t;
            }

        }

        //caculate cost of the node;

        int calcCost(int *arr, int count){
            int i;
            int t;
            int ret = 0;
            int flag = 0;
            i = count;
            for(;i>1;i--){
                if(!flag && arr[i-1] == i){
                    continue;
                }
                t = arr[i-1]-arr[i-2];
                if( t==1 || t==-1 ){
                    continue;
                }
                ret++;
                flag=1;
            }
            return ret;
        }
    private:

        int* m_CakeArray;    // 烙饼信息数组

        int m_nCakeCnt;    // 烙饼个数

        int m_nMaxSwap;    // 最多交换次数。根据前面的推断,这里最多为

        // m_nCakeCnt * 2

        int* m_SwapArray;    // 交换结果数组


        int* m_ReverseCakeArray;    // 当前翻转烙饼信息数组

        int* m_ReverseCakeArraySwap;    // 当前翻转烙饼交换结果数组

        int m_nSearch;    // 当前搜索次数信息

        int *m_nCost;
        int *m_flags;
};
int main(){
    CPrefixSorting cps2;
    int cakeArray2[10]={3,2,1,6,5,4,9,8,7,0};
    cps2.Run(cakeArray2,10);
    cps2.Output();
    return 0;
}


爬山法的结果。
运行结果:
4 8 6 8 4 9
 |Search Times| : 2333
Total Swap times = 6

附录

gdb常用调试命令
gdb cake | gdb; file cake

break func|lineNo

until LineNo to cross the loop.

n = step over

s = step in

p *a@n = print a[n];打印一个数组

break 11 if var==val...

g++ -g -o cake cake.cpp



阅读(1214) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~