如何在字符串中获得最长的后续子序列?

时间:2013-09-06 06:36:36

标签: java algorithm dynamic-programming

我的Java技能非常生疏,但我正在尝试编写一个程序,提示用户输入一个字符串并显示一个最大长度,增加了有序的字符子序列。例如,如果用户输入Welcome,则程序将输出Welo。如果用户输入WWWWelllcommmeee,程序仍会输出Welo。我已经完成了这么多工作,但它并没有做到它应该做的事情,我老实说不知道为什么。

import java.util.ArrayList;
import java.util.Scanner;

public class Stuff {

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    System.out.println("Please enter a string. ");
    String userString = input.next();
    ArrayList charList = new ArrayList();
    ArrayList finalList = new ArrayList();
    int currentLength = 0;
    int max = 0;

    for(int i = 0; i < userString.length(); i++){
        charList.add(userString.charAt(i));

        for(int j = i; j < userString.length(); j++){
            int k=j+1;
            if(k < userString.length() && userString.charAt(k) > userString.charAt(j)){
                charList.add(userString.charAt(j));
                currentLength++;
            }
        }
    }

    if(max < currentLength){
        max = currentLength;
        finalList.addAll(charList);
    }

    for (int i = 0; i < finalList.size(); i++){
        char item = (char) finalList.get(i);
        System.out.print(item);
    }

    int size1 = charList.size();
    int size2 = finalList.size();
    System.out.println("");
    System.out.println("Size 1 is: " + size1 + " Size 2 is : " + size2);    
  }
 }

我的代码,如果我输入Welcome,则输出WWeceeclcccome

有没有人对我做错了什么提示?

3 个答案:

答案 0 :(得分:1)

在这些情况下,它往往有助于远离键盘并考虑您尝试实现的算法。尝试用文字解释它。

您正在构建单个字符列表,方法是在输入字符串中附加每个字符,然后在其右侧添加与其后继字符串正确的字符。对于输入“欢迎”,这意味着累计输出将显示垂直和内循环的外循环:

W W e c
e e c
l c
c c
o
m
e

总计:WWeceeclccome

答案 1 :(得分:0)

我看不出这种实现的逻辑。这是一个在O(nlogn)时间内运行的更快的解决方案。

import java.util.Scanner;

public class Stuff
{   
    //return the index of the first element that's not less than the target element
    public static int bsearch(char[] arr, int size, int key)
    {
        int left = 0;
        int right = size - 1;
        int mid;
        while (left <= right)
        {
            mid = (left + right) / 2;
            if(arr[mid] < key)
                left = mid + 1;
            else
                right = mid - 1;
        }
        return left;
    }

    public static void main(String[] args) 
    {
        Scanner input = new Scanner(System.in);
        System.out.println("Please enter a string: ");
        String userString = input.next();


        char[] maxArr = new char[userString.length()];
        char[] precedent = new char[userString.length()];
        maxArr[0] = userString.charAt(0);
        precedent[0] = userString.charAt(0);
        int len = 1;
        for(int i = 1; i < userString.length(); i++)
        {
            if(userString.charAt(i) > maxArr[len - 1])
            {
                maxArr[len] = userString.charAt(i);
                precedent[len] = userString.charAt(i);
                len++;
            }
            else
                maxArr[bsearch(maxArr, len, userString.charAt(i))] = userString.charAt(i);
        }

        //System.out.println(len);
        for(int i = 0; i < len; i++)
            System.out.print(precedent[i]);

    }

 }

答案 2 :(得分:0)

在词典编排顺序中使用动态编程O(N ^ 2)意味着如果i / p是abcbcbcd那么o / p可以是abccc,abbbcd,abbccd但是按照词典编排顺序o / p将是abbbcd。

public static String longestIncreasingSubsequence(String input1) {
    int dp[] = new int[input1.length()];
    int i,j,max = 0;
    StringBuilder str = new StringBuilder();

    /* Initialize LIS values for all indexes */
     for ( i = 0; i < input1.length(); i++ )
        dp[i] = 1;

     /* Compute optimized LIS values in bottom up manner */
     for ( i = 1; i < input1.length(); i++ )
        for ( j = 0; j < i; j++ ) 
              if (input1.charAt(i) >= input1.charAt(j) && dp[i] < dp[j]+1)
                  dp[i] = dp[j] + 1;

     /* Pick maximum of all LIS values */
     for ( i = 0; i < input1.length(); i++ ) {
        if ( max < dp[i] ) {
             max = dp[i];
             if (i + 1 < input1.length() && max == dp[i+1] && input1.charAt(i+1) < input1.charAt(i)) {
                 str.append(input1.charAt(i+1));
                 i++;
             } else {
                 str.append(input1.charAt(i)); 
             }
        }
     }
     return str.toString();
}