搞应用开发也遇到算法问题,求助,你肯定感兴趣的

lindping 2012-11-09 03:46:20
事情的起因是我需要从域里面读出所有被禁用的域账号作清理。
然后发现域账号的属性里有一项userAccountControl表示账号的启用状态的。
1 该项的状态值允许有多个,并且只存储它们的和。
2 所有状态值为2的n次方。(1,2,4,8...)
附微软官方资料
属性标志 十六进制值 十进制值
SCRIPT 0x0001 1
ACCOUNTDISABLE 0x0002 2
HOMEDIR_REQUIRED 0x0008 8
LOCKOUT 0x0010 16
PASSWD_NOTREQD 0x0020 32
PASSWD_CANT_CHANGE 0x0040 64
ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
TEMP_DUPLICATE_ACCOUNT 0x0100 256
NORMAL_ACCOUNT 0x0200 512


利用ladp协议读取出来的总和值,如何反推出来由哪几个状态组合而成的?
事实我上的目的无非就是想确认账号里有没有被禁用状态(值为2)。
注:一个用户被禁用后,肯定有2的状态,但还会有若干个其它状态。

最后归纳为数学问题,已知数列为2的那次方(1,2,4,8,16...)
从中抽取任意个(各不相同)相加,已知和为N,如何反推出来这几个加数是多少?
...全文
182 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
silentcross 2012-11-09
  • 打赏
  • 举报
回复
其实就是每个值对应二进制里的一位 1 00000001 2 00000010 4 00000100 8 00001000
铜臂阿铁木 2012-11-09
  • 打赏
  • 举报
回复
域操作本来就不快,你还玩乘法,这不是要了命了么
silentcross 2012-11-09
  • 打赏
  • 举报
回复
位与嘛,这是老式的状态记录方式,比如你想知道X里包含4没有,那就是 if(X & 4 == 4){...}
铜臂阿铁木 2012-11-09
  • 打赏
  • 举报
回复
引用 14 楼 sunzongbao2007 的回复:
二进制展开之后你就会发现一个很长的二进制。 每位代表一个开关。 你只需要做右移位->判断类型->加入属性列表。 就行了。
至于什么除以二的操作……太慢了
铜臂阿铁木 2012-11-09
  • 打赏
  • 举报
回复
二进制展开之后你就会发现一个很长的二进制。 每位代表一个开关。 你只需要做右移位->判断类型->加入属性列表。 就行了。
dlgdd 2012-11-09
  • 打赏
  • 举报
回复
引用 6 楼 Return_false 的回复:
需要修正一下,如果是任意的之和的话,上面只是顺序输出 C# code 12345678910111213 private List<int> GetList(int sum) { List<int> list = new List<int>(); for (int i = 1; i……
很强大,学习了。。。二进制都还给老师了。。。
dlgdd 2012-11-09
  • 打赏
  • 举报
回复
======================= 这是我的代码 我测了一下,试了几个值,结果都是正确的。 ======================= static void Main(string[] args) { int sum; string strSum = Console.ReadLine(); sum = Convert.ToInt32(strSum); List<int> ln = new List<int>(); int n; while(sum>0) { n = (int)Math.Log(sum, 2); sum -= (int)Math.Pow(2, n); ln.Add(n); } if (ln.Count>0) { for (int i = 0; i < ln.Count;i++ ) { Console.WriteLine(ln[i]); } } Console.ReadKey(); }
引用 10 楼 dlgdd 的回复:
有个比较笨的方法,假设任意个加数从小到大排列,分别为2^n1、2^n2...2^nx, 它们的加和为sum 可以证明sum肯定小于2^(nx +1 ),且大于或等于2^nx。 所以,nx的值为(long)Math.Log(2,sum); 将sum - 2^x 得到 sum1, 循环用上述方法,直到刚好有一个2^ni等于sumk或者sumk=1。 代码才刚学,思路先奉上,希望楼主喜欢
紫魂一号 2012-11-09
  • 打赏
  • 举报
回复
引用 6 楼 Return_false 的回复:
需要修正一下,如果是任意的之和的话,上面只是顺序输出 C# code 12345678910111213 private List<int> GetList(int sum) { List<int> list = new List<int>(); for (int i = 1; i……
sum & i 这个啥意思 没搞懂哈。。
dlgdd 2012-11-09
  • 打赏
  • 举报
回复
有个比较笨的方法,假设任意个加数从小到大排列,分别为2^n1、2^n2...2^nx, 它们的加和为sum 可以证明sum肯定小于2^(nx +1 ),且大于或等于2^nx。 所以,nx的值为(long)Math.Log(2,sum); 将sum - 2^x 得到 sum1, 循环用上述方法,直到刚好有一个2^ni等于sumk或者sumk=1。 代码才刚学,思路先奉上,希望楼主喜欢
xuan.ye 2012-11-09
  • 打赏
  • 举报
回复
8楼的意思看明白了,就是程序没懂,好深奥,学习了。
真相重于对错 2012-11-09
  • 打赏
  • 举报
回复
CRIPT 0x0001 1 ACCOUNTDISABLE 0x0002 2 HOMEDIR_REQUIRED 0x0008 8 LOCKOUT 0x0010 16 PASSWD_NOTREQD 0x0020 32 PASSWD_CANT_CHANGE 0x0040 64 ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128 TEMP_DUPLICATE_ACCOUNT 0x0100 256 NORMAL_ACCOUNT 0x0200 512 把这些值转为二进制,你就清楚了 1 = 1; 2 = 10 4 = 100; 8 = 1000; 16=10000; 32=100000; 64 。。。。。。 只要和相应位 与运算,就可以得出结果 例如 求 ACCOUNTDISABLE if(accountdisable&0x2!=0) 禁用 else 启用
紫魂一号 2012-11-09
  • 打赏
  • 举报
回复
分析: N值有两种结果:奇数或偶数。凡是与1相加的必定为奇数,其他的相加则必定是偶数 if(N is 奇数) { N = N-1;..............//此时这个N必定是2的n次方的组合相加 } else if(N is 偶数) { .....//这个N也将是2的n次方相加 } ...至于大括号里要如何取处理还没想到。。。
  • 打赏
  • 举报
回复
需要修正一下,如果是任意的之和的话,上面只是顺序输出
private List<int> GetList(int sum)
            {
                List<int> list = new List<int>();
                for (int i = 1; i<sum; i *= 2)
                {
                    bool flag = (sum & i) != 0;
                    if (flag)
                    {
                        list.Add(i);
                    }
                }
                return list;
            }
  • 打赏
  • 举报
回复
上面的注释应该是
/*
                 * 1 2 4 8 16 32
                 */ 
  • 打赏
  • 举报
回复
private List<int> GetList(int sum)
            {
                List<int> list = new List<int>();
                for (int i = 1; ; i *= 2)
                {
                    bool flag = (sum & i) != 0;
                    if (flag)
                    {
                        list.Add(i);
                    }
                    else
                        break;
                }
                return list;
            }
调用
//调用
                List<int> temp=GetList(63);
                /*
                 * 1 2 4
                 */ 
游离失所 2012-11-09
  • 打赏
  • 举报
回复
没听懂啥意思...能不能直接点上例子...然后想得到的结果是什么
victo7 2012-11-09
  • 打赏
  • 举报
回复
这个就是一个关于“2”的问题
xuan.ye 2012-11-09
  • 打赏
  • 举报
回复
不等于2,并且取模不等于0不可以吗?

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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