代码之家  ›  专栏  ›  技术社区  ›  Vivek Mishra

从列表中提取与给定字符串匹配次数最多的项

  •  -1
  • Vivek Mishra  · 技术社区  · 6 年前

    我的应用程序中有两个ArrayList。第一个arrayList是对象类型的,它包含一个问题列表。现在这个问题列表有一个名为 “关键字” 是的。这是一个字符串,但可以包含逗号分隔的关键字。

    现在我有了一个文本字段,用户可以根据这些关键字搜索问题,我面临的问题是我想根据关键字匹配的数量从问题列表中筛选出问题。

    例如。 用户在搜索文本字段中输入了3个逗号分隔的关键字。我现在想要的是,如果所有3个关键字都与问题列表中的某个值匹配,那么我只需要返回这些元素。这部分很简单,我能做到。

    但是如果我们在列表中没有得到任何精确匹配,那么我必须找到具有最大关键字匹配的项,即,如果逗号分隔的字符串中的3个关键字中的2个与列表中的某个项匹配,则我必须返回该项作为结果。

    存储在列表中的值:

    a) Hi, Hello, Hola, Bonjour.
    
    b) Hi, Hello
    
    c) Hi
    

    在搜索文本中输入的值:

    Hi, Hello, Hola
    

    现在作为回应,我只需要第一个元素,因为它有3个关键字与用户输入的匹配。 我不知道怎么做。此外,我正在从sqlite数据库中获取这个问题列表,因此如果这可以通过一些sql查询完成,那么我也准备好了。

    这是我当前的筛选方法代码

     public ArrayList<QuestionAnswerModal> filter(String keyword,boolean isQuestionSearch) {
        ArrayList<QuestionAnswerModal> arrayList = new ArrayList<>();
    
        if (!isQuestionSearch) {
            for (QuestionAnswerModal modal : questionAnswerArrayList) {
                if (modal.getKeyword().equalsIgnoreCase(keyword)) {
                    arrayList.add(modal);
                }else{
                    ArrayList<String> keywords=new ArrayList<>();
                    String[]word=modal.getKeyword().split(",");
    
                }
            }
            if (arrayList.size() > 0) {
            System.out.print("list size "+arrayList.size());
    
    
            } else {
                  System.out.print("No records found");
    
            }
            return arrayList;
        }else{
            for (QuestionAnswerModal modal : questionAnswerArrayList) {
                if (modal.getQuestion().equalsIgnoreCase(keyword)) {
                    arrayList.add(modal);
                }
            }
            if (arrayList.size() > 0) {
              System.out.print("list size "+arrayList.size());
    
    
            } else {
                System.out.print("No records found");
            }
            return arrayList;
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Eric Green    6 年前

    我把它留给您作为一个练习来了解这个解决方案是如何工作的,但是您可以随意提出任何问题。


    Java 7解决方案:

    import java.util.*;
    
    import static org.apache.commons.lang3.StringUtils.trimToEmpty;
    
    public class MaxMatchFinder {
    
        public static void main(String[] args) {
    
            Map<String, Set<String>> tagsByName = new HashMap<>();
            tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
            tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
            tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
    
            String searchText = "Hi, Hello, Hola";
    
            String[] tagsToFind = searchText.split(",");
    
            Map<String, Integer> matchCountsByEntryName = new HashMap<>();
    
            for (String tagToFind : tagsToFind) {
                for (String entryName : tagsByName.keySet()) {
                    Set<String> tags = tagsByName.get(entryName);
                    if (tags.contains(trimToEmpty(tagToFind))) {
                        Integer count = matchCountsByEntryName.get(entryName);
                        Integer incrementedCount = count == null ? 1 : count + 1;
                        matchCountsByEntryName.put(entryName, incrementedCount);
                    }
                }
            }
    
            List<Map.Entry<String, Integer>> sortedEntries = new ArrayList<>(matchCountsByEntryName.entrySet());
            Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Integer>>() {
                @Override
                public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
                    return e2.getValue().compareTo(e1.getValue());
                }
            });
    
            Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
    
            System.out.printf("Of the entries to be searched," +
                " entry \"%s\" contains the most matches (%d).\n",
                    entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
        }
    }
    

    Java 8解决方案:

    import java.util.*;
    import java.util.stream.Collectors;
    
    import static org.apache.commons.lang3.StringUtils.trimToEmpty;
    
    public class MaxMatchFinder {
    
        public static void main(String[] args) {
    
            Map<String, Set<String>> tagsByName = new HashMap<>();
            tagsByName.put("a", new HashSet<>(Arrays.asList("Hi", "Hello", "Hola", "Bonjour")));
            tagsByName.put("b", new HashSet<>(Arrays.asList("Hi", "Hello")));
            tagsByName.put("c", new HashSet<>(Arrays.asList("Hi")));
    
            String searchText = "Hi, Hello, Hola";
    
            String[] tagsToFind = searchText.split(",");
    
            Map<String, Integer> matchCountsByEntryName = new HashMap<>();
    
            Arrays.stream(tagsToFind)
                    .forEach(tagToFind -> {
                        for (String entryName : tagsByName.keySet()) {
                            Set<String> tags = tagsByName.get(entryName);
                            if (tags.contains(trimToEmpty(tagToFind))) {
                                matchCountsByEntryName.compute(entryName, (k, v) -> v == null ? 1 : v + 1);
                            }
                        }
                    });
    
            List<Map.Entry<String, Integer>> sortedEntries = matchCountsByEntryName.entrySet().stream()
                    .sorted((e1, e2) -> e2.getValue().compareTo(e1.getValue()))
                    .collect(Collectors.toList());
    
            Map.Entry<String, Integer> entryWithMostMatches = sortedEntries.get(0);
    
            System.out.printf("Of the entries to be searched," +
                " entry \"%s\" contains the most matches (%d).\n",
                    entryWithMostMatches.getKey(), entryWithMostMatches.getValue());
        }
    }
    
        2
  •  0
  •   Vivek Mishra    6 年前

    经过许多天的努力,我想我找到了解决问题的办法。下面是我现在使用的代码。

    public ArrayList<QuestionAnswerModal> filter(String keyword, boolean isQuestionSearch) {
        ArrayList<QuestionAnswerModal> arrayList = new ArrayList<>();
        HashMap<String, Integer> countList = new HashMap<>();
    
        if (isQuestionSearch) {
            for (QuestionAnswerModal modal : questionAnswerArrayList) {
                if (modal.getKeyword().equalsIgnoreCase(keyword)) {
                    arrayList.add(modal);
                }
            }
            return arrayList;
        } else {
            //will store the index of the question with largest match
            int[] count = new int[questionAnswerArrayList.size()];
    
            for (int i = 0; i < questionAnswerArrayList.size(); i++) {
                List<String> keywords = new ArrayList<>();
                String[] word = questionAnswerArrayList.get(i).getKeyword().split(",");
                keywords = Arrays.asList(word);
                String[] userKeywords = keyword.split(",");
                for (int j = 0; j < userKeywords.length; j++) {
                    if (keywords.contains(userKeywords[j])) {
                        if (countList.size() == 0) {
                            //countList.put(userKeywords[j], 1);
                            count[i]++;
                        }
                    }
                }
            }
    
            //index with largest match
            int largest = 0;
            //valu if the index
            int largestCount = count[largest];
    
            for (int i = 0; i < count.length; i++) {
                if (count[i] > largestCount)
                    largest = i;
            }
    
            arrayList.add(questionAnswerArrayList.get(largest));
    
            if (arrayList.size() > 0) {
                lvQuestionAnswer.invalidate();
                QuestionAnswerAdapter questionAnswerAdapter = new QuestionAnswerAdapter(arrayList, MainActivity.this, MainActivity.this, MainActivity.this);
                lvQuestionAnswer.setAdapter(questionAnswerAdapter);
                dialog.dismiss();
    
            } else {
                Toast.makeText(MainActivity.this, "No records found", Toast.LENGTH_SHORT).show();
            }
            return arrayList;
    
    
        }
    }