C#实现前缀树时节点属性修改不生效,无需指针如何解决?
问题根源
你遇到的问题核心是**Node被定义为struct(值类型)**而非class(引用类型)。在C#中,值类型变量赋值时会创建完整副本,所以你执行tmp.end = true时,只是修改了栈上的临时副本,字典里存储的实际Node实例完全不受影响——这和C++里指针/引用操作同一块内存的逻辑本质不同。
解决方法
把Node从struct改成class,所有操作就会基于引用执行,修改tmp的属性会直接作用于字典中存储的实际节点。
修改后的完整代码
public class Node { public char val; public bool end; public Dictionary<char, Node> children; public Node(char val) { this.val = val; end = false; children = new Dictionary<char, Node>(); } } public class Solution { public string ReplaceWords(IList<string> dictionary, string sentence) { Node head = new Node('a'); foreach (var word in dictionary) { Node tmp = head; for (int i = 0; i < word.Length; i++) { char charact = word[i]; if (!tmp.children.ContainsKey(charact)) { Node newNode = new Node(charact); tmp.children.Add(charact, newNode); } tmp = tmp.children[charact]; } // 现在修改的是引用指向的实际节点属性,会同步到前缀树中 tmp.end = true; } StringBuilder res = new StringBuilder(); string[] words = sentence.Split(' '); for (int i = 0; i < words.Length; i++) { string word = words[i]; Node travel = head; StringBuilder tmpStr = new StringBuilder(); bool foundRoot = false; foreach (var charact in word) { if (travel.children.ContainsKey(charact)) { tmpStr.Append(charact); travel = travel.children[charact]; if (travel.end) { foundRoot = true; break; } } else { break; } } res.Append(foundRoot ? tmpStr.ToString() : word); if (i != words.Length - 1) { res.Append(' '); } } return res.ToString(); } }
额外优化说明
- 用
StringBuilder替代字符串拼接,避免频繁创建字符串对象,提升大数据量场景下的性能。 - 调整前缀查找逻辑,用
foundRoot标记更清晰,避免提前覆盖临时字符串。
内容的提问来源于stack exchange,提问作者Masterdemon123
相关产品推荐
相关产品推荐

