热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

枚举类型表示组合状态的抽象代数原理

可以使用枚举类型定义位标志,从而使该枚举类型的实例可以存储枚举数列表中定义的值的任意组合。(当然,某些组合在您的程序代码中可能没有意义或不允许使用。)System.FlagsAttribute

可以使用枚举类型定义位标志,从而使该枚举类型的实例可以存储枚举数列表中定义的值的任意组合。 (当然,某些组合在您的程序代码中可能没有意义或不允许使用。)

System.FlagsAttribute attribute and defining the values appropriately so that AND, OR, NOT and XOR bitwise operations can be performed on them.">创建位标志枚举的方法是应用 System.FlagsAttribute 特性并适当定义一些值,以便可以对这些值执行 ANDORNOT 和 XOR 按位运算。 在位标志枚举中包含一个值为零(表示“未设置任何标志”)的命名常量。如果零值不表示“未设置任何标志”,则请不要为标志指定零值。

首先我们定义一个支持组合状态的枚举如下,用FlagsAttribute对定义的枚举类型进行标识:

    [Flags]
    public enum Permission
    {
        NOne=0,
     Create
=1, Retrive=2, Update=4, Delete=8, All=Create|Retrive|Update|Delete, }

FlagsAttribute标签的意义是按照位域来处理此枚举类型:

/// Indicates that an enumeration can be treated as a bit field; that is, a set of flags.
    /// 1
    [AttributeUsage(AttributeTargets.Enum, Inherited = false), ComVisible(true)]
    [Serializable]
    public class FlagsAttribute : Attribute
    {
    }

通常我们对组合的枚举类型的操作为:

1.检查组合中是否包含某个值 2.往组合中添加一个值 3.从组合中去掉某个值

我们定义上面三种操作如下:

 public static class PermissionExtention
    {
        public static bool HasPermission(this Permission compositePermission, Permission verifiedPermission)
        {
            return (compositePermission & verifiedPermission) == verifiedPermission;
        }

        public static Permission AddPermission(this Permission compositePermission, Permission toAddPermission)
        {
            if (compositePermission.HasPermission(toAddPermission))
                return compositePermission;
            else
                return compositePermission | toAddPermission;
        }
        public static Permission RemovePermission(this Permission compositePermission, Permission toRemovePermission)
        {
            //if (!compositePermission.HasPermission(toAddPermission))
            //    return compositePermission;
            //else
                return compositePermission & (~toRemovePermission);
        }
        public static Permission RemovePermission2(this Permission compositePermission, Permission toRemovePermission)
        {
            if (!compositePermission.HasPermission(toRemovePermission))
                return compositePermission;
            else
                return compositePermission^toRemovePermission;
        }
    }
 
我们注意到我们使用了全部四种操作符:& ,|,^,~来是想上面的三种目的。直观上理解三个操作符的意义就是

x & y 整型按位“与”

x ^ y 整型按位“异或”

x | y 整型按位“或”

~x按位求反

RemovePermission 与 RemovePermission2 这两个方法需要说明一下,其中RemovePermission形式比较简单,一句代码搞定

compositePermission & (~toRemovePermission);

对待删除的元素按位取反之后,按位与,直接表示保留除了toRemovePermission之外的其它所有权限。

RemovePermission2形式更加好理解,但是容易出错。如果没有第一句的判断直接异或操作的话可能会把原来没有的权限加进去。


数学原理:抽象代数之二进制码词群

设w=a1a2...an是一个n位二进制数码,称为一个码词,S是所有这样的码词构成的集合,即S={a1a2...an|ai=0或1,i=1,2,...n}

在S中定义二元运算|表示位运算按位或

 所以我们把原来的枚举类型换成数学符号如下

NOne=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000,All=1111

由四位二进制数组成的二进制码集合为S={a1a2a3a4|ai=0或1},即所有的可能权限组合组成此集合。
对于我们定义的运算|,显然在此集合上满足封闭性,结合律,另外单位元为NOne=0000

同时所有元素的逆元也为NOne=0000。

所以集合S构成一个群(S,|),并且满足交换律,所以也是Abel群。

并且最小生成元集为M={NOne=0000,Create=0001,Retrive=0010,Update=0100,Delete=1000}

所以所有的权限组合均可以由M中的元素生成。

下面来分析下前面代码中的各种运算符的数学集合意义,a表示一个二进制码词

~:  表面上是求元素a的的按位求反,实际在集合中的意义是除去a元素的的其它所有元素的集合。

&:  按位与运算,在集合中的a&b的意义就是求a中的权限与b中权限的交集

^:  异或“^”运算相当于 a^b 相当于{权限x|x属于a,但x不属于b}U{权限y|y属于b,但不属于a}

|:  或运算“|”,在这里相当于是并运算,即集合得合并运算。

再回头看代码:

取得权限的交集,判断权限中是否包含verifiedPermission

public static bool HasPermission(this Permission compositePermission, Permission verifiedPermission)
        {
            return (compositePermission & verifiedPermission) == verifiedPermission;
        }

添加权限,取集合的合并结果

 public static Permission AddPermission(this Permission compositePermission, Permission toAddPermission)
        {
            if (compositePermission.HasPermission(toAddPermission))
                return compositePermission;
            else
                return compositePermission | toAddPermission;
        }

删除一个权限,原权限集合与集合(~toRemovePermission)的交集,其中(~toRemovePermission)这个集合表示toRemovePermission的补集。

 public static Permission RemovePermission(this Permission compositePermission, Permission toRemovePermission)
        {
            //if (!compositePermission.HasPermission(toAddPermission))
            //    return compositePermission;
            //else
                return compositePermission & (~toRemovePermission);
        }

删除一个权限第二种方法.其中else之后的语句表示一个并集:{权限x|x属于compositePermission,但x不属于toRemovePermission}U{权限y|y属于toRemovePermission,但不属于compositePermission}

 public static Permission RemovePermission2(this Permission compositePermission, Permission toRemovePermission)
        {
            if (!compositePermission.HasPermission(toRemovePermission))
                return compositePermission;
            else
                return compositePermission^toRemovePermission;
        }

 

我们可以用枚举类型的此种用法实现程序中的状态组合,任务状态组合,权限管理组合等。

作者:Andy Zeng

欢迎任何形式的转载,但请务必注明出处。

http://www.cnblogs.com/andyzeng/p/3723278.html


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
author-avatar
手机用户2602915451
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有