zoukankan      html  css  js  c++  java
  • 数据结构与算法 -- 回溯算法

    1、八皇后问题

    //8皇后问题--回溯算法
    public class Recall {
        int[] result = new int[8];//全局或成员变量,下标表示行,值表示queue存储在哪一列
        
        public static void main(String[] args) {
            Recall recall = new Recall();
            recall.cal8queues(0);
        }
        
        public void cal8queues(int row) {//调用方式:cal8queues(0)
            if(row == 8) {//8个棋子都放置好了,打印结果
                printQueues(result);
                return;//8行棋子都放好了,已经没法再往下递归了,所以就return
            }
            for(int column=0; column<8; column++) {//每一行都有8种放法
                if(isOk(row, column)) {//有些放法不满足要求
                    result[row] = column;//第row行的棋子放到了column列
                    cal8queues(row+1);//考察下一行
                }
            }
        }
        
        private boolean isOk(int row, int column) {//判断row行column列放置是否合适
            int leftup = column-1, rightup = column+1;
            for(int i=row-1; i>=0; i--) {//逐行往上考察每一行
                if(result[i] == column) {
                    return false;//第i行的column列有棋子吗?
                }
                if(leftup >= 0) {//考察左上对角线:第i行leftup列有棋子吗?
                    if(result[i] == leftup) {
                        return false;
                    }
                }
                if(rightup < 8) {//考察右上对角线:第i行rightup列有棋子吗?
                    if(result[i] == rightup) {
                        return false;
                    }
                }
                leftup--;
                rightup++;
            }
            return true;
        }
        private void printQueues(int[] result) {//打印一个二维矩阵
            for(int row=0; row<8; row++) {
                for(int column=0; column<8; column++) {
                    if(result[row] == column) {
                        System.out.print("Q");
                    }else {
                        System.out.print("*");
                    }
                }
                System.out.println();
            }
            System.out.println();
        }
    }

     2、0-1背包问题

    //0-1背包问题--回溯算法
    public class Recall {
        public int maxW = Integer.MIN_VALUE;//存储背包中物品总重量的最大值
        /**
         * cw 表示当前已经装进去的物品的重量和;i表示考察到哪个物品了
         * w 背包重量;items表示每个物品的重量;n表示物品个数
         * 假设背包可承受重量100,物品个数10,物品重量存储在数组a中,那可以这样调用函数:f(0, 0, a, 10, 100)
         */
        public void f(int i, int cw, int[] items, int n, int w) {
            if(cw == w || i == n) {//cw==w表示装满了;i==n表示已经考察完所有的物品
                if(cw > maxW) {
                    maxW = cw;
                }
                return;
            }
            f(i+1, cw, items, n, w);
            if(cw + items[i] <= w) {//已经超过背包可以承受的重量的时候,就不要再装了
                f(i+1, cw+items[i], items, n, w);
            }
        }
        
        public static void main(String[] args) {
            Recall recall = new Recall();
            int[] items = {1, 2, 3, 4, 5};
            recall.f(0, 0, items, 5, 12);
            System.out.println("背包所装物品的重量为:" + recall.maxW);
        }
    }

    3、0-1背包问题【升级版】

    //0-1背包问题【升级版】--回溯算法
    public class Recall {
        public int maxV = Integer.MIN_VALUE;//结果放到maxV中
        private int[] items = {2, 2, 4, 6, 3};//物品的重量
        private int[] value = {3, 4, 8, 9, 6};//物品的价值
        private int n = 5;//物品个数
        private int w = 9;//背包承受的最大重量
      
        public void f(int i, int cw, int cv) {//调用方式 f(0, 0, 0)
            if(cw == w || i == n) {//cw==w表示装满了;i==n表示已经考察完所有的物品
                if(cv > maxV) {
                    maxV = cv;
                }
                return;
            }
            f(i+1, cw, cv);//选择不装第i个物品
            if(cw + items[i] <= w) {
                f(i+1, cw+items[i], cv+value[i]);//选择装第i个物品
            }
        }
      
        public static void main(String[] args) {
            Recall recall = new Recall();
            recall.f(0, 0, 0);
            System.out.println("背包所装物品的最大价值为:" + recall.maxV);
        }
    }

    4、正则表达式

    //正则表达式问题--回溯算法
    public class Pattern {
        private boolean matched = false;//是否匹配标识
        private char[] pattern;//正则表达式
        private int plen;//正则表达式长度
        
        public Pattern(char[] pattern, int plen) {
            this.pattern = pattern;
            this.plen = plen;
        }
        
        public boolean match(char[] text, int tlen) {//文本串及长度
            matched = false;
            rmatch(0, 0, text, tlen);
            return matched;
        }
        private void rmatch(int ti, int pj, char[] text, int tlen) {
            if(matched) {
                return;//如果已经匹配了,就不要继续递归了
            }
            if(pj == plen) {//正则表达式结尾了
                if(ti == tlen) {
                    matched = true;//文本串也到结尾了
                }
                return;
            }
            if(pattern[pj] == '*') {//*匹配任意个字符
                for(int k=0; k<=tlen-ti; k++) {
                    rmatch(ti+k, pj+1, text, tlen);
                }
            }else if(pattern[pj] == '?') {//?匹配0或1个字符
                rmatch(ti, pj+1, text, tlen);
                rmatch(ti+1, pj+1, text, tlen);
            }else if(ti<tlen && pattern[pj] == text[ti]) {//纯字符匹配才行
                rmatch(ti+1, pj+1, text, tlen);
            }
        }
        
        public static void main(String[] args) {
            char[] patternStr = "a?bc*r?".toCharArray();
            Pattern patternMain = new Pattern(patternStr, patternStr.length);
            String text = "abcqwrrtw";
            System.out.println("匹配结果:" + patternMain.match(text.toCharArray(), text.length()));
        }
    }
  • 相关阅读:
    基于pandas索引的数据查找、排序和去重小结
    python中的变量引用小结
    python中日志logging模块和异常捕获traceback模块的使用
    undefined和not defined
    spring 整合dubbo session中调用用户转换异常 classcastEcxeption
    iframe占满整个屏幕
    freemarker获取url中参数
    H5的新增标签
    Redis
    类加载过程
  • 原文地址:https://www.cnblogs.com/jiangwangxiang/p/11071027.html
Copyright © 2011-2022 走看看