【问题标题】:How to avoid out of memory using trie by C#如何通过 C# 使用 trie 来避免内存不足
【发布时间】:2019-11-09 08:04:00
【问题描述】:

如何用更少的内存将数十亿的数据写入到 trie 中

我想从新闻中提取一些信息,例如公司名称,所以我将数十亿个公司名称写入 trie,但是它需要大量内存并抛出内存异常,我不知道如何解决它,所以任何人可以帮忙,提前谢谢。

    public class Node
    {
        public char Value { get; set; }

        public List<Node> Children { get; set; }

        public int Depth { get; set; }

        public string Code { get; set; }

        public bool Terminal { get; set; }

        public Node(char value, int depth)
        {
            Value = value;
            Depth = depth;
            Children = new List<Node>();
        }


        public Node FindChildNode(char c)
        {
            foreach (var child in Children)
                if (child.Value == c)
                    return child;

            return null;
        }


    }

    public class Trie
    {
        private  Node _root;

        public Trie()
        {
            _root = new Node('^',0);
        }

        public Node Prefix(string s)
        {
            var currentNode = _root;
            var result = currentNode;

            foreach (var c in s)
            {
                currentNode = currentNode.FindChildNode(c);
                if (currentNode == null)
                    break;
                result = currentNode;
            }

            return result;
        }



        public void Insert(string randomLength,string code)
        {
            var commonPrefix = Prefix(randomLength);
            var current = commonPrefix;

            for (var i = current.Depth; i < s.Length; i++)
            {
               var newNode = new Node(s[i], current.Depth + 1);
                if (i+1==s.Length)
                {
                    newNode.Terminal = true;
                    newNode.Code = code;
                }
                current.Children.Add(newNode);
                current = newNode;
            }

        }



    }

Trie t=new Trie();
t.Insert("C","ABCG00DFD"); 上面的语句运行了1000000000个循环,“C”可以用不同长度的不同字符串替换,随着循环的增加,它会抛出内存异常,那么如何避免或改变它呢?

【问题讨论】:

  • 您的代码无法编译 - The name 's' does not exist in the current context.
  • 您是在构建和运行 64 位还是 32 位?如果是 32 位,那就是你的问题。
  • “如何用更少的内存将数十亿数据写入 trie” - 呃,什么?要插入数十亿个数据,您需要 X * 十亿字节,其中 X 取决于数据类型。您可以找到一个散列和散列函数来巧妙地实际呈现大量数据,但如果您想更改单个字节/位 - 您仍然需要全部字节。至于OutOfMemoryException 你试图在某处分配太大的数组。
  • 你为什么还要在内存中存储这么多项目?
  • 这是一个最小的Trie 定义:public class Trie&lt;T&gt; : List&lt;Trie&lt;T&gt;&gt; { public T Value { get; set; } public bool Terminal { get; set; } }

标签: c# out-of-memory trie


【解决方案1】:

试试这个Trie,看看你能不能让它满足你的需要:

public class Trie : Dictionary<char, Trie>
{
    public void Add(string value)
    {
        var c = String.IsNullOrEmpty(value) ? '\0' : value[0];
        if (!this.ContainsKey(c))
        {
            this[c] = new Trie();
        }
        if (c != '\0')
        {
            this[c].Add(value.Substring(1));
        }
    }
}

【讨论】:

  • 首先,谢谢,没用。其实字典还是跟数组有关系的,所以随着数据的增加,内存也越来越大。
  • @Jack - 你永远不会得到一个内存效率非常高的 trie。每个char 至少使用两个字节,每个对对象的引用使用4 个字节。它不是一种内存高效的数据结构。但对于确定某物是否为成员的速度而言,它是首屈一指的。
猜你喜欢
  • 2015-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
相关资源
最近更新 更多