У меня есть hashMap, который содержит «термин» как ключ и «список документов» как значения.
Например:
KEY::VALUE
afternoon::Doc2
activities::Doc1, Doc2, Doc3
admissions::Doc1, Doc2, Doc4, Doc5
alternate::Doc5
Мне нужно передать логические выражения терминам и получить соответствующие документы. Это выражение будет передано через другую строковую переменную.
Например:
(afternoon AND activities) OR alternate => Doc2, Doc5
(afternoon AND activities) OR (admissions AND alternate) => Doc2, Doc5
activities AND NOT afternoon = > Doc1, Doc3
Есть ли в Java какие-нибудь функции для таких операций? Любые внешние библиотеки тоже будут работать. Фрагмент кода мне очень поможет, так как мое задание должно быть завтра, и это последний шаг моего решения.
Если операции являются фиксированными логическими операциями, вы можете использовать Enums, чтобы сопоставить их с соответствующей логикой.
Выражения могут меняться при каждом запуске. Я только что привел здесь пример, чтобы объяснить желаемый результат.
Если выражения представлены в виде свободного текста, то я думаю, что ваше задание может быть в опасности :( Решение SOme: вы можете использовать некоторую базу данных в памяти (например, H2, sqlite, ...), вы можете использовать Antlr (это сложно сделать относительно быстро) или вы можете написать какой-нибудь простой синтаксический анализатор / оценщик самостоятельно только для AND, OR, NOT.
Это последний шаг. Так что, если это работает только для AND, это тоже нормально. Я могу сдать и получить оценки за остальную часть моей работы. Но без этой последней части мое задание будет неполным.




Просмотрите значения карты и найдите все ключи, соответствующие этому значению, чтобы создать Map<String, Set<String>>, где, например, ключ. Doc1 и значение, например. мероприятия, входные билеты. Представьте каждое выражение как Predicate<Set<String>>, который просматривает набор терминов и решает, соответствует ли оно выражению.
Сейчас,
map.entrySet().stream().filter(e -> expression.test(e.getValue())).map(Entry::getKey).collect(Collectors.toList());
возвращает список документов, соответствующих выражению термина
Я думаю, что использование предикатов здесь - самая простая часть. Ключевым моментом в задаче является преобразование произвольного текста в цепочку предикатов.
@zolv Я предполагаю, что проблема уже решена, например. у него длинный список предикатов, и он может жестко их запрограммировать.
На мой взгляд, вы хотите добиться объединения и пересечения элементов списка для логических выражений. Вы можете написать собственный метод, например
public Set<Doc> andOp(Set<Doc> list1, Set<String> Doc) {
if (list1.isEmpty() || list2.isEmpty())
return new HashSet<>();
Set<Doc> result = new HashSet<>();
Iterator<Doc> it = list1.iterator();
while( it.hasNext()) {
Doc Doc1 = it.next();
if (list2.contains(Doc))
result.add(Doc);
}
return result;
}
public Set<Doc> orOp(Set<Doc> list1, Set<Doc> list2) {
if (list1.isEmpty()) return list2;
if (list2.isEmpty()) return list1;
Set<Doc> result = new HashSet<>();
result.addAll(list1);
result.addAll(list2);
return result;
}
Таким образом, результирующее выражение для (полдень И деятельность) ИЛИ (поступление И допуск) будет выглядеть следующим образом:
Set<Doc> doc1 = andOp(map.get("activities"), map.get("afternoon"));
Set<Doc> doc2 = andOp(map.get("admissions"), map.get("admissions"));
doc1 = orOp(doc1, doc2);
Операции фиксированы / статичны? Или это просто примеры, взятые из какой-то текстовой панели?