C# 我该如何进行这样的排序

C# 我该如何进行这样的排序,c#,vb.net,C#,Vb.net,目前,对于一个学校项目,我必须根据类似的数字制作一个数组 任何长度为1-2-3-4的数字都可以有子项 然而,我不知道如何通过编程来解决这个问题,因为当这个场景中的数字1440不存在时,144010~必须将其自身排序为144,如果144不存在,它将降到14以下,但保持在以142开头的数字之下 如果能为我解决这个问题提供帮助,我将不胜感激 编辑: 我尝试过的一些代码: 1 14 141 141010 141020 141030

目前,对于一个学校项目,我必须根据类似的数字制作一个数组

任何长度为1-2-3-4的数字都可以有子项

然而,我不知道如何通过编程来解决这个问题,因为当这个场景中的数字1440不存在时,144010~必须将其自身排序为144,如果144不存在,它将降到14以下,但保持在以142开头的数字之下

如果能为我解决这个问题提供帮助,我将不胜感激

编辑:

我尝试过的一些代码:

 1
  14
    141
        141010
        141020
        141030
        141040
        141050
        141060
    142
        142010
        142020
    144
        1440
          144010
          144020
          144030
          144040  

正如我之前所说,查看Treeview。它已经为您提供了这种层次结构

这段代码是用C语言编写的,但是你可以很容易地转换成VB(手动或使用像Telerik这样的在线转换器进行编辑):

注意:如果不想使用Treeview,请使用如下逻辑:

  • 创建一个列表
  • 循环你的价值观
  • 对于每个值,以字符串形式获取值
  • 循环从长度向0开始,并获取子字符串(假设值为144010)
  • 检查子字符串是否存在(您将找到1440)
  • 如果它确实使用该值加上分隔符作为值的前缀,(1440\144010)
  • 现在继续搜索新的父项(1440)
  • 添加您找到的任何“家长”(最终将成为1/14/144/1440/144010)
  • 将此添加到顶部的列表中
  • 对列表进行排序(因为类似于目录的结构,所有值都会找到它们的位置)
  • 您可以转储按分隔符计数+最后一个分隔符后的值(如目录结构中的最后一个文件夹名)缩进的值

    • 以下是不使用Treeview的情况下如何做到这一点(我不知道你为什么不这样做):

      这是VB版本(警告:我不使用VB,也不知道它,使用了Telerik converter并进行了轻微修改以使其正常工作,因为VB.Net缺少“\t”之类的文字,我打算使用4个空格-不想添加VisualBasic命名空间):

      Private Sub-Main()
      作为字符串的Dim值=
      1.
      14
      141
      141010
      141020
      141030
      141040
      141050
      141060
      142
      142010
      142020
      144
      1440
      144010
      144020
      144030
      144040
      145020
      145030
      145010
      '拆分并转换为按随机顺序排列的整数集合
      “仅仅显示最初的顺序并不重要
      将myValue设置为整数
      Dim myData=值_
      .Split(Environment.NewLine.ToCharArray(),StringSplitOptions.RemoveEmptyEntries)_
      .选择(函数If(Integer.TryParse(s.Trim(),myValue),myValue,-1))_
      .其中(函数(n)n-1)_
      .OrderBy(函数(n)Guid.NewGuid())
      “我们有藏品。按“目录”方式排序
      Dim myList As List(Of String)=新列表(Of String)()
      Dim list=myData.Select(函数(d)d.ToString())
      对于myData中的每个v
      添加(完整路径(v.ToString(),列表))
      下一个
      “写出预期的结果
      Dim ordered=myList.OrderBy(函数(l)l)
      对于排序中的每个元素
      尺寸级别=元素计数(函数(e)e=“/”c)
      Dim值=If(级别>0,元素移除(0,元素.LastIndexOf(“/”c)+1),元素)
      Console.WriteLine(“.”.PadLeft(级别*4,”)+值)
      下一个
      端接头
      '获取具有祖先的值的完整路径
      ie:1/14/1440/144010是144010的完整路径
      私有函数Fullpath(ByVal键作为字符串,ByVal列表作为(字符串的)IEnumerable)作为字符串
      作为列表(字符串的)调整路径=新列表(字符串的)()
      对于i As Integer=1到key.Length
      如果list.Any(函数(v)key.Substring(0,i)=v),则
      path.Add(key.Substring(0,i))
      如果结束
      下一个
      返回字符串。连接(“/”,路径)
      端函数
      '=======================================================
      “Telerik提供的服务(www.Telerik.com)
      “由重构要素支持的转换。
      推特:@telerik
      Facebook:Facebook.com/telerik
      '=======================================================
      
      任何长度为1-2-3-4的数字
      数字没有长度,所以我猜你真的在使用字符串?这篇文章通常都很不清楚你的最终结果是什么?这仅仅是一个顺序(例如在数组中)还是你真的想要一个层次结构作为你的最终结果?你尝试了什么,你是如何失败的?理想情况下,您应该提供您尝试过的内容的详细信息,并包括关于失败原因的具体信息,以及错误消息和/或错误输出。不是代码编写服务;最好的问题是那些提供有用信息的问题,这样那些回答问题的人可以引导你设计出自己的正确答案。请看一个好问题。@Protoix是的,很抱歉英语不是我的第一语言,事实上每一个“数字”是一个字符串currentlyHello@Chris我不知道如何解释它,但当例如141不存在时,141010-141060必须保持在14以下,但所有以142开头的数字必须在141之后。我很抱歉问这个问题,但是我如何处理代码中的列表部分,因为我被你的解释弄糊涂了。我将添加另一个答案。
       Public Class DataSet
              Public Property one As Integer
              Public Property two As New List(Of Two)
              Public Property three As New List(Of three)
              Public Property four As New List(Of four)
          End Class
      
          Public Class Two
              Public Property two As Integer
              Public Property three As New List(Of three)
          End Class
      
          Public Class three
              Public Property three As Integer
              Public Property four As New List(Of four)
          End Class
      
          Public Class four
              Public Property four As Integer
              Public Property six As New List(Of String)
          End Class
      
          Sub Main()
              Dim ds As New List(Of DataSet)
              Dim one As New List(Of String)
              Dim two As New List(Of String)
              Dim three As New List(Of String)
              Dim three_found As New List(Of String)
              Dim four As New List(Of String)
              Dim six As New List(Of String)
              Dim words() As String = File.ReadAllLines("Numbers.txt")
              For Each w In words
                  Dim length = w.Length
                  Dim number = Convert.ToInt32(w)
                  Select Case length
                      Case 1
                          one.Add(w)
                      Case 2
                          two.Add(w)
                      Case 3
                          three.Add(w)
                      Case 4
                          four.Add(w)
                      Case 6
                          six.Add(w)
                  End Select
              Next
      
              For Each i In one
                  Dim dso As New DataSet
                  dso.one = i
                  For Each t In two
                      If t.StartsWith(i.ToString()) Then
                          Dim newtwo = New Two
                          newtwo.two = t
                          dso.two.Add(newtwo)
                      End If
                      For Each th In three
                          If th.StartsWith(i) Then
                              three_found.Add(th)
                              Dim twoc = th.Substring(0, 2)
                              If twoc.StartsWith(t) Then
                                  Dim threec As New three
                                  threec.three = th
                                  Dim threef = dso.two.Where(Function(w) w.two = twoc).FirstOrDefault()
                                  If threef IsNot Nothing Then
                                      threef.three.Add(threec)
                                  Else
                                      dso.three.Add(threec)
                                  End If
                              End If
                          End If
                      Next
                  Next        
                  ds.Add(dso)
              Next
      
          End Sub
      
      void Main()
      {
          string values = @"1
        14
          141
              141010
              141020
              141030
              141040
              141050
              141060
          142
              142010
              142020
          144
             1440
                144010
                144020
                144030
                144040
          145020
          145030
          145010
                ";
      
          int myValue;
          var myData = values.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
              .Select(s => int.TryParse(s.Trim(), out myValue)?myValue:-1)
              .Where(n => n != -1);
      
          Func<int, IEnumerable<int>, int?> parent = (value, list) =>
          {
              while (value > 0)
              {
                  value /= 10;
                  if (list.Any(l => l == value))
                  {
                      return value;
                  }
              }
              return null;
          };
      
          var nodes = myData
              .Select(d => new { d, parentNode = parent(d, myData) })
              .OrderBy(d => d.parentNode)
              .ThenBy(d => d.d);
      
          TreeView tv = new TreeView();
          foreach (var n in nodes)
          {
              var v = n.d.ToString();
              ((n.parentNode == null)
              ? tv.Nodes
              : tv.Nodes.Find("_" + n.parentNode.ToString(), true).First().Nodes)
              .Add("_" + v, v);
          }
      
          foreach (TreeNode node in tv.Nodes)
          {
              WriteNode(node, 0);
          }
      }
      
      private void WriteNode(TreeNode node, int level)
      {
          Console.WriteLine("".PadLeft(level, '\t') + node.Text);
          foreach (TreeNode n in node.Nodes)
          {
              WriteNode(n, level + 1);
          }
      }
      
      1
        14
          141
            141010
            141020
            141030
            141040
            141050
            141060
          142
            142010
            142020
          144
            1440
              144010
              144020
              144030
              144040
          145010
          145020
          145030
      
      void Main()
      {
          string values = @"1
        14
          141
              141010
              141020
              141030
              141040
              141050
              141060
          142
              142010
              142020
          144
             1440
                144010
                144020
                144030
                144040
          145020
          145030
          145010
                ";
      
          int myValue;
      // Splitting and converting to a collection of integers ordered by randomly
      // just to show initial order doesn't matter
          var myData = values.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
              .Select(s => int.TryParse(s.Trim(), out myValue) ? myValue : -1)
              .Where(n => n != -1)
              .OrderBy(n => Guid.NewGuid());
      
      // We have the collection. Sort it "directory" style
          List<string> myList = new List<string>();
          var list = myData.Select(d => d.ToString());
          foreach (var v in myData)
          {
              myList.Add(Fullpath(v.ToString(), list));
          }
          var ordered = myList.OrderBy(l => l);
      // Write out the result intended
          foreach (var element in ordered)
          {
              var levels = element.Count(e => e == '/');
              var value = levels > 0 ? element.Remove(0, element.LastIndexOf('/') + 1) : element;
              Console.WriteLine("".PadLeft(levels, '\t') + value);
          }
      }
      
      // Get the full path for a value with ancestors
      // ie: 1/14/1440/144010 is the full path for 144010
      private string Fullpath(string key, IEnumerable<string> list)
      {
          List<string> paths = new List<string>();
          for (int i = 1; i <= key.Length; i++)
          {
              if (list.Any(v => key.Substring(0, i) == v))
              {
                  paths.Add(key.Substring(0, i));
              }
          }
          return string.Join("/", paths);
      }
      
      1
        14
          141
            141010
            141020
            141030
            141040
            141050
            141060
          142
            142010
            142020
          144
            1440
              144010
              144020
              144030
              144040
          145010
          145020
          145030
      
      Private Sub Main()
          Dim values As String = <values>
      1
        14
          141
              141010
              141020
              141030
              141040
              141050
              141060
          142
              142010
              142020
          144
             1440
                144010
                144020
                144030
                144040
          145020
          145030
          145010
      </values>
      
      ' Splitting and converting to a collection of integers ordered by randomly
      ' just to show initial order does not matter
          Dim myValue As Integer
          Dim myData = values _
              .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) _
              .Select(Function(s) If(Integer.TryParse(s.Trim(), myValue), myValue, -1)) _
              .Where(Function(n) n <> -1) _
              .OrderBy(Function(n) Guid.NewGuid())
      
      ' We have the collection. Sort it "directory" style
          Dim myList As List(Of String) = New List(Of String)()
          Dim list = myData.Select(Function(d) d.ToString())
          For Each v In myData
              myList.Add(Fullpath(v.ToString(), list))
          Next
      
      ' Write out the result intended
          Dim ordered = myList.OrderBy(Function(l) l)
          For Each element In ordered
              Dim levels = element.Count(Function(e) e = "/"c)
              Dim value = If(levels > 0, element.Remove(0, element.LastIndexOf("/"c) + 1), element)
              Console.WriteLine("".PadLeft(levels * 4, " ") + value)
          Next
      End Sub
      
      ' Get the full path for a value with ancestors
      ' ie: 1/14/1440/144010 is the full path for 144010
      Private Function Fullpath(ByVal key As String, ByVal list As IEnumerable(Of String)) As String
          Dim paths As List(Of String) = New List(Of String)()
          For i As Integer = 1 To key.Length
              If list.Any(Function(v) key.Substring(0, i) = v) Then
                  paths.Add(key.Substring(0, i))
              End If
          Next
      
          Return String.Join("/", paths)
      End Function
      
      '=======================================================
      'Service provided by Telerik (www.telerik.com)
      'Conversion powered by Refactoring Essentials.
      'Twitter: @telerik
      'Facebook: facebook.com/telerik
      '=======================================================