我正在研究一種方法,如果存在具有指定名稱的節點,則該方法給出下一個可用節點名稱。但想法是該方法從最大值給出下一個,例如:

如果我添加一個名為“test”的新節點,該方法應該回傳“test6”而不是“test2”。包含數字作為名稱的節點也會發生同樣的情況:

如果我添加一個名為“20”的新節點,下一個可用名稱應該是“31”。
所以這個想法是從序列中獲取“最大值”并添加一個。這個樹節點很容易包含 500 多個節點,因此優化該方法非常重要。我一直在嘗試使用此代碼執行此操作,但沒有按預期作業:
internal static string GetNextAvailableName(TreeView treeView, string searchFor)
{
//Check if item exists
if (NodeExistsInSection(treeView, searchFor))
{
return searchFor;
}
else
{
//Initialize variables
string nextAvailableName = searchFor;
int counter = 0;
Match result = Regex.Match(searchFor, @"\d $", RegexOptions.RightToLeft);
if (result.Success)
{
counter = int.Parse(result.Value);
if (searchFor.Length >= result.Value.Length)
{
searchFor = searchFor.Substring(0, (searchFor.Length - result.Value.Length));
}
}
while (SearchRecByText(treeView, nextAvailableName) != null)
{
counter ;
nextAvailableName = string.Join("", searchFor, counter);
}
return nextAvailableName;
}
}
internal static bool NodeExistsInSection(TreeView treeView, string searchFor)
{
bool nodeExists = false;
// Print each node recursively.
foreach (TreeNode n in treeView.Nodes)
{
//recursiveTotalNodes ;
if (LoopNodesRecursive(n, searchFor) != null)
{
nodeExists = true;
break;
}
}
return nodeExists;
}
internal static TreeNode SearchRecByText(TreeView treeView, string searchFor)
{
TreeNode matchedNode = null;
// Print each node recursively.
foreach (TreeNode n in treeView.Nodes)
{
//recursiveTotalNodes ;
matchedNode = LoopNodesRecursive(n, searchFor);
if (matchedNode != null)
{
break;
}
}
return matchedNode;
}
private static TreeNode LoopNodesRecursive(TreeNode treeNode, string searchFor)
{
// Visit each node recursively.
foreach (TreeNode tn in treeNode.Nodes)
{
if (tn.Text.Equals(searchFor, StringComparison.OrdinalIgnoreCase))
{
return tn;
}
}
return null;
}
uj5u.com熱心網友回復:
如果性能是你的直接目標,我想我會有一個字典跟蹤樹節點,如果用戶輸入一個數字,它會有一個特殊情況。從發布的代碼看來,節點必須在整個樹中唯一命名。因此,我會在 tree init 上構建一個字典并在我進行時維護它
這是根據用戶鍵入的內容建議新節點名稱的方法:
Dictionary<string, int> prefixes = new();
string GetNodeName(string prefix){
//strip trailing numbers entered by the user
prefix = Regex.Replace(prefix, "\\d $", "");
//have we seen the prefix before?
var n = prefixes.GetValueOrDefault(prefix, 0);
prefixes[prefix] = n 1;
if(n > 0) //nth time we saw it, return number suffix
return prefix n;
if(prefix == "") //user entered just a number, for the first time
return "1";
return prefix; //user entered a new prefix
}
GetNodeName 通過去除尾隨數字并檢查結果前綴的下一個已知數字是什么來識別用戶鍵入的前綴文本。如果前綴未知,則為 0,然后將 1 添加為下一個數字,0 是特殊情況,表示“沒有數字后綴”
如果我們需要從某個地方恢復樹,我們需要建立我們在構建時看到的 max 1 值:
void Build(string nodename){
//strip trailing numbers
var prefix = Regex.Replace(prefix, "\\d $", "");
//get the number off the end. Uses c# 8 ranges; if your c# version is less, use Remove(length) instead
var number = int.Parse(nodename[prefix.Length..]);
//have we seen the prefix before?
var n = prefixes.GetValueOrDefault(prefix, 0);
//node number is higher than dictionary? Bump dict
if(number >= n)
prefixes[prefix] = number 1;
}
當您從 DB 或其他任何內容重建樹時,為每個節點文本呼叫 build;它會將前綴字典中的數字提高到它所看到的 1
我認為允許用戶重復輸入“test2”前綴是一個邏輯錯誤,并且您將創建“test2”、“test21”、test22”節點 - 我認為前綴是“test”,用戶提供了 2被忽略,節點獲取“test”的下一行,即“test7”。如果用戶只輸入一個數字,則此邏輯有效,然后前綴為“”并相應編號
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/315639.html
