标签:
问题:写出一个程序,对于n块大小不一的烙饼,输出最优化的翻饼过程?要保证烙饼按照大小次序摆好——小的在上面,大的在下面。
package chapter1youxizhilePrefixSorting; import java.util.Scanner; /** * 一摞烙饼的 * @author DELL * */ public class PrefixSorting { private int[] m_CakeArray; //烙饼信息数组 private int m_nCakeCnt; //烙饼个数 private int m_nMaxSwap; //最多交换次数,根据推断,最多为(m_nCakeCnt-1)*2; private int[] m_SwapArray; //交换结果数组 private int[] m_ReverseCakeArray; //当前翻转烙饼信息数组 private int[] m_ReverseCakeArraySwap; //当前翻转烙饼交换结果数组 private int m_nSearch; //当前搜索次数信息 public PrefixSorting(int[] pCakeArray, int nCakeCnt){ m_nCakeCnt = 0; m_nMaxSwap = 0; Run(pCakeArray, nCakeCnt); } /** * 计算烙饼翻转信息 * @param pCakeArray 存储烙饼索引数组 * @param nCakeCnt 烙饼个数 */ public void Run(int[] pCakeArray, int nCakeCnt){ Init(pCakeArray, nCakeCnt); m_nSearch = 0; Search(0); } //输出烙饼具体翻转次数 public void Output(){ System.out.print("交换结果数组为:"); for(int i=0;i<m_nMaxSwap;i++){ System.out.print(m_SwapArray[i]+" "); } System.out.println("\n|Search Times| : "+ m_nSearch); System.out.println("Total Swap times = "+ m_nMaxSwap); } /** * 初始化数组信息 * @param pCakeArray 存储烙饼索引数组 * @param nCakeCnt 烙饼个数 */ private void Init(int[] pCakeArray, int nCakeCnt){ if(pCakeArray==null) System.out.println("烙饼索引数组为空!"); if(nCakeCnt <= 0) System.out.println("烙饼个数非法!"); m_nCakeCnt = nCakeCnt; //初始化烙饼数组 m_CakeArray = new int[m_nCakeCnt]; for(int i=0;i<m_nCakeCnt;i++){ m_CakeArray[i] = pCakeArray[i]; } //设置最多交换次数信息 m_nMaxSwap = UpBound(m_nCakeCnt); //初始化交换结果数组 m_SwapArray = new int[m_nMaxSwap]; //初始化中间交换结果信息 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]; } /** * 寻找当前翻转的上界 * @param nCakeCnt 烙饼个数 * @return */ private int UpBound(int nCakeCnt){ return (nCakeCnt-1)*2; } /** * 寻找当前翻转的下界 * @param pCakeArray 当前翻转烙饼信息数组 * @param nCakeCnt 当前烙饼数量 * @return */ private int LowerBound(int[] pCakeArray, int nCakeCnt){ int t, ret = 0; //根据当前数组的排序信息情况来判断最少需要交换多少次 for(int i=1;i<nCakeCnt;i++){ //判断位置相邻的两个烙饼,是否为尺寸排序上相邻的 t = pCakeArray[i] - pCakeArray[i-1]; if(Math.abs(t)==1){ //尺寸排序上相邻不计数 }else{ ret++; } } return ret; } //排序的主函数 private 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++){ Revert(0,i); if(step<m_nMaxSwap) m_ReverseCakeArraySwap[step] = i; Search(step+1); Revert(0,i); } } /** * 判断是否排好序 * @param pCakeArray 当前翻转烙饼信息数组 * @param nCakeCnt 烙饼数量 * @return */ private boolean IsSorted(int[] pCakeArray, int nCakeCnt){ for(int i=1;i<nCakeCnt;i++){ if(pCakeArray[i-1] > pCakeArray[i]){ return false; } } return true; } /** * 翻转烙饼信息 * @param nBegin 开始位置 * @param nEnd 结束位置 */ private void Revert(int nBegin, int nEnd){ if(nBegin>=nEnd){ System.out.println("参数信息有误!开始位置不能大于等于结束位置!"); } 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; } } public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("请输入烙饼从上到下的半径,以逗号分隔:"); String s = input.nextLine(); String[] ch = s.split(","); // int nCakeCnt = 10; int nCakeCnt = ch.length; int[] pCakeArray = new int[nCakeCnt]; for(int i=0;i<nCakeCnt;i++){ pCakeArray[i] = Integer.parseInt(ch[i]); } // int[] pCakeArray = {3,2,1,6,5,4,9,8,7,0}; PrefixSorting ps = new PrefixSorting(pCakeArray, nCakeCnt); ps.Output(); } }
程序运行结果如下:
请输入烙饼从上到下的半径,以逗号分隔: 3,2,1,6,5,4,9,8,7,0 交换结果数组为:4 8 6 8 4 9 |Search Times| : 148015 Total Swap times = 6
标签:
原文地址:http://www.cnblogs.com/gaopeng527/p/4600372.html