给定一个单词列表,如何找到重叠的常用字母

时间:2014-10-24 11:49:43

标签: java algorithm time-complexity space-complexity

我有一个单词输入列表。您将第一个单词的后缀检查到下一个单词的前缀。

例如

平静 下一个 探戈舞 额外

{serene,next}= 2common letters    {serene,tango}=0   {serene,extra}= 1
{next,serene}= 0      {next,tango}= 1   {next,extra}= 3
{tango,serene}=0       {tango,next}= 0  {tango,extra}= 0
{extra,serene}=0        {extra,next}=0   {extra,tango}=0   

如果重叠字母得分更好,你也可以切换单词的顺序,即(下一个,宁静的)

所以你检查每个单词的重叠分数,最后返回最高分的单词列表

按输入列表,分数为1 宁静,接下来,探戈,额外= 1

最大分数= 5,返回的输出列表如下:

丝氨酸,下,额外的,探戈

serene,next= 2common letters    serene,tango=0   serene,extra= 1
next,serene= 0                  next,tango= 1   next,extra= 3
tango,serene=0                  tango,next= 0  tango,extra= 0
extra,serene=0                   extra,next=0   extra,tango=0   

根据复杂程度计算重叠分数和返回最大分数列表的最佳方法是什么?

我只能计算连续单词的重叠分数,但这并不能给出最高分。

2 个答案:

答案 0 :(得分:1)

您可以在列表中添加所有字母,然后执行retainAll,如:

String one="next", two="extra";
List<Character> oneList=new ArrayList<Character>();
for(Character c : one.toCharArray()) {
    oneList.add(c);
}
List<Character> twoList=new ArrayList<Character>();
for(Character c : two.toCharArray()) {
    twoList.add(c);
}
List<Character> finalList = new ArrayList<Character>(oneList);
finalList.retainAll(twoList);
System.out.print("There are "+finalList.size()+ " letters in common and they are : ");
for(Character c: finalList){
    System.out.print(c+" ");
}

不幸的是,我不知道将原始数据类型转换为使用Google Guava library或其他3方API的其他列表的更好方法。如果你想优化代码然后查看它们。

答案 1 :(得分:0)

我不确定这是最有效的方法,但我会计算任意两个连续单词的分数矩阵,然后只需使用回溯来找到最长的链。

回溯的效率声誉很差,但在目前的使用案例中,我认为它可以使用,因为我们可以在2个单词得分为0时立即停止分析。所以我可以找到正确的最高分5和11次操作中的最佳顺序。

代码:

public class Overlap {
    int[][] matrix;
    int total;
    int [] bestSeq;
    String[] strings;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] strings) {
        // TODO code application logic here
        Overlap overlap = new Overlap(strings);
        int score = overlap.compute();
        System.out.println("Best score : " + score);
        for (int i : overlap.bestSeq) {
            System.out.print(" " + strings[i]);
        }
        System.out.println(" in " + overlap.total + " operations");

    }

    public Overlap(String[] strings) {
        this.strings = strings;
        matrix = matrix(strings);
        bestSeq = new int[strings.length];
    }

    int compute() {
        total = 0;
        int[] sequence = new int[strings.length];
        for (int i=0; i < strings.length; i++) {
            sequence[i] = i;
        }
        return this.bestSequence(-1, sequence, bestSeq);
    }

    static int findOverlap(String a, String b) {
        int la = a.length();
        int l = Math.min(la, b.length());
        while (l > 0) {
            if (a.substring(la - l).equals(b.substring(0, l))) {
                return l;
            }
            l--;
        }
        return 0;
    }

    static int[][] matrix(String[] strings) {
        int l = strings.length;
        int[][] mx = new int[l][l];
        for (int i = 0; i < l - 1; i++) {
            for (int j = i + 1; j < l; j++) {
                mx[i][j] = findOverlap(strings[i], strings[j]);
            }
        }
        return mx;
    }

    int bestSequence(int initial, int[] sequence, int[] best) {
        total += 1;
        int max = 0;
        if (best.length != sequence.length) {
            throw new java.lang.IllegalArgumentException();
        }
        int l = sequence.length;
        int[] newseq = new int[l - 1];
        int[] newbest = new int[l - 1];
        for (int i : sequence) {
            int val = (initial == -1) ? 0 : matrix[initial][i];
            if ((val > 0) || (initial == -1)) {
                int k = 0;
                for (int j : sequence) {
                    if (j != i) {
                        newseq[k++] = j;
                    }
                }
                val += bestSequence(i, newseq, newbest);
                if (val > max) {
                    max = val;
                    best[0] = i;
                    System.arraycopy(newbest, 0, best, 1, l - 1);
                }
            }
        }
        if (max == 0) {
            System.arraycopy(sequence, 0, best, 0, l);
        }
        return max;
    }
}

使用参数serene next tango extra,它会打印:

Best score : 5
 serene next extra tango
in 11 operations