我正在尝试按二进制格式对整数数组进行排序。例如,如果我有{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
个元素对数组元素进行排序。
我不会两者都用,但是我把它们告诉你我想用的东西。 预先感谢。
答案 0 :(得分:0)
有两种不同的自定义排序方法:
Array.Sort
的目的。比较必须返回一个int
,其值为负,零或正,以指示第一个元素是否小于,等于或大于第二个元素。 (您的lambda表达式当前返回bool
,因为您使用的是>
。)OrderBy
的工作-但您在OrderBy
中提供的lambda表达式会将一个元素的计数与 same 元素的计数进行比较。我建议使用OrderBy
方法,因为这要简单得多。您只是想按计数排序,因此只需要计算所提供元素中的1,然后返回该计数即可:
string[] sorted = binaries.OrderBy(b => b.Count(z => z == '1')).ToArray();
现在,您的方法应立即返回int[]
。大概它将每个二进制字符串转换回int
。我建议不要这样做-而是更改您的Sort
方法以返回排序后的string[]
。然后,您可以使用其他方法执行转换,无论是单独的方法还是调用方法。
这是我首先采用的方法,是对代码的最小更改-也是了解Sort
和OrderBy
方法中发生的情况的一种方式。然后,您可以直接更改整数的顺序,而无需像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}"); }
}