Java 文本对齐算法

Java 文本对齐算法,java,recursion,dynamic-programming,Java,Recursion,Dynamic Programming,这是DP中一个非常著名的问题,有人能帮助可视化它的递归部分吗?排列或组合将如何生成 问题参考。 P>给定最大行宽度为L,证明文本T的思想是考虑文本的所有后缀(考虑词而不是字符以形成后缀是精确的)。 动态规划不过是“小心的暴力”。 如果你考虑蛮力的方法,你需要做如下。 考虑把1,2。。第一行有n个单词 对于案例1中所描述的每一个案例(如我的话都放在第1行),考虑1, 2的情况。在第二行输入n-i个单词,然后在第三行输入剩余的单词,依此类推 让我们只考虑问题来找出一个单词在一行的开头的代价。 一般来

这是DP中一个非常著名的问题,有人能帮助可视化它的递归部分吗?排列或组合将如何生成

问题参考。

P>给定最大行宽度为L,证明文本T的思想是考虑文本的所有后缀(考虑词而不是字符以形成后缀是精确的)。 动态规划不过是“小心的暴力”。 如果你考虑蛮力的方法,你需要做如下。

  • 考虑把1,2。。第一行有n个单词
  • 对于案例1中所描述的每一个案例(如我的话都放在第1行),考虑1, 2的情况。在第二行输入n-i个单词,然后在第三行输入剩余的单词,依此类推 让我们只考虑问题来找出一个单词在一行的开头的代价。 一般来说,我们可以将DP(i)定义为将第(i-1)个字视为行的开头的成本

    我们如何形成DP(i)的递推关系?

    如果第j个字是下一行的开头,那么当前行将包含字[i:j)(j不包括在内),第j个字作为下一行开头的成本将是DP(j)。 因此DP(i)=DP(j)+在当前行中放置单词[i:j]的成本 由于我们希望将总成本降至最低,DP(i)可定义如下

    重复关系:

    DP(i)=min{DP(j)+在当前行中放置单词[i:j]的成本} 对于[i+1,n]中的所有j

    注:j=n表示下一行中没有剩余的单词

    基本大小写:DP(n)=0=>此时没有字可写

    总结如下:

  • 子问题:后缀,单词[:i]
  • 猜猜:下一行从哪里开始,选择n-i->O(n)
  • 重复:DP(i)=最小{DP(j)+在当前行中放置单词[i:j]的成本} 如果我们使用记忆,大括号内的表达式应该花费O(1)次,循环运行O(n)次(选择次数)。 i从n到0不等=>因此总复杂度降低到O(n^2)
  • 现在,即使我们推导出了证明文本的最小成本,我们也需要通过跟踪在上述表达式中选择为最小值的j值来解决原始问题,以便我们以后可以使用相同的值来打印证明文本。其思想是保留父指针

    希望这有助于您理解解决方案。下面是上述想法的简单实现

     public class TextJustify {
        class IntPair {
            //The cost or badness
            final int x;
    
            //The index of word at the beginning of a line
            final int y;
            IntPair(int x, int y) {this.x=x;this.y=y;}
        }
        public List<String> fullJustify(String[] words, int L) {
            IntPair[] memo = new IntPair[words.length + 1];
    
            //Base case
            memo[words.length] = new IntPair(0, 0);
    
    
            for(int i = words.length - 1; i >= 0; i--) {
                int score = Integer.MAX_VALUE;
                int nextLineIndex = i + 1;
                for(int j = i + 1; j <= words.length; j++) {
                    int badness = calcBadness(words, i, j, L);
                    if(badness < 0 || badness == Integer.MAX_VALUE) break;
                    int currScore = badness + memo[j].x;
                    if(currScore < 0 || currScore == Integer.MAX_VALUE) break;
                    if(score > currScore) {
                        score = currScore;
                        nextLineIndex = j;
                    }
                }
                memo[i] = new IntPair(score, nextLineIndex);
            }
    
            List<String> result = new ArrayList<>();
            int i = 0;
            while(i < words.length) {
                String line = getLine(words, i, memo[i].y);
                result.add(line);
                i = memo[i].y;
            }
            return result;
        }
    
        private int calcBadness(String[] words, int start, int end, int width) {
            int length = 0;
            for(int i = start; i < end; i++) {
                length += words[i].length();
                if(length > width) return Integer.MAX_VALUE;
                length++;
            }
            length--;
            int temp = width - length;
            return temp * temp;
        }
    
    
        private String getLine(String[] words, int start, int end) {
            StringBuilder sb = new StringBuilder();
            for(int i = start; i < end - 1; i++) {
                sb.append(words[i] + " ");
            }
            sb.append(words[end - 1]);
    
            return sb.toString();
        }
      }
    
    公共类TextJustify{
    类整数对{
    //代价还是坏处
    最终整数x;
    //一行开头的单词索引
    最终INTY;
    IntPair(intx,inty){this.x=x;this.y=y;}
    }
    public List fullJustify(字符串[]个字,整数L){
    IntPair[]备注=新的IntPair[words.length+1];
    //基本情况
    memo[words.length]=新的整数对(0,0);
    对于(int i=words.length-1;i>=0;i--){
    int分数=整数最大值;
    int nextLineIndex=i+1;
    对于(int j=i+1;j currScore){
    分数=当前分数;
    nextLineIndex=j;
    }
    }
    备注[i]=新的整数对(分数,下一行索引);
    }
    列表结果=新建ArrayList();
    int i=0;
    while(i宽度)返回Integer.MAX_值;
    长度++;
    }
    长度--;
    int temp=宽度-长度;
    返回温度*温度;
    }
    私有字符串getLine(字符串[]个字,整数开始,整数结束){
    StringBuilder sb=新的StringBuilder();
    for(int i=start;i
    欢迎使用堆栈溢出,请阅读并编辑您的问题:)