英文:
Trie Data Structure Insertion and Compression implementation in Java using Concurrent Hash Map
问题
以下是您提供的代码的翻译部分:
尝试实现 Trie 数据结构添加元素,然后尝试通过 Trie 压缩机制来减少它。由于特定的用例,实现进入无限循环,可能需要查看一下,看看什么是可能的最佳基本条件。
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class TrieNode {
private String value;
private ConcurrentHashMap<String, TrieNode> children;
private boolean isWord;
public TrieNode(String value){
this.value = value;
this.children = new ConcurrentHashMap<String, TrieNode>();
}
public static void sortbykey(ConcurrentHashMap<String, TrieNode> map) {
ArrayList<String> sortedKeys = new ArrayList<String>(map.keySet());
Collections.sort(sortedKeys);
}
public static ArrayList<TrieNode> hashMapValues (ConcurrentHashMap<String, TrieNode> map) {
ArrayList<TrieNode> nodeList = new ArrayList<TrieNode>(map.values());
return nodeList;
}
public ArrayList<TrieNode> getChildren() {
sortbykey(this.children);
return hashMapValues(this.children);
}
public ConcurrentHashMap<String, TrieNode> getChildrenMappings()
{
return this.children;
}
public void addChild(int numCharacters, String value)
{
// 如果已经到达根级别
if(value.length() == numCharacters)
{
this.isWord = true;
}
// 如果值仍有更多字符,则添加一个子节点
else
{
TrieNode nextNode = null;
String nextCharacter = Character.toString(value.charAt(numCharacters));
if(this.children.get(nextCharacter) == null)
{
String nextPrefix = value.substring(0, numCharacters + 1);
nextNode = new TrieNode(nextPrefix);
this.children.put(nextCharacter, nextNode);
}
numCharacters++;
this.children.get(nextCharacter).addChild(numCharacters, value);
}
}
public void reduce(){
for(ConcurrentHashMap.Entry<String, TrieNode> child : this.children.entrySet()){
child.getValue().reduce();
// 清除原始子节点映射
this.children.remove(child.getKey());
// 用可能包含多个字符的新映射替换,如果我的子节点与其他子节点合并
String newMapping = child.getValue().getValue().substring(this.getValue().length());
this.children.put(newMapping, child.getValue());
}
if(this.children.size() == 1){
for(ConcurrentHashMap.Entry<String, TrieNode> child : this.children.entrySet()){
// 如果我只有一个子节点,如果我自己不是一个单词,就用他的子节点替换我
if(!this.isWord()){
// 清除额外的子节点
this.children.remove(child.getKey());
// 获取子节点的值、单词状态和子节点
this.setValue(child.getValue().getValue());
this.setIsWord(child.getValue().isWord());
for(ConcurrentHashMap.Entry<String, TrieNode> grandchild : child.getValue().getChildrenMappings().entrySet()){
this.children.put(grandchild.getKey(), grandchild.getValue());
}
}
}
}
}
public boolean isWord()
{
return this.isWord;
}
public void setIsWord(boolean isWord){
this.isWord = isWord;
}
public String getValue()
{
return this.value;
}
public void setValue(String newValue){
this.value = newValue;
}
public static void main(String[] args){
TrieNode tN = new TrieNode("");
tN.addChild(0, "www.corriere.it/27esimaora/laquila");
tN.addChild(0, "www.corriere.it/27esimaora");
tN.addChild(0, "www.corriere.it/cronache/sesso-e-amore/");
tN.addChild(0, "www.corriere.it/foto-gallery/cronache/sesso-e-amore/");
tN.reduce();
ConcurrentHashMap<String, TrieNode> childrenMappings = tN.getChildren().get(0).getChildren().get(0).getChildren().get(0).getChildrenMappings();
for(Map.Entry<String, TrieNode> children : childrenMappings.entrySet()){
System.out.println(children.getKey() + " = " + children.getValue().getChildrenMappings() + children.getValue().getValue() + " " + children.getValue().isWord);
}
System.out.println(tN.getChildren());
}
}
请注意,翻译是基于您提供的代码进行的,保留了代码结构和注释。如果您对翻译有任何疑问,请随时提问。
英文:
Trying to implement Trie data structure addition of elements and then trying to to reduce it as trie compression mechanism. There is a specific use case due to which the implementation is running forever as an infinite loop, may we have a look at it and see what could be the best possible base condition for that.
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class TrieNode {
private String value;
private ConcurrentHashMap<String, TrieNode> children;
private boolean isWord;
public TrieNode(String value){
this.value = value;
this.children = new ConcurrentHashMap<String, TrieNode>();
}
public static void sortbykey(ConcurrentHashMap<String, TrieNode> map) {
ArrayList<String> sortedKeys = new ArrayList<String>(map.keySet());
Collections.sort(sortedKeys);
}
public static ArrayList<TrieNode> hashMapValues (ConcurrentHashMap<String, TrieNode> map) {
ArrayList<TrieNode> nodeList = new ArrayList<TrieNode>(map.values());
return nodeList;
}
public ArrayList<TrieNode> getChildren() {
sortbykey(this.children);
return hashMapValues(this.children);
}
public ConcurrentHashMap<String, TrieNode> getChildrenMappings()
{
return this.children;
}
public void addChild(int numCharacters,String value)
{
//If we have arrived at the root level
if(value.length() == numCharacters)
{
this.isWord = true;
}
//If the value still has more characters then add a child
else
{
TrieNode nextNode = null;
String nextCharacter = Character.toString(value.charAt(numCharacters));
if(this.children.get(nextCharacter)==null)
{
String nextPrefix = value.substring(0,numCharacters+1);
nextNode = new TrieNode(nextPrefix);
this.children.put(nextCharacter, nextNode);
}
numCharacters++;
this.children.get(nextCharacter).addChild(numCharacters,value);
}
}
public void reduce(){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
child.getValue().reduce();
//Get rid of original child mapping
this.children.remove(child.getKey());
//Replace with a new mapping which may include multiple characters if my child has been combined with other children
String newMapping = child.getValue().getValue().substring(this.getValue().length());
this.children.put(newMapping, child.getValue());
}
if(this.children.size() == 1){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
//If I only have a single child, replace it with his children if I'm not also a word on my own
if(!this.isWord()){
//Get rid of the extra child node
this.children.remove(child.getKey());
//Take the child nodes value, word status and children
this.setValue(child.getValue().getValue());
this.setIsWord(child.getValue().isWord());
for(ConcurrentHashMap.Entry<String,TrieNode> grandchild : child.getValue().getChildrenMappings().entrySet()){
this.children.put(grandchild.getKey(),grandchild.getValue());
}
}
}
}
}
public boolean isWord()
{
return this.isWord;
}
public void setIsWord(boolean isWord){
this.isWord = isWord;
}
public String getValue()
{
return this.value;
}
public void setValue(String newValue){
this.value = newValue;
}
public static void main(String[] args){
TrieNode tN = new TrieNode("");
tN.addChild(0, "www.corriere.it/27esimaora/laquila");
tN.addChild(0, "www.corriere.it/27esimaora");
tN.addChild(0, "www.corriere.it/cronache/sesso-e-amore/");
tN.addChild(0, "www.corriere.it/foto-gallery/cronache/sesso-e-amore/");
tN.reduce();
ConcurrentHashMap<String, TrieNode> childrenMappings = tN.getChildren().get(0).getChildren().get(0).getChildren().get(0).getChildrenMappings();
for(Map.Entry<String, TrieNode> children : childrenMappings.entrySet()){
System.out.println(children.getKey() + " = " + children.getValue().getChildrenMappings() + children.getValue().getValue() + " "+ children.getValue().isWord);
}
System.out.println(tN.getChildren());
}
}
答案1
得分: 0
我修改了你的代码,并添加了一个条件:只有当新映射不等于当前子节点时,才会删除当前子节点并添加新的映射。
我还不确定你最后想要打印什么内容。因此我添加了我的打印语句。
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
class TrieNode {
private String value;
private ConcurrentHashMap<String, TrieNode> children;
private boolean isWord;
public TrieNode(String value){
this.value = value;
this.children = new ConcurrentHashMap<String, TrieNode>();
}
public static void sortbykey(ConcurrentHashMap<String, TrieNode> map) {
ArrayList<String> sortedKeys = new ArrayList<String>(map.keySet());
Collections.sort(sortedKeys);
}
public static ArrayList<TrieNode> hashMapValues (ConcurrentHashMap<String, TrieNode> map) {
ArrayList<TrieNode> nodeList = new ArrayList<TrieNode>(map.values());
return nodeList;
}
public ArrayList<TrieNode> getChildren() {
sortbykey(this.children);
return hashMapValues(this.children);
}
public ConcurrentHashMap<String, TrieNode> getChildrenMappings()
{
return this.children;
}
public void addChild(int numCharacters,String value)
{
//If we have arrived at the root level
if(value.length() == numCharacters)
{
this.isWord = true;
}
//If the value still has more characters then add a child
else
{
TrieNode nextNode = null;
String nextCharacter = Character.toString(value.charAt(numCharacters));
if(this.children.get(nextCharacter)==null)
{
String nextPrefix = value.substring(0,numCharacters+1);
nextNode = new TrieNode(nextPrefix);
this.children.put(nextCharacter, nextNode);
}
numCharacters++;
this.children.get(nextCharacter).addChild(numCharacters,value);
}
}
public void reduce(){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
child.getValue().reduce();
//Get rid of original child mapping
//this.children.remove(child.getKey());
//Replace with a new mapping which may include multiple characters if my child has been combined with other children
String newMapping = child.getValue().getValue().substring(this.getValue().length());
// only if the new mapping is not equal.
if (!newMapping.equals(child.getKey())) {
this.children.remove(child.getKey());
this.children.put(newMapping, child.getValue());
}
//this.children.put(newMapping, child.getValue());
}
if(this.children.size() == 1){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
//If I only have a single child, replace it with his children if I'm not also a word on my own
if(!this.isWord()){
//Get rid of the extra child node
this.children.remove(child.getKey());
//Take the child nodes value, word status and children
this.setValue(child.getValue().getValue());
this.setIsWord(child.getValue().isWord());
for(ConcurrentHashMap.Entry<String,TrieNode> grandchild : child.getValue().getChildrenMappings().entrySet()){
this.children.put(grandchild.getKey(),grandchild.getValue());
}
}
}
}
}
public boolean isWord()
{
return this.isWord;
}
public void setIsWord(boolean isWord){
this.isWord = isWord;
}
public String getValue()
{
return this.value;
}
public void setValue(String newValue){
this.value = newValue;
}
public static void main(String[] args){
TrieNode tN = new TrieNode("");
tN.addChild(0, "www.corriere.it/27esimaora/laquila");
tN.addChild(0, "www.corriere.it/27esimaora");
tN.addChild(0, "www.corriere.it/cronache/sesso-e-amore/");
tN.addChild(0, "www.corriere.it/foto-gallery/cronache/sesso-e-amore/");
tN.reduce();
System.out.println(" root " + tN.getValue());
System.out.println(" first level child 1 " + tN.getChildren().get(0).getValue());
System.out.println(" first level child 2 " + tN.getChildren().get(1).getValue());
System.out.println(" second level child 1 " + tN.getChildren().get(1).getChildren().get(0).getValue());
System.out.println(" first level child 3 " + tN.getChildren().get(2).getValue());
/*ConcurrentHashMap<String, TrieNode> childrenMappings = tN.getChildren().get(0).getChildren().get(0).getChildren().get(0).getChildrenMappings();
for(Map.Entry<String, TrieNode> children : childrenMappings.entrySet()){
System.out.println(children.getKey() + " = " + children.getValue().getChildrenMappings() + children.getValue().getValue() + " "+ children.getValue().isWord);
}
System.out.println(tN.getChildren());
*/
}
}
英文:
I modified your code and added a condition that only if the new mapping not equal to the current child, then only remove the current child and add the new mapping.
I was also not sure what you were trying to print in the end. Therefore I have added my print statements.
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
class TrieNode {
private String value;
private ConcurrentHashMap<String, TrieNode> children;
private boolean isWord;
public TrieNode(String value){
this.value = value;
this.children = new ConcurrentHashMap<String, TrieNode>();
}
public static void sortbykey(ConcurrentHashMap<String, TrieNode> map) {
ArrayList<String> sortedKeys = new ArrayList<String>(map.keySet());
Collections.sort(sortedKeys);
}
public static ArrayList<TrieNode> hashMapValues (ConcurrentHashMap<String, TrieNode> map) {
ArrayList<TrieNode> nodeList = new ArrayList<TrieNode>(map.values());
return nodeList;
}
public ArrayList<TrieNode> getChildren() {
sortbykey(this.children);
return hashMapValues(this.children);
}
public ConcurrentHashMap<String, TrieNode> getChildrenMappings()
{
return this.children;
}
public void addChild(int numCharacters,String value)
{
//If we have arrived at the root level
if(value.length() == numCharacters)
{
this.isWord = true;
}
//If the value still has more characters then add a child
else
{
TrieNode nextNode = null;
String nextCharacter = Character.toString(value.charAt(numCharacters));
if(this.children.get(nextCharacter)==null)
{
String nextPrefix = value.substring(0,numCharacters+1);
nextNode = new TrieNode(nextPrefix);
this.children.put(nextCharacter, nextNode);
}
numCharacters++;
this.children.get(nextCharacter).addChild(numCharacters,value);
}
}
public void reduce(){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
child.getValue().reduce();
//Get rid of original child mapping
//this.children.remove(child.getKey());
//Replace with a new mapping which may include multiple characters if my child has been combined with other children
String newMapping = child.getValue().getValue().substring(this.getValue().length());
// only if the new mapping is not equal.
if (!newMapping.equals(child.getKey())) {
this.children.remove(child.getKey());
this.children.put(newMapping, child.getValue());
}
//this.children.put(newMapping, child.getValue());
}
if(this.children.size() == 1){
for(ConcurrentHashMap.Entry<String,TrieNode> child : this.children.entrySet()){
//If I only have a single child, replace it with his children if I'm not also a word on my own
if(!this.isWord()){
//Get rid of the extra child node
this.children.remove(child.getKey());
//Take the child nodes value, word status and children
this.setValue(child.getValue().getValue());
this.setIsWord(child.getValue().isWord());
for(ConcurrentHashMap.Entry<String,TrieNode> grandchild : child.getValue().getChildrenMappings().entrySet()){
this.children.put(grandchild.getKey(),grandchild.getValue());
}
}
}
}
}
public boolean isWord()
{
return this.isWord;
}
public void setIsWord(boolean isWord){
this.isWord = isWord;
}
public String getValue()
{
return this.value;
}
public void setValue(String newValue){
this.value = newValue;
}
public static void main(String[] args){
TrieNode tN = new TrieNode("");
tN.addChild(0, "www.corriere.it/27esimaora/laquila");
tN.addChild(0, "www.corriere.it/27esimaora");
tN.addChild(0, "www.corriere.it/cronache/sesso-e-amore/");
tN.addChild(0, "www.corriere.it/foto-gallery/cronache/sesso-e-amore/");
tN.reduce();
System.out.println(" root " + tN.getValue());
System.out.println(" first level child 1 " + tN.getChildren().get(0).getValue());
System.out.println(" first leve child 2 " + tN.getChildren().get(1).getValue());
System.out.println(" second level child 1 " + tN.getChildren().get(1).getChildren().get(0).getValue());
System.out.println(" first level child 3 " + tN.getChildren().get(2).getValue());
/*ConcurrentHashMap<String, TrieNode> childrenMappings = tN.getChildren().get(0).getChildren().get(0).getChildren().get(0).getChildrenMappings();
for(Map.Entry<String, TrieNode> children : childrenMappings.entrySet()){
System.out.println(children.getKey() + " = " + children.getValue().getChildrenMappings() + children.getValue().getValue() + " "+ children.getValue().isWord);
}
System.out.println(tN.getChildren());
*/
}
}
专注分享java语言的经验与见解,让所有开发者获益!
评论