JSP+Servlet实现的一个图片分享网站7_模糊搜索

实现功能

最基础的搜索功能就是包含连续的搜索框中的值,这个可以用mysql的LIKE很容易实现。但是更高级的模糊搜索应该是可以不连续的包含并且有一定的容错率。
我的搜索功能分为按照标题搜索和按照主题搜索,并且搜索结果可以根据发布时间或热度排序。另外,我实现了一个相似度的功能,即搜索结果和搜索内容的相似度,100%即为搜索框的所有内容都要包含才能被搜索到,0%则可以搜索到全部的图片。比如,我输入park,相似度调为50%,那么只要包含p和a或p和r或p和k或a和r或a和k或r和k,即可。
在这里插入图片描述

思路

其实这就是组合数的种类,设搜索内容长度为m,相似度为s,则抽取的字母的长度n=m*s,那么就有C(m,n)种结果。
采用递归思想,从m个字母里取n个只需先取第i(0<i<m-n+2)个,再从i+1到m中去n-1个,直到n=1。

代码

    public List<Picture> getPicturesByFuzzyContent(String content,String filter,String sort,int page, int pageSize,int similar){
        //去掉空格
        content = content.replaceAll(" +","");
        //高级模糊
        List<String> contents = fuzzyString(content,similar);
        StringBuilder sql = new StringBuilder("SELECT i.ImageID id, i.Title title, i.PATH path, u.UserName author FROM travelimage i, " +
                "traveluser u WHERE i.UID = u.UID AND (i.");
        if(filter.equals("title")){
            sql.append("Title LIKE '");
            sql.append(contents.get(0));
            sql.append("' ");
            int i = 1;
            while (i < contents.size()){
                sql.append("OR i.Title LIKE '");
                sql.append(contents.get(i));
                sql.append("' ");
                i++;
            }
        }
        else{
            sql.append("Content LIKE '");
            sql.append(contents.get(0));
            sql.append("' ");
            int i = 1;
            while (i < contents.size()){
                sql.append("OR i.Content LIKE '");
                sql.append(contents.get(i));
                sql.append("' ");
                i++;
            }
        }
        sql.append(") ");
        sql.append("ORDER BY ");
        if(sort.equals("hot")){
            sql.append("i.Hot ");
        }
        else {
            sql.append("i.RecentUpdate ");
        }
        sql.append("DESC LIMIT ?,?");
//        System.out.println(sql);
        return getAll(sql.toString(),(page - 1)*pageSize,pageSize);
    }

    private List<String> fuzzyString(String initString,int similar){
        List<String> stringList = new ArrayList<>();
        int length = (int)Math.ceil(similar*initString.length()/100.0) ;
        if(length==0){
            stringList.add("%");
        }
        else {
//            System.out.println(length);
            charsCombinationWithLabel(new StringBuilder("%"),stringList,new StringBuilder(initString),length,1,0);
        }
        return stringList;
    }
    
private void charsCombinationWithLabel(StringBuilder readyString, List<String> stringList, StringBuilder leftString, int needNumber,int lengthOfReady,int begin){
    if(readyString.length() <= lengthOfReady+1){
        readyString.append("%%");//占位
    }
    if(needNumber == 1){
        for(int i = begin; i < leftString.length();i++){
            readyString.setCharAt(lengthOfReady,leftString.charAt(i));
            readyString.setCharAt(lengthOfReady+1,'%');
            stringList.add(String.valueOf(readyString));
        }
    }
    else {
        for(int i = begin;i < leftString.length();i++){
            char toDelete = leftString.charAt(i);
            readyString.setCharAt(lengthOfReady,toDelete);
            readyString.setCharAt(lengthOfReady+1,'%');
            charsCombinationWithLabel(readyString,stringList,leftString,needNumber-1,lengthOfReady+2,i+1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值