如何对零和一的字符串数组进行排序?

时间:2018-07-07 18:44:12

标签: c# .net

我正在尝试按二进制格式对整数数组进行排序。例如,如果我有{1,2,3},我必须将它们转换为二进制,然后根据每个1的数量对其进行排序;如果数字只有一个1,则它是数字1,然后出现具有二进制形式的两个1的数字,依此类推。

我尝试使用以下两种方法,但是由于错误,我无法使用它们,我也不明白。我搜索了所有stackoverflow,但无法弄清楚,我在这里遇到了这个问题。

public static int[] xx = { 1, 2, 3, 4, 5, 6, 87, 8, 9, 7, 5, 24, 58, 63, 10, 11, 87, 20, 22, 90, 14, 17, 19, 21, 18, 24 };

        public string[] ChangeToBinary(int[] data)
        {
            string[] binary = new string[data.Length];
            var i = 0;
            foreach (int d in data)
            {
                string newvalue = Convert.ToString(d, 2);
                binary[i] = newvalue;
                i++;
            }
            return binary;
        }

        public int[] Sort(string[] binaries)
        {
            Array.Sort(binaries, (x, y) => x.Count(z => z == '1') > y.Count(e => e == '1'));
            string[] sorted = binaries.OrderBy(b => b.Count(z => z == '1') > b.Count(e => e == '1'));
        }

sort函数中的两行,我知道在某些地方我错了,有人可以告诉我该怎么做吗?我试图说要根据元素中最少1个元素对数组元素进行排序。

我不会两者都用,但是我把它们告诉你我想用的东西。 预先感谢。

3 个答案:

答案 0 :(得分:0)

有两种不同的自定义排序方法:

  • 您提供了任意两个元素之间的比较。这就是Array.Sort的目的。比较必须返回一个int,其值为负,零或正,以指示第一个元素是否小于,等于或大于第二个元素。 (您的lambda表达式当前返回bool,因为您使用的是>。)
  • 您从 one 元素提供一个投影,然后排序算法将比较该投影的结果。这就是OrderBy的工作-但您在OrderBy中提供的lambda表达式会将一个元素的计数与 same 元素的计数进行比较。

我建议使用OrderBy方法,因为这要简单得多。您只是想按计数排序,因此只需要计算所提供元素中的1,然后返回该计数即可:

string[] sorted = binaries.OrderBy(b => b.Count(z => z == '1')).ToArray();

现在,您的方法应立即返回int[]。大概它将每个二进制字符串转换回int。我建议不要这样做-而是更改您的Sort方法以返回排序后的string[]。然后,您可以使用其他方法执行转换,无论是单独的方法还是调用方法。

这是我首先采用的方法,是对代码的最小更改-也是了解SortOrderBy方法中发生的情况的一种方式。然后,您可以直接更改整数的顺序,而无需像Dmitry所建议的那样直接创建字符串数组。

答案 1 :(得分:0)

借助Convert Linq ,您可以轻松计算1个:

 int value = ...

 ones = Convert
   .ToString(value, 2)    // Binary representation
   .Count(c => c == '1'); // Count 1's

完成此操作后,让我们对数组进行排序:

 int[] xx = ...

 int[] sorted = xx
   .OrderBy(value => Convert // criterium: see the code above
      .ToString(value, 2)
      .Count(c => c == '1'))
   .ThenBy(value => value)   // on tie e.g. 0b101 and 0b110 let's use value
   .ToArray();

答案 2 :(得分:0)

为我们当中那些只涉足Linq的人提供的解决方案。更多代码,但请记住linq在下面循环。

 public static int[] xx = { 1, 2, 3, 4, 5, 6, 87, 8, 9, 7, 5, 24, 58, 63, 10, 11, 87, 20, 22, 90, 14, 17, 19, 21, 18, 24 };
        public class MyBinary
        {
            public string BinString { get; set; }
            public int OneCount { get; set; }
            public int OriginalInt { get; set; }
            public MyBinary(string input, int count, int original)
            {
                OriginalInt = original;
                BinString = input;
                OneCount = count;
            }
        }

        private List<MyBinary> SortByOnes(int[] input)
        {
            List<MyBinary> lst = new List<MyBinary>();
            //The following will give a result First ordered by number of ones but also 
            // secondarily the original numbers
            //just a bit of linq
            int[] SortedArray = (from i in input orderby i select i).ToArray();
            List <MyBinary> lstSorted = new List<MyBinary>();
            int index = 0;
            string[] Bin = new string[SortedArray.Count()];
            foreach (int i in SortedArray)
            {
                Bin[index] = Convert.ToString(i, 2);
                 int oneCount = 0;
                foreach (char c in Bin[index])
                {
                    if (c == '1')
                        oneCount += 1;
                }
                //sends the binary string, the count of ones, and the original number
                //to the constructor of MyBinary
                lst.Add(new MyBinary(Bin[index], oneCount, i));
                lstSorted = (from b in lst orderby b.OneCount descending select b).ToList();
                index += 1;
            }
            return lstSorted;
        }
       //To use:
        private void TestSort()
        {
            List<MyBinary> lst = SortByOnes(xx);
            foreach (MyBinary b in lst)
            { Debug.Print($"{b.OneCount}  -  {b.BinString}  -  {b.OriginalInt}"); }
        }