一个小算法,自己老是不能静心想,好几天也没写出来,还是问问高手吧

wdgphc 2008-11-10 12:35:38
其实问题并不是很复杂,就是描述起来不太好说,加上我的语文也不太。。。

我有N个二进制数,举例就写7个吧。都是9位(每位都是0或1)的,
第 876543210位
a0 010010001
a1 101010011
a2 100001001
a3 100001010
a4 100000001
a5 000001010
a6 011000000

我要从中找到3个数(如果有符合要求的话)

满足以下要求:
这3个数必须有相同的3位包含这3位所有的1。 (不太好理解,下面举例说明)

比如上例中的 a0-a6 这7个数中, 看第5,7,8这3位,是不是只有 a0,a1,a6这3个数有1,而其他的数这3位全是0。 则a0a1a6为一组结果。
3个数3位满足要求可以出现的组合为
(1)、
011
101
110

(2)、
011
110
111

(3)、
011
111
111

(4)、
111
111
111

就是说只要其中某3个数的相同的某3位为这4种情况,而其他的数在这3位上都是0,则不管这3个数其他位是0是1,都是正确结果。
需要输出这3个数和这3位。

只要寻得一组数即可return。

...全文
277 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
mmmcd 2008-11-12
  • 打赏
  • 举报
回复
组合优化问题几乎可以用网络流算法求解

构造点集X,有N个点,分别对应这N个数
构造点集Y,有M个点,分别对应每个数的M个bit (如果只关心其中的3个bit位,则只需考虑3个)
如果数ai的第j个bit等于1,则点Xi与Yj之间连一条边
X与Y之间的边上赋予一个容量值为1

源点s与X的所有点分别连一条边,容量值为1
Y的所有点分别与汇点t连一条边,容量值为正无穷

对这个容量网络N(X,Y,s,t)求一个最大流

然后访问s与X的每条边,如果边<s,xi>赋予的流量非0,则ai数是所选的。
绿色夹克衫 2008-11-11
  • 打赏
  • 举报
回复
用穷举作,思路比较简单,当然,也可以先将bit集合分类,比如包含3个元素的集合,
按照lz所给出的模式,应当只有集合元素全都一样的情况下,才能符合条件。

如果找到3个一样的集合(模式4),那就算找到了,
如果找到2个一样的集合(模式3),然后根据集合中的元素C(3,2) = 3种情况,在2个元素的集合中找

同理,在找2个元素的集合时,如果两个集合的并集元素正好是3,也可以按照C(3,2) = 3种情况,在剩余的集合中找有没有符合条件的。

效率可能会比穷举高一些。

如果lz是因为是嫌穷举麻烦,附一个简单的穷举程序,相当于C(m,n)


private int[][] createPerArray(int totalCount, int selectCount)
{
List<int[]> All = new List<int[]>();
int[] currentSelect = new int[selectCount];
int last = selectCount - 1;
int position;

for (int i = 0; i < selectCount; i++)
{
currentSelect[i] = i;
}

while (true)
{
All.Add((int[])currentSelect.Clone());
if (currentSelect[last] < totalCount - 1)
{
currentSelect[last]++;
}
else
{
position = last;
while (position > 0 && currentSelect[position - 1] == currentSelect[position] - 1)
{
position--;
}
if (position == 0)
{
break;
}
currentSelect[position - 1]++;

for (int i = position; i < selectCount; i++)
{
currentSelect[i] = currentSelect[i - 1] + 1;
}
}
}
return All.ToArray();
}
yzfyzyl 2008-11-11
  • 打赏
  • 举报
回复
像是解数独的fish法


o(∩_∩)o

飞燕算法群:46520219
wdgphc 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 litaoye 的回复:]
是不是象上面大王所说的,所有三个集合的并集为3个数就可以?有没有例外?
[/Quote]

应该没用例外了,例外的情况在此之前我已经都处理,走不到这个函数了。
daidodo 2008-11-10
  • 打赏
  • 举报
回复
mark
绿色夹克衫 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wdgphc 的回复:]
只需要4种模式

3个数3位满足要求可以出现的组合为
(1)、
011
101
110

(2)、
011 011 110 110
110 或 101 或 101 不会出现 110
111 111 111 111

(3)、
011 101 110
111 或 111 或 111
111 111 111

(4)、
111
111
111

或3行轮换。
就是不可能出现某位只…
[/Quote]

是不是象上面大王所说的,所有三个集合的并集为3个数就可以?有没有例外?
wdgphc 2008-11-10
  • 打赏
  • 举报
回复
只需要4种模式

3个数3位满足要求可以出现的组合为
(1)、
011
101
110

(2)、
011 011 110 110
110 或 101 或 101 不会出现 110
111 111 111 111

(3)、
011 101 110
111 或 111 或 111
111 111 111

(4)、
111
111
111

或3行轮换。
就是不可能出现某位只有1个数为1的情况。
dobear_0922 2008-11-10
  • 打赏
  • 举报
回复
看看,支持9楼。
  • 打赏
  • 举报
回复
这个前面我也问过,楼主说的是“具体在我的程序中是不可能出现的,为了简化,我只把有可能出现的4种情况发布了一下”

要把这样的情况考虑进去也很简单,把'1'的总数放宽到1~3就可以了
绿色夹克衫 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 dlyme 的回复:]
首先统计每一位‘1’的总数。按照你给出的4种情况,只有总数是2或3的才有可能(同时还要记录在哪几行中出现过),其它的bit位都可以排除;
然后在可能的bit位中取3个进行组合。对于选出的3个bit位,检查它们出现过的“行号”的并集。如果行号并集中恰好是3行,那么就找到了满足要求的解。
[/Quote]

不一定吧,如果有这样的集合
a1,a2
a1,a2
a1,a2,a3

似乎不满足lz给出的4种模式
  • 打赏
  • 举报
回复
首先统计每一位‘1’的总数。按照你给出的4种情况,只有总数是2或3的才有可能(同时还要记录在哪几行中出现过),其它的bit位都可以排除;
然后在可能的bit位中取3个进行组合。对于选出的3个bit位,检查它们出现过的“行号”的并集。如果行号并集中恰好是3行,那么就找到了满足要求的解。
绿色夹克衫 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wdgphc 的回复:]
回1楼,原理是这样的,但是编程思路我一直想不太明白。
回2楼 统计每一位‘1’的总数,对总数为2或3的,保存bit为‘1’对应的原始数,对给出的数据,对bit7,‘1’的总数为2,保存对应的原始数a0和a6;
这样得到了9个数,对应bit8到bit0 ----- 这一步我也做了。

对这9个数中为2或3的,取3个组合,进行相应bit位的判断就行了 ---关键就是这一步没有思路啊!

回3楼 谢谢,我试试,但是这样肯定能得到吗?不一定…
[/Quote]

不一定能得到,因为可能存在

11
11
11

这样的组合,另外在位的筛选和计数删除那一步,剩余的位可能就不到3了

但我所说的方法,如果存在一组解,就一定能找到,如果本身就不存在一组解的话,就肯定找不到了!
wdgphc 2008-11-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dlyme 的回复:]
引用楼主 wdgphc 的帖子:
比如上例中的 a0-a6 这7个数中, 看第5,7,8这3位

好像你的例子里是在说4、6、7这三位


引用楼主 wdgphc 的帖子:
3个数3位满足要求可以出现的组合为
(1)、
011
101
110

(2)、
011
110
111

(3)、
011
111
111

(4)、
111
111
111

就是说只要其中某3个数的相同的某3位为这4种情况...
为什么只有这4种情况?还有很多啊
100
010
00…
[/Quote]


对对对,程序中是从0开始的。是4,6,7三位。
另外,
100
010
001
这种情况是对的,但是具体在我的程序中是不可能出现的,为了简化,我只把有可能出现的4种情况发布了一下。谢谢!
绿色夹克衫 2008-11-10
  • 打赏
  • 举报
回复
再补充一点

比如当前的578,每个集合2个元素,共6个元素,按照1的模式来判断

011
101
110

8 a0,a6
7 a1,a6
5 a0,a1

(只取578位)
a0 010010001 => 101
a1 101010011 => 011
a6 011000000 => 110

对101\011\110 排序=>011\101\110

然后再同模式1比较
wdgphc 2008-11-10
  • 打赏
  • 举报
回复
回1楼,原理是这样的,但是编程思路我一直想不太明白。
回2楼 统计每一位‘1’的总数,对总数为2或3的,保存bit为‘1’对应的原始数,对给出的数据,对bit7,‘1’的总数为2,保存对应的原始数a0和a6;
这样得到了9个数,对应bit8到bit0
----- 这一步我也做了。

对这9个数中为2或3的,取3个组合,进行相应bit位的判断就行了 ---关键就是这一步没有思路啊!

回3楼 谢谢,我试试,但是这样肯定能得到吗?不一定吧。
  • 打赏
  • 举报
回复
[Quote=引用楼主 wdgphc 的帖子:]
比如上例中的 a0-a6 这7个数中, 看第5,7,8这3位
[/Quote]
好像你的例子里是在说4、6、7这三位


[Quote=引用楼主 wdgphc 的帖子:]
3个数3位满足要求可以出现的组合为
(1)、
011
101
110

(2)、
011
110
111

(3)、
011
111
111

(4)、
111
111
111

就是说只要其中某3个数的相同的某3位为这4种情况...[/Quote]
为什么只有这4种情况?还有很多啊
100
010
001
这样的为什么不算?
绿色夹克衫 2008-11-10
  • 打赏
  • 举报
回复
a0 010010001
a1 101010011
a2 100001001
a3 100001010
a4 100000001
a5 000001010
a6 011000000 +
------------------------
sum 422023034

sum >=2 <=3 =>2 4 5 7 8位

8 a0,a6
7 a1,a6
5 a0,a1
4 a2,a3,a5
2 a1,a3,a5

计数
a0 = 2
a1 = 3
a2 = 1
a3 = 2
a5 = 2
a6 = 2

a2 < 2 删除,所以
4 a2,a3,a5 删除
a3 = 1 a5 = 1 a3\a5 < 2 删除
2 a1,a3,a5 删除

剩下

8 a0,a6
7 a1,a6
5 a0,a1

穷举一下位的组合,组合后的集合元素数量如果=6按照1判断=7按照2判断=8按照3判断=9按照4判断
比如当前的875,每个集合2个元素,共6个元素,按照1的模式来判断

011
101
110


(这种方法效率不高,但应当可以找到1组)
oo 2008-11-10
  • 打赏
  • 举报
回复
统计每一位‘1’的总数,对总数为2或3的,保存bit为‘1’对应的原始数,对给出的数据,对bit7,‘1’的总数为2,保存对应的原始数a0和a6;
这样得到了9个数,对应bit8到bit0

对这9个数中为2或3的,取3个组合,进行相应bit位的判断就行了
fenix124 2008-11-10
  • 打赏
  • 举报
回复
枚举哪3位,对于这道题来说规模是个常量。
对于每选定的三位稍描以下整个N个二进制数,结果最多为8个,这8个数来一下3次方的计算,又是一个常量。
最后复杂度为o(N).


完事,给点分。

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧