goodluck 发表于 2010-2-20 14:18:52

J2SE综合--浅析实现排列组合查询算法

<p >所谓的排列组合查询就相当于GOOGLE高级查询中“包含以下全部的字词”查询,也就是说查询中必须包含所有查询关键词,而且他们的顺序可以是任意。以下程序段实现了这一功能。比如输入查询关键字:tom tina则最一般的情况是在程序中使用类似于"select sex from student where name like '%tom%tina%' or name like '%tina%tom%' ordered by age" 的查询语句实现以上的查询,因此如何得到'%tina%tom%' 和'%tom%tina%' 就是该程序和算法要实现的.<BR><BR>首先想到的就是写出一个排列组合的算法,然后用该算法输出所要查询关键字的所有情况,比如 我输入了以下几个关键字: EGG APPLE TIME 则要写一个程序输出 这3个单词的所有排列情况,比如:EGG APPLE TIME 情况2 EGG TIME APPLE, 情况3 APPLE EGG TIME......不用说,大家一看就知道应该是3的阶乘种情况也就是1*2*3这里就不一一列出了。<BR><BR>写出一段程序,或者一个函数比如: public String paileizuhe(String inputstr){......} 该函数返回一个排列组合好的QUERY字符串,比如使用该函数并赋予他两个字符串参数(tom,tina)则:public String pailiezuhe("tom","tina");则输出: "select sex from student where name like '%tom%tina%' or name like '%tina%tom%' ordered by age "这里,我们关心的是如何生成tom tina 的组合即'%tina%tom%' 和'%tom%tina%' 至于生成整个如上的字符串是非常简单的只要用StringBuffer将那些常量悬挂起来最后组合一下就可以了.以下程序给出了排列组合输出的实现:<BR><BR>import java.math.BigInteger;<BR>import java.util.*;<BR><BR>public class PermutationGenerator {<BR><BR>    private int[] a;<BR>    private BigInteger numLeft;<BR>    private BigInteger total;<BR>    public PermutationGenerator(int n) {<BR>      if (n < 1) {<BR>            throw new IllegalArgumentException("Min 1");<BR>      }<BR>      a = new int;<BR>      total = getFactorial(n);<BR>      reset();<BR>    }<BR><BR>    //------<BR>    // Reset<BR>    //------<BR><BR>    public void reset() {<BR>      for (int i = 0; i < a.length; i++) {<BR>            a = i;<BR>      }<BR>      numLeft = new BigInteger(total.toString());<BR>    }<BR><BR>    //------------------------------------------------<BR>    // Return number of permutations not yet generated<BR>    //------------------------------------------------<BR><BR>    public BigInteger getNumLeft() {<BR>      return numLeft;<BR>    }<BR><BR>    //------------------------------------<BR>    // Return total number of permutations<BR>    //------------------------------------<BR><BR>    public BigInteger getTotal() {<BR>      return total;<BR>    }<BR><BR>    //-----------------------------<BR>    // Are there more permutations?<BR>    //-----------------------------<BR><BR>    public boolean hasMore() {<BR>      return numLeft.compareTo(BigInteger.ZERO) == 1;<BR>    }<BR><BR>    //------------------<BR>    // Compute factorial<BR>    //------------------<BR><BR>    private static BigInteger getFactorial(int n) {<BR>      BigInteger fact = BigInteger.ONE;<BR>      for (int i = n; i > 1; i--) {<BR>            fact = fact.multiply(new BigInteger(Integer.toString(i)));<BR>      }<BR>      return fact;<BR>    }<BR><BR>    //--------------------------------------------------------<BR>    // Generate next permutation (algorithm from Rosen p. 284)<BR>    //--------------------------------------------------------<BR><BR>    public int[] getNext() {<BR><BR>      if (numLeft.equals(total)) {<BR>            numLeft = numLeft.subtract(BigInteger.ONE);<BR>            return a;<BR>      }<BR><BR>      int temp;<BR><BR>      // Find largest index j with a < a<BR><BR>      int j = a.length - 2;<BR>      while (a > a) {<BR>            j--;<BR>      }<BR><BR>      // Find index k such that a is smallest integer<BR>      // greater than a to the right of a<BR><BR>      int k = a.length - 1;<BR>      while (a > a) {<BR>            k--;<BR>      }<BR><BR>      // Interchange a and a<BR><BR>      temp = a;<BR>      a = a;<BR>      a = temp;<BR><BR>      // Put tail end of permutation after jth position in increasing order<BR><BR>      int r = a.length - 1;<BR>      int s = j + 1;<BR><BR>      while (r > s) {<BR>            temp = a;<BR>            a = a;<BR>            a = temp;<BR>            r--;<BR>            s++;<BR>      }<BR><BR>      numLeft = numLeft.subtract(BigInteger.ONE);<BR>      return a;<BR><BR>    }<BR>//程序测试入口<BR>    public static void main(String[] args) {<BR><BR>      int[] indices;<BR>      String[] elements = { "1", "2", "3" };<BR>      PermutationGenerator x = new PermutationGenerator(elements.length);<BR>      StringBuffer permutation;<BR><BR>      while (x.hasMore()) {<BR>            permutation = new StringBuffer("%");<BR>            indices = x.getNext();<BR>            for (int i = 0; i < indices.length; i++) {<BR>                permutation.append(elements]).append("%");<BR>            }<BR>            System.out.println(permutation.toString());<BR><BR>      }<BR>    }<BR><BR>}<BR><BR>可以看到我们输入1 2 3 得到了他门所有的排列组合:<BR>%1%2%3%<BR>%1%3%2%<BR>%2%1%3%<BR>%2%3%1%<BR>%3%1%2%<BR>%3%2%1%<BR>由此,我们可以很轻易的得到给定关键字的排列组合了.<BR>需要注意的是,如果查询是输入关键字过多,比如5个则会有120中的组合,6个是720种,要是10个以上的话......所以该算法不适合很多关键字的全排列查询.<BR><BR>当然我的思路是最土和直接的,远不如GOOGLE,只是一种实现而已,如果文章对诸位有所帮助,便起到了作用。谁有更好的方法希望您也能共享出来。<BR><FONT face="Times New Roman" size=3></FONT><p align="center"></p></p>
页: [1]
查看完整版本: J2SE综合--浅析实现排列组合查询算法