【问题标题】:How do I correctly sort this array?如何正确排序这个数组?
【发布时间】:2016-12-09 12:47:53
【问题描述】:

我正在尝试对堆叠的立方体数组进行排序。 数组看起来像这样(一个例子)

Nth Cube | Position (0, its on the desk, >0,  its on another cube)
---
1|6
---
2|8
---
3|0
---
4|0
---
5|0
---
6|0
---
7|1
---
8|4
---

看起来像这样可视化

[7] [2]
---
[1] [8]
---
[6] [4] [3] [5]
---

我整理了另一个上的立方体:

string[,] t 在这种情况下是整个数组

static string[,] stackedCubes(string[,] t)
    {
        string[,] stackedHelp = new string[NumberOfStacked(),2];
        int j = 0;
        for (int i = 0; i < t.GetLength(0); i++)
        {
            if (t[i, 1]!="0")
            {

                stackedHelp[j, 0] = t[i, 0];
                stackedHelp[j, 1] = t[i, 1];
                j++;
            }
        }
        return stackedHelp;
    }

结果如下:

1|6
---
2|8
---
7|1
---
8|4
---

现在我试图从顶部放下它们(所以 7/2 然后 1/8)

string[,] t 从这里开始是stackedCubes

static string[,] Putdown(string[,] t)
    {
        string[,] stackedOrder = new string[NumberOfStacked(), 2];
        int j = 0;
        do
        {
            for (int i = 0; i < t.GetLength(0); i++)
            {
                if (t[i, 1] == t[j, 0])
                {
                    j = i;
                }
                else if(IsSomethingOnTheCube(t[j,0],t)==false)
                {
                    stackedOrder[i, 0] = t[j, 0];
                    stackedOrder[i, 1] = "0";
                    t[i, 1] = "0";
                }
            }
        }
        while (AreAllTheCubesOnTable(t) != true);

        return stackedOrder;
    }

这里我从第一个 Cube 1(t[j,0]) 出发并检查上面是否有东西,它在 t[i,1] 上找到它并返回 7(t[j,0] ) 并返回。 我在这里检查一下 Cube 上是否有东西

    static bool IsSomethingOnTheCube(string Cube,string[,] t)
    {
        for (int i = 0; i < t.GetLength(0); i++)
        {
            if(Cube==t[i,1])
            {
                return true;
            }
        }
        return false;
    }

我还检查他们是否都在桌子上(在做的时候)

    static bool AreAllTheCubesOnTable(string[,] t)
    {
        for (int i = 0; i < t.GetLength(0); i++)
        {
            if (t[i, 1] != "0")
            {
                return false;
            }
        }
        return true;
    }

而且输出全错了:

7|0
---
7|0
---
7|0
---
7|0
---

什么时候应该是这样的:

7|0
---
1|0
---
2|0
---
8|0
---

我在哪里索引错误?(或其他)

【问题讨论】:

  • 您的预期结果 (7|0, 1|0, 2|0, 8|0) 应该代表什么?
  • Putdown() 的返回值 - 即 string[,]StackedOrder - 完成后
  • 您在问题中使用的领域语言令人困惑;一个“立方体”是“在桌子上”或“在另一个立方体上”,对于您大脑之外的人或知情者之外的人来说绝对没有任何意义。用简单的代码说话。
  • @eurotrash 虽然这可能是你的意见,但我只是想象了一个由立方体组成的金字塔。因此,虽然您可能认为它没用,但 OP 描述帮助我将他的问题置于上下文中
  • 是的,我也不知道这应该做什么。

标签: c# arrays sorting


【解决方案1】:

在提供的样本中

string[] cubes = new string[]
  {"1|6", "2|8", "3|0", "4|0", "5|0", "6|0", "7|1", "8|4"};

问题中的底线看起来像是随机的。让我们订购 最低的立方体(比如说,按字典顺序),因此可视化将是:

lines:
   2:        [2]     [7]
   1:        [8]     [1]
   0:    [3] [4] [5] [6]  <- bottom line is sorted
------------------------
files:    0   1   2   3

完成后,我们可以实现两个帮助方法

   // Line: 0 for lowest cubes
   private static int CubeLine(string value, IEnumerable<String> stack) {
      for (int line = 0; ; ++line) {
        string parent = value.Substring(value.IndexOf('|') + 1);

        if ("0".Equals(parent))
          return line;

        value = stack.First(item => item.StartsWith(parent + "|"));
      }
    }

还有

    // File: 0 for leftmost cubes
    private static int CubeFile(string value, IEnumerable<String> stack) {
      string root = value;

      while (true) {
        string parent = root.Substring(root.IndexOf('|') + 1);

        if ("0".Equals(parent))
          break;

        root = stack.First(item => item.StartsWith(parent + "|"));
      }

      return stack
        .Where(item => item.Substring(value.IndexOf('|') + 1) == "0")
        .OrderBy(item => item)
        .Select((item, index) => new {
          item = item,
          index = index
        })
        .First(item => item.item == root)
        .index;
    }

然后您可以轻松地对您喜欢的任何内容进行排序。例如,让我们排序 最上面的立方体优先,如果是最左边的优先:

 string[] cubes = new string[]
   {"1|6", "2|8", "3|0", "4|0", "5|0", "6|0", "7|1", "8|4"};

  var result = cubes
    .Select (cube => new {
      name = cube.Substring(0, cube.IndexOf('|')),
      file = CubeFile(cube, cubes),
      line = CubeLine(cube, cubes) })
    .OrderByDescending(cube => cube.line)
    .ThenBy(cube => cube.file)
    .Select(cube => cube.name);

  Console.Write(string.Join(", ", result));

结果是

  2, 7, 8, 1, 3, 4, 5, 6

编辑:如果要先从左到右排序,则从上到下排列:

  var result = cubes
    .Select (cube => new {
      name = cube.Substring(0, cube.IndexOf('|')),
      file = CubeFile(cube, cubes),
      line = CubeLine(cube, cubes) })
    .OrderBy(cube => cube.file)
    .ThenByDescending(cube => cube.line)
    .Select(cube => cube.name);  

结果是

 3, 2, 8, 4, 5, 7, 1, 6

编辑2:放下顺序:底部优先,并列任意

  var result = cubes
    .Select (cube => new {
      name = cube.Substring(0, cube.IndexOf('|')),
      file = CubeFile(cube, cubes),
      line = CubeLine(cube, cubes) })
    .OrderBy(cube => cube.line)
    .Select(cube => cube.name);  

结果:

  3, 4, 5, 6, 1, 8, 2, 7 

【讨论】:

  • 问题中的预期结果给出了排序 7 -> 1,这使得可视化意味着垂直排序。您的回答给出了横向排序。
  • @EpicSam:拥有CubeFileCubeLine 可以根据需要轻松整理数组。查看我的编辑。
  • 天哪,我从哪里开始,首先感谢您抽出时间回答这个问题,但是由于我最近才开始学习编程,所以我无法真正制作任何您放在那里的代码,并翻译成我的成功(我试过了,当它可以构建它时输出 system.linq ...),当我尝试从上往下放置()它们时,我真的只需要排序数组stackedCubes()的帮助,如预期结果所示
【解决方案2】:

尽管在开始编程时在许多示例中都使用了多维数组,但通常建议使用强类型类的数组。也就是说,当多维数组仍然可以解析为另一种格式时,例如字典。例如:

string[,] cubes = {{"1","6"} ,{ "2","8"} ,{ "3","0"} ,{ "4","0"} ,{ "5","0"} ,{ "6","0"} ,{ "7","1"} ,{ "8","4"}};


//create a dictionary of all cube-parents
var parents = (from i in Enumerable.Range(0, cubes.GetLength(0))                    
                group cubes[i,0] by cubes[i,1])
                .ToDictionary(g=>g.Key, g=>g.ToArray());    

var layer = parents["0"]; //table level cubes [3,4,5,6]
var layers=  new List<string[]>();
while(layer != null){
    layers.Add(layer);
    string[] children, nextlayer = null;
    for(int i = 0; i < layer.Length; i++)
        if(layer[i] != null && parents.TryGetValue(layer[i], out children)){
            if(nextlayer==null)nextlayer= new string[layer.Length];
            nextlayer[i] = children[0]; //what to do with multiple children?
        }
    layer= nextlayer;
};

当上述完成后,layers 包含{[3,4,5,6],[null,8,null,1], [null,2,null,7]} 也就是几个层。我不完全确定哪个是理想的最终结果。它是视觉表示还是类似所有不在桌子上的立方体(对于后者,它只是所有没有父“0”的项目)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多