import
java.io.*;
import
java.util.*;
class
PersistentTrie {
PersistentTrie[] children;
boolean
keyEnd =
false
;
PersistentTrie(
boolean
keyEnd) {
this
.keyEnd = keyEnd; }
PersistentTrie(PersistentTrie[] children,
boolean
keyEnd)
{
this
.children = children;
this
.keyEnd = keyEnd;
}
boolean
findKey(String key,
int
len,
PersistentTrie dummy)
{
if
(key.length() == len)
return
this
.keyEnd;
if
(
this
.children[key.charAt(len) -
'a'
] == dummy)
return
false
;
return
this
.children[key.charAt(len) -
'a'
].findKey(
key, len +
1
, dummy);
}
PersistentTrie insert(String key,
int
len)
{
if
(len == key.length()) {
return
new
PersistentTrie(
this
.children.clone(),
true
);
}
PersistentTrie[] new_version_PersistentTrie
=
this
.children.clone();
PersistentTrie tmpNode
= new_version_PersistentTrie[key.charAt(len)
-
'a'
];
new_version_PersistentTrie[key.charAt(len) -
'a'
]
= tmpNode.insert(key, len +
1
);
return
new
PersistentTrie(
new_version_PersistentTrie,
false
);
}
}
class
GFG {
static
final
int
sz =
26
;
static
PersistentTrie dummy;
static
void
init()
{
dummy =
new
PersistentTrie(
false
);
PersistentTrie[] children =
new
PersistentTrie[sz];
for
(
int
i =
0
; i < sz; i++)
children[i] = dummy;
dummy.children = children;
}
static
void
printAllKeysInTrie(PersistentTrie root,
String s)
{
int
flag =
0
;
for
(
int
i =
0
; i < sz; i++) {
if
(root.children[i] != dummy) {
flag =
1
;
printAllKeysInTrie(root.children[i],
s + ((
char
)(
'a'
+ i)));
}
if
(root.children[i].keyEnd)
System.out.println(s + (
char
)(
'a'
+ i));
}
}
public
static
void
main(String[] args)
{
init();
List<String> keys = Arrays.asList(
new
String[] {
"goku"
,
"gohan"
,
"goten"
,
"gogeta"
});
PersistentTrie[] root
=
new
PersistentTrie[keys.size() +
1
];
root[
0
] = dummy;
for
(
int
i =
1
; i <= keys.size(); i++) {
root[i]
= root[i -
1
].insert(keys.get(i -
1
),
0
);
}
int
idx =
3
;
System.out.println(
"All keys in trie "
+
"after version - "
+ idx);
String key =
""
;
printAllKeysInTrie(root[
3
], key);
String queryString =
"goku"
;
int
l =
2
, r =
3
;
System.out.println(
"range : "
+
"["
+ l +
", "
+ r +
"]"
);
if
(root[r].findKey(queryString,
0
, dummy)
&& !root[l -
1
].findKey(queryString,
0
, dummy))
System.out.println(
queryString +
" - exists in above range"
);
else
System.out.println(queryString
+
" - does not exist in "
+
"above range"
);
queryString =
"goten"
;
l =
2
;
r =
4
;
System.out.println(
"range : "
+
"["
+ l +
", "
+ r +
"]"
);
if
(root[r].findKey(queryString,
0
, dummy)
&& !root[l -
1
].findKey(queryString,
0
, dummy))
System.out.println(
queryString +
" - exists in above range"
);
else
System.out.println(
queryString
+
" - does not exist in above range"
);
}
}