存储器不足异常在C#的[关闭](Out of Memory Exception In C# [clo

2019-09-30 04:18发布

我试图构建一个后缀特里结构,并且由于严格的要求,必须在内存中进行索引。

编辑:这个问题是不是树本身,但实际上我读文件的方式。

Answer 1:

如果你传递整个文本文件作为一个string ,你可以很容易碰到内存不足的异常与你的第一个循环!

// imagine if s.Length was 100k or so
for (int i = 0; i < s.Length; i++)
{
    AddString(s.Substring(i, s.Length-i));
}

当读取文件,构建线索,你需要拆分每一行,并可能正常化的特点:

string line;
while (null != (line = reader.ReadLine()))
{
    string[] parts = line.Split(' ', ',', '.', '!', '\t', '?'); // naive
    foreach (string part in parts)
    {
        if (part.Length > 0)
        {
            // make each string uppercase so as to avoid Hello and hello being
            // two trie entries
            trie.AddSuffix(part.ToUpperInvariant());
        }
    }
}

例如(从输出dir /bc:\windows ):

A
 D
  D
   I
    N
     S
  E
   D
 P
  P
   C
    O
     M
      P
       A
        T
   P
    A
     T
      C
       H
...

为了适当地处理更大的文件,更紧凑的线索结构是可取的。 我只想有存储在一个单独的字典非共享后缀:

// If you add a character, but there is no entry in m_children
// just park the tail end of it here
Dictionary<char, string> m_tails;

然后,您可以移动每个字符的逻辑在AddString的的SuffixNode

public void AddString(string s)
{
    if (s.Length == 0) return;

    char c = s[0];
    if (m_children.ContainsKey(c))
    {
        if (s.Length > 1) m_children[c].AddString(s.Substring(1));
    }
    else if (m_tails.ContainsKey(c))
    {
        SuffixNode node = new SuffixNode();
        node.AddString(m_tails[c]);
        if (s.Length > 1) node.AddString(s.Substring(1));

        m_children.Add(c, node);
        m_tails.Remove(c);
    }
    else
    {
        m_tails.Add(c, s.Length > 1 ? s.Substring(1) : "");
    }
}

现在你有线索,这将大大减少儿童数量的更加紧凑版本SuffixNode对于任何给定的语料库创建秒。 返回到dir /bc:\windows例子,我们可以看到在节点实用的还原:

A
 P
  P
   COMPAT
   PATCH
  I
 T
  I
   O
    N
     S
...

此时你的线索有更高效的表现。 留给你的决定如何,以确保查找准确处理终端节点表示。



文章来源: Out of Memory Exception In C# [closed]