在32位二进制中找到某一个位置左右的1出现的位
是这样,我用两位为一组表示一个位置上的四种状态,就像这样:
组:0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 01 01 00
值:00 01 00 10 10 10 00 00 01 01 01 00 10 00 00 00
现在我要把红色的00那一位作为原点,分别向左右查找第一组10。
我的思路是
00 01 00 10 10 10 00 00 01 01 01 00 10 00 00 00
and
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
=
00 00 00 10 10 10 00 00 00 00 00 00 10 00 00 00
然后就不会了…………
因为这个原点的位置是未知的,可以是0-14之间的任何一个(15那个一直为00)。哪位能提出高效的算法?截断的话是不是还不如直接遍历比较了。。。。
[解决办法]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var groups = "0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 01 01 00".Split(' ').Select(x => x);
var values = "00 01 00 10 10 10 00 00 01 01 01 00 10 00 00 00".Split(' ').Select(x => (x[0] - '0') * 2 + (x[1] - '0'));
var query = groups.Zip(values, (g, v) => new { g, v })
.Select((x, i) => new { i, x.g, x.v })
.GroupBy(x => x.i <= 7).Select(x => x.Key ? x.OrderBy(y => y.i).Last(y => y.v == 2).g : x.OrderBy(y => y.i).First(y => y.v == 2).g);
foreach (var item in query)
Console.WriteLine(item);
}
}
}
int origin = 7; //原点位置
var values = "00 01 00 10 10 10 00 00 01 01 01 00 10 00 00 00".Split(' ')
.Select((x, i) => new { v = Convert.ToByte(x, 2), i })
.Skip(1) //15总是00,因此不需要对其筛选
.ToArray();
var left = values.Take(origin - 1).Where(s => s.v == 2).Select(s => s.i).Last();
var right = values.Skip(origin - 1).Where(s => s.v == 2).Select(s => s.i).First();
//因为是从F -> 0排列的,因此索引需要与15取补数
Console.WriteLine("Left:{0}\tRight:{1}", (15 - left).ToString("X2"), (15 - right).ToString("X2"));