使用并发哈希映射在Java中实现Trie数据结构插入和压缩

使用并发哈希映射在Java中实现Trie数据结构插入和压缩,java,hashmap,trie,concurrenthashmap,Java,Hashmap,Trie,Concurrenthashmap,尝试实现Trie数据结构中元素的添加,然后尝试将其简化为Trie压缩机制。有一个特定的用例,由于这个用例,实现将永远作为一个无限循环运行,我们可以看看它,看看什么可能是最好的基本条件 import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class TrieNode { private String value; private ConcurrentHashMap<String

尝试实现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 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());
    }
}
import java.util.*;
导入java.util.concurrent.ConcurrentHashMap;
公共类三元组{
私有字符串值;
私隐儿童;
私有布尔字;
公共三节点(字符串值){
这个值=值;
this.children=新的ConcurrentHashMap();
}
公共静态无效sortbykey(ConcurrentHashMap映射){
ArrayList sortedKeys=新的ArrayList(map.keySet());
收集。分类(分类键);
}
公共静态ArrayList hashMapValues(ConcurrentHashMap映射){
ArrayList nodeList=新的ArrayList(map.values());
返回节点列表;
}
公共ArrayList getChildren(){
sortbykey(这是儿童);
返回hashMapValues(this.children);
}
公共ConcurrentHashMap getChildrenMappings()
{
把这个还给孩子们;
}
public void addChild(int numCharacters,字符串值)
{
//如果我们已经到达了根级别
if(value.length()==numCharacters)
{
this.isWord=true;
}
//如果该值仍有更多字符,则添加一个子项
其他的
{
三节点nextNode=null;
字符串nextCharacter=Character.toString(value.charAt(numCharacters));
if(this.children.get(nextCharacter)==null)
{
字符串nextPrefix=value.substring(0,numCharacters+1);
nextNode=新的三节点(nextPrefix);
this.children.put(nextCharacter,nextNode);
}
numCharacters++;
this.children.get(nextCharacter).addChild(numCharacters,value);
}
}
公共空间减少(){
for(ConcurrentHashMap.Entry子项:this.children.entrySet()){
child.getValue().reduce();
//去掉原始的子映射
this.children.remove(child.getKey());
//替换为新映射,如果我的孩子已与其他孩子组合,则该映射可能包含多个字符
字符串newMapping=child.getValue().getValue().substring(this.getValue().length());
this.children.put(newMapping,child.getValue());
}
if(this.children.size()==1){
for(ConcurrentHashMap.Entry子项:this.children.entrySet()){
//如果我只有一个孩子,如果我自己一个字也没有,就用他的孩子来代替
如果(!this.isWord()){
//去掉额外的子节点
this.children.remove(child.getKey());
//获取子节点值、单词状态和子节点
这个.setValue(child.getValue().getValue());
this.setIsWord(child.getValue().isWord());
对于(ConcurrentHashMap.Entry孙子:child.getValue().getChildrenMappings().entrySet()){
this.children.put(孙子.getKey(),孙子.getValue());
}
}
}
}
}
公共布尔值isWord()
{
返回此.isWord;
}
public void setIsWord(布尔值isWord){
this.isWord=isWord;
}
公共字符串getValue()
{
返回此.value;
}
公共void setValue(字符串newValue){
this.value=newValue;
}
公共静态void main(字符串[]args){
三节点tN=新三节点(“”);
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 childrenMappings=tN.getChildren().get(0.getChildren().get(0.getChildrenMappings());
对于(Map.Entry子项:childrenMappings.entrySet()){
System.out.println(children.getKey()+“=”+children.getValue().getChildrenMappings()+children.getValue().getValue()+“”+children.getValue().isWord);
}
System.out.println(tN.getChildren());
}
}

我修改了您的代码并添加了一个条件,即仅当新映射不等于当前子映射时,才删除当前子映射并添加新映射

我也不确定你最后想要打印什么。因此,我添加了我的打印报表

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());
        */
    }
}
import java.util.*;
导入java.util.concurrent.ConcurrentHashMap;
类三节点{
私有字符串值;
私隐儿童;
私有布尔字;
公共三节点(字符串值){
这个值=值;
this.children=新的ConcurrentHashMap();
}
公共静态无效sortbykey(ConcurrentHashMap映射){
ArrayList sortedKeys=新的ArrayList(map.keySet());
收集。分类(分类键);
}
公共静态ArrayList hashMapValues(ConcurrentHashMap映射){
ArrayList nodeList=新的ArrayList(map.values());
返回节点列表;
}
公共ArrayList getChildren(){
sortbykey(这是儿童);
返回hashMapValues(this.children);
}
公共ConcurrentHashMap getChildrenMappings()
{
把这个还给孩子们;
}
public void addChild(int numCharacters,字符串值)
{
//如果我们已经到达了根级别
如果(value.length()==numChar