从列表中提取具有给定字符串最大匹配项的项目

时间:2018-07-12 06:47:12

标签: java android sqlite arraylist

我的应用程序中有2个数组列表。第一个arraylist是Object类型,其中包含问题列表。现在,此问题列表具有一个名为“关键字” 的字段。这是一个字符串,但可以包含逗号分隔的关键字。

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

例如。用户在搜索文本字段中输入了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 个答案:

答案 0 :(得分:1)

我把它留给您作为练习,以弄清楚该解决方案的工作原理,但是随时问您想要的任何问题。


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());
    }
}

答案 1 :(得分:0)

经过几天的尝试,我认为我找到了解决问题的方法。下面是我现在使用的代码。

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;


    }
}