Я предлагаю вам 2 способа сделать это.
Первый способ: с одним деревом.
Можно хранить все необходимое в одном дереве.Ваш класс клиентов в порядке, и здесь возможна реализация RadixNode
.
Я считаю, что не может быть двух клиентов с одинаковым именем или с одним и тем же номером телефона.Если это не так (например, возможность иметь людей с одинаковыми именами и номерами телефонов), скажите мне в комментарии, которые я отредактирую.
Важно понимать, что если вы хотите иметь дваразличные способы поиска клиента, и вы используете один Trie, каждый клиент появится дважды в вашем Trie.Один раз в конце пути, соответствующего его имени, и один раз после окончания пути, соответствующего его номеру телефона.
import java.util.HashMap;
import java.util.Map;
class RadixNode {
private Map<Character, RadixNode> children;
private Customer customer;
public RadixNode(){
this.children = new Map<Character, RadixNode>();
this.Customer = NULL;
}
Map<Character, RadixNode> getChildren() {
return children;
}
boolean hasCustomer() {
return this.customer != NULL;
}
Customer getCustomer() {
return customer;
}
void setCustomer(Customer customer) {
this.customer = customer;
}
}
Как видите, существует только одна карта, хранящая дочерние элементы узла.Это потому, что мы можем видеть номер телефона в виде цепочки цифр, поэтому этот файл будет хранить всех клиентов ... дважды.Один раз для имени, один раз для номера телефона.
Теперь давайте посмотрим функцию вставки.Вашему трию понадобится рут, и давайте назовем его root
.
public void insert(RadixNode root, Customer customer){
insert_with_name(root, customer, 0);
insert_with_phone_nb(root, customer, 0);
}
public void insert_with_name(RadixNode node, Customer customer, int idx){
if (idx == customer.getName().length()){
node.setCustomer(customer);
} else {
Character current_char = customer.getName().chatAt(idx);
if (! node.getChlidren().containsKey(current_char){
RadixNode new_child = new RadixNode();
node.getChildren().put(current_char, new_child);
}
insert_with_name(node.getChildren().get(current_char), customer, idx+1);
}
}
Метод insert_with_phone_nb()
аналогичен.Это будет работать до тех пор, пока у людей есть уникальные имена, уникальные номера телефонов и если чье-то имя не может быть чьим-либо номером.
Как видите, метод рекурсивный.Я советую вам рекурсивно строить свою структуру трия (и, как правило, все, что основано на древовидных структурах), так как это упрощает и упрощает очистку кода.
Функция поиска является почти копией-вставкой функции вставки:
public void search_by_name(RadixNode node, String name, int idx){
// returns NULL if there is no user going by that name
if (idx == name.length()){
return node.getCustomer();
} else {
Character current_char = name.chatAt(idx);
if (! node.getChlidren().containsKey(current_char){
return NULL;
} else {
return search_by_name(node.getChildren().get(current_char), name, idx+1);
}
}
}
Второй способ: с 2 попытками
Принцип тот же, все, что вам нужно сделать, это повторно использовать приведенный выше код, но сохранить два отдельных узла root
, каждый из которыхони построят три (один для имен, один для телефонных номеров).Единственным отличием будет функция insert
(так как она будет вызывать insert_with_name
и insert_with_phone_nb
с двумя разными корнями) и функция поиска, которая также должна будет искать в нужном дереве.
public void insert(RadixNode root_name_trie, RadixNode root_phone_trie, Customer customer){
insert_with_name(root_name_trie, customer, 0);
insert_with_phone_nb(root_phone_trie, customer, 0);
}
Редактировать : После уточнения комментариев могут быть клиенты с одинаковыми именами, вот альтернативная реализация, позволяющая RadixNode
содержать ссылки на несколько Customer
.
Заменить *Атрибут 1038 * в RadixNode
, например, Vector<Customer>
.Конечно, методы должны быть изменены соответствующим образом, и поиск по имени вернет вам вектор покупателей (возможно, пустой), поскольку этот поиск может привести к нескольким результатам.
В вашем случае, я быперейти на одну Trie, содержащую векторы клиентов.Таким образом, вы можете иметь как поиск по имени, так и по телефону (приведите число как String
), а также одну структуру данных для обслуживания.