Во-первых, я думаю, что у вас есть небольшая, но существенная ошибка в вашем коде, отслеживающая использование каждого TrieNode
. Если вы изучите значение counter
для TrieNode, представляющего b
в cab
, вы увидите, что это 1, когда должно быть 2, для:
cab
cabin
Вам необходимо записать использование узлов, представляющих последний символ в слове, путем обновления кода в конце вашего метода insert
следующим образом:
p.counter++;
p.isEnd = true;
С этим обновлением вы можете получить наиболее частые префиксы (возможно, быть более чем одним) с чем-то вроде этого:
public static int findMostFrequentPrefix(TrieNode current, int n, int max, char[] curr, int depth,
List<Prefix> result)
{
if (n == 0)
{
if (current.counter >= max)
{
if (current.counter > max)
{
result.clear();
max = current.counter;
}
result.add(new Prefix(max, String.valueOf(curr)));
}
return max;
}
for (TrieNode child : current.children)
{
if (child != null)
{
curr[depth] = child.value;
max = Math.max(max, findMostFrequentPrefix(child, n - 1, max, curr, depth + 1, result));
}
}
return max;
}
Использование небольшого вспомогательного класса PrefIx
:
static class Prefix
{
int freq;
String value;
public Prefix(int freq, String value)
{
this.freq = freq;
this.value = value;
}
}
Тест:
int len = 3;
List<Prefix> result = new ArrayList<>();
int max = findMostFrequentPrefix(t.getRoot(), len, 0, new char[len], 0, result);
System.out.format("max frequency: %d%n", max);
for(Prefix p : result)
System.out.println(p.value);
Вывод:
max frequency: 2
cab
tes
Вот попытка реализации вашего второго метода, findMostFrequentPrefixGreaterEqual
. Вам нужно будет проверить и подтвердить, что он возвращает ожидаемые результаты во всех случаях:
public static int findMostFrequentPrefixGreaterEqual(TrieNode current, int n, int max, char[] curr, int depth,
List<Prefix> result)
{
if (n <= 0)
{
if (current.counter >= max)
{
result.clear();
max = current.counter;
result.add(new Prefix(max, String.valueOf(curr, 0, depth)));
}
else
{
return max;
}
}
for (TrieNode child : current.children)
{
if (child != null)
{
curr[depth] = child.value;
max = Math.max(max, findMostFrequentPrefixGreaterEqual(child, n - 1, max, curr, depth + 1, result));
}
}
return max;
}
Test:
t.insert("test");
t.insert("testi");
t.insert("testif");
t.insert("testify");
int len = 2;
int maxLen = 7;
List<Prefix> result = new ArrayList<>();
int max = findMostFrequentPrefixGreaterEqual(t.getRoot(), len, 0, new char[maxLen], 0, result);
System.out.format("max frequency: %d%n", max);
for(Prefix p : result)
System.out.println(p.value);
Обратите внимание, что теперь мы должны знать максимальную длину любых слов в Trie
, чтобы выделить достаточно места в массиве char
.
Вывод:
max frequency: 4
test