实现List按与一个字符串的相似度和字母顺序排序(适用于模糊查询后的排序)
因公司业务需要,自己写了一个,保存起来以后可能还会用到。如果还有更好的方法或者算法,希望大家提出来。
1、简单的相似度算法(自己想到的)
因为List中每个String都会包含一个标准的字符串,那么每个字符串除了标准字符串的左边或者右边都会有一定量的字符。相似度的定义是多出来的字符*100(只适用与在标准字符串左边最多还多出99字符的字符串,可以根据情况扩大)+标准字符串左边的字符的个数。例:标准字符串是"abc",那么字符串"abcd"与标准字符串的相似度是100,字符串"dabc"与标准字符串的相似度是101,字符串"xabcz"与标注字符串的相似度是201,字符串"xzabc"与标准字符串的相似度是202。因此这里定义的相似度最小为0,其越小就越接近标准字符串。说到这里这个就不应该就相似度、应该叫偏差度。
1 private static Integer getSemblance(String toBeComparedString, String standardString){ 2 if(StringUtils.isBlank(toBeComparedString) || StringUtils.isBlank(standardString)){ 3 LOGGER.error("出错,待比较的字符串或标注字符串为空"); 4 return null; 5 } 6 Integer diffIndex = toBeComparedString.length() - standardString.length(); 7 if(diffIndex<0){ 8 LOGGER.error("出错,待比较的字符串比标准的字符串还要短"); 9 return null; 10 } 11 Integer headDiffIndex = toBeComparedString.indexOf(standardString); 12 if(headDiffIndex<0){ 13 LOGGER.error("出错,待比较的字符串不包含标准字符串"); 14 return null; 15 } 16 return diffIndex*100+headDiffIndex; 17 }
2、java中快速排序的方法(可以自定义排序规则)
jave中的java.util.Comparator。Comparator<T>是一个快速排序的接口,只要写个类实现接口的排序规则的方法就行。
1 /** 2 * File Name:Sort.java 3 * Package Name:[packName] 4 * Date:2015年11月12日上午10:57:14 5 * Copyright (c) 2015年11月12日, Pwenlee All Rights Reserved. 6 * 7 */ 8 9 package com.olymtech.cs.openplatform.ds.service.impl; 10 11 import java.util.Comparator; 12 13 /** 14 * ClassName:Sort <br/> 15 * Function: 字符串compaer排序. <br/> 16 * Reason: TODO ADD REASON. <br/> 17 * Date: 2015年11月12日 上午10:57:14 <br/> 18 * @author PwenLee 19 * @version 20 * @see 21 */ 22 public class Sort implements Comparator<String> { 23 24 /** 25 * Function: 字符串排序的规则. <br/> 26 * @Date: 2015年11月12日 上午10:57:14 <br/> 27 * @author PwenLee 28 */ 29 @Override 30 public int compare(String arg0, String arg1) { 31 if(arg0.compareTo(arg1)>0){ 32 return 1; 33 }else if(arg0.compareTo(arg1)<0){ 34 return -1; 35 }else{ 36 return 0; 37 } 38 } 39 }
1 //new后面是实现compare的类 2 Comparator<String> comparator = new Sort(); 3 Collections.sort(List, comparator);
3、主算法
1 1 public static List<String> sort(List<String> toBeComparedStringList, String standardString){ 2 2 List<String> listAfterSort = new ArrayList<String>(); //定义待比较字符串List的相似度的List List<Integer> listSemblance = new ArrayList<Integer>(); if(toBeComparedStringList.size()<=0){ System.out.println("出错,待比较的字符串为空"); return null; } //初始化相似度的List for(int i=0;i<toBeComparedStringList.size();i++){ listSemblance.add(getSemblance(toBeComparedStringList.get(i),standardString)); } while(true){ //循环的终止条件,当相似度的List里面全是Integer的最大值就跳出循环 if((Integer)Collections.min(listSemblance).intValue() == Integer.MAX_VALUE.intValue()){ break; } else{ //取到相似度最小的位置 Integer minIndex = getMinIndex(listSemblance); //并记录初始的相似度 Integer origSemblance = listSemblance.get(minIndex); //将这个位置的相似度置为Integer的最大值 listSemblance.set(minIndex, Integer.MAX_VALUE); if(origSemblance.intValue() != listSemblance.get(getMinIndex(listSemblance)).intValue()){ //如果相似度List中没有和初始相似度相同的 //则取出待排序List对应位置的字符串 String minString = toBeComparedStringList.get(minIndex); listAfterSort.add(minString); }else{ //如果相似度List中还有有和初始相似度相同的 则还原该位置相似度的初始值 listSemblance.set(minIndex, origSemblance); List<String> tempList = new ArrayList<String>(); //将相似度List中的所有该相似度的位置记下,将这些位置的相似度置为Integer的最大值,并取出待排序List中对应的String for(int i=0;i<listSemblance.size();i++){ if(listSemblance.get(i).intValue == origSemblance.intValue){ listSemblance.set(i, Integer.MAX_VALUE); tempList.add(toBeComparedStringList.get(i)); } } //将相似度相同的临时的List进行排序 Collections.sort(tempList, comparator); listAfterSort.addAll(tempList); } } } return listAfterSort; }
附件中是源码,还包括了排序后截取自定义size的方法。
链接:http://pan.baidu.com/s/1hqpW8b6 密码:6mn1