字符串基本运用 与 位运算

原创 2018年04月16日 20:10:10
    应用层,更多的是对数据进行一些简单的处理,然后更新到UI上。如果对性能要求不高的情况时,只要不是太复杂的,动动脑子,基本都没问题。如果对性能要求较高时,就要动一番脑筋了。比如项目中有个简单的小功能。   
    场景介绍: 新闻类资讯,列表中每条新闻都会有一些标题,简介和标签,比如 暖文 广告 原创 专题 热门 置顶 等等标签,每条目中都要显示相对应的标签。
    刚开始每个标签只有三个,每个都用一个boolean 属性值代表。如果为true,则在ListView 的 item 上显示对应的标签,后来标签逐渐增多,有十多个,并且这些标签可以共存,客户端bean对应的属性也由3个增加到十多个,按照这个速度,如果有100个标签,岂不是要写100个属性,所以为了方便客户端和服务端,决定改变做法,用一个属性字段来标识所有属性值。
    如果每个item只显示一个标签或者不显示标签,我们可以定义数据,从0开始,0表示不显示,1对应 暖文,2对应 广告,3对应 原创 等等,依次类推,但是 我们这里标签是可以共存的,意思是说可能同时要显示 暖文  原创  热门 置顶 四个标签,这是都是不确定的,怎么办?回归到上面说的用一个字段表示所有属性,titleDisplay :"11010010" 。定义了一个常量,从右往左,每一位数字代表一个标签,1表示有该标签,0表示没有该标签,从右到左,依次为 暖文 广告 原创 专题 热门 置顶 等等。以后如果增加新的标签,往数据的左边补数据。所以,我们需要把该属性数据进行解析,获取1对应的位值,放到一个集合中,同时要做兼容处理,万一客户端返回数据由8位变为10位,老版客户端解析不能出错。拿到数据后,再根据数据值拿对应的标签。
    刚开始做的时候,用一般的方法。


    public static final String TEST_STR = "1111010010"; //  测试数据
    public static final int TITLE_DISPLAY_LENGTH = 8; //置顶热门等标签属性的字符串最小长度
    public static final int TITLE_DISPLAY_LENGTH2 = TITLE_DISPLAY_LENGTH - 1; //辅助值,标签属性长度小1
    public static final int TITLE_DISPLAY_FLAG = 49; //置顶热门等标签值为1,转换为字符值为49


    private static List<Integer> hotIndex = new ArrayList<>();




    private void signTitleDisplay(String titleDisplay) {
        if (!TextUtils.isEmpty(titleDisplay) && titleDisplay.length() >= TITLE_DISPLAY_LENGTH) {
            String newTitleDisplay = titleDisplay.substring(titleDisplay.length() - TITLE_DISPLAY_LENGTH);
            char[] stringArr = newTitleDisplay.toCharArray();
            for (int count = stringArr.length - 1; count >= 0; count--) {
                if (TITLE_DISPLAY_FLAG == stringArr[count]) {
                    hotIndex.add(TITLE_DISPLAY_LENGTH2 - count); // a
                }
            }
        }
    }
// 调用方法
signTitleDisplay(TEST_STR);

    把 titleDisplay :"11010010" 转换为字符数组,遍历每一个字符的值,比较值是否是 49, 因为字符表中字符1对应的值为49。为了兼容,防止出错,需要对titleDisplay 进行 非空判断 和 长度判断,如果长度大于8位,需要截取后八位,因为前面的数据是新加的。 堆数据判断截取后,转换为数组,然后遍历,如果等于1,则把索引添加到集合中。注意 a 步骤,对索引进行了一个小运算,因为字符串变为数组时遍历时,是从左往右的,而当初定需求时,是从右往左的,所以需要取倒,用数组索引的最后一位,减去当前的索引,添加的集合中。例子中集合中的值为 1 4 6 7。可以去拿对应的标签的。


    private void signTitleDisplay2(String titleDisplay) {
        char[] stringArr = titleDisplay.toCharArray();
        reverseArr(stringArr);
        for (int count = stringArr.length - 1; count >= 0; count--) {
            if ((TITLE_DISPLAY_FLAG == stringArr[count]) {
                hotIndex.add(count);
            }
        }
    }

    private void reverseArr(char[] arr) {
        if(arr != null){
            int start = 0, end = arr.length - 1;
            char t;
            while(start < end){
                t = arr[start];
                arr[start] = arr[end];
                arr[end] = t;
                start++;
                end--;
            }
        }
    }
    
    // 调用方法
    signTitleDisplay2(TEST_STR);

    方法2,原理一样,只是在获取到字符数组后,对数组数据进行了翻转,前后位置颠倒,这样,集合里添加索引时就不用取倒了。 
    下面再说一种位运算


    public static final int[] FLAG_ARR = {1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };

    private void signTitleDisplay3(String titleDisplay){
        int newTitleDisplay = Integer.valueOf(titleDisplay, 2);
        for (int i = 0, count = FLAG_ARR.length; i < count; i++) {
            int value = FLAG_ARR[i] & newTitleDisplay;
            if (value != 0) {
                hotIndex.add(i);
            }
        }
    }
    // 调用方法
    signTitleDisplay3(TEST_STR);


    由于 titleDisplay :"11010010" 为字符串,首先要转换为2进制,这点很重要,不要单纯的转换为数字,要2进制。然后看FLAG_ARR数组,简单说,值为 0000 0001, 0000 0010, 0000 0100, 0000 1000 等等,只写了数据的后八位。用 & ,对应位上面值都为1值才为1,否则为0。不明白的可以复习一下位运算。
 
    相比较而言,大量数据时,方法3更好。首先位运算很快,同时节省了一个数组的消耗,再次如果给的 titleDisplay 是10位,也不必去判断截取,应为FLAG_ARR 里面没写,为0;新版本只需要在FLAG_ARR数组里增加对应的新值就 行了,而 方法1和方法2,还需要去改动方法,对比之下,三更好。













php字符串位运算的一个小技巧

最近在做一个网站,采用utf-8编码,但在php中对字符串进行位运算目前没有较好的办法,目前有一个小技巧$str = "中文"; for ($i=0; $i...
  • u010091666
  • u010091666
  • 2016-09-11 16:14:38
  • 188

位运算/逻辑运算总结

判断a的二进制数中1的个数的奇偶性function(a:longint):longint; begin a:=a xor(a>>1); a:=a xor(a>>2); a:=a xor(...
  • slongle_amazing
  • slongle_amazing
  • 2015-12-10 11:47:55
  • 731

位运算与应用

一,位运算基础 位运算(包括与,或,取反,异或,左移,右移等)是程序设计中的一个重要的领域。尤其是安全和底层开发中,除了指针的频繁使用之外,位运算是另一个非常频繁使用的领域。 因此,在求职面试中...
  • u012713968
  • u012713968
  • 2016-01-08 11:34:26
  • 1078

[C++基础]位运算 游戏开发中的应用

位运算的定义:通俗点说,位运算就是对一个整数在计算机中二进制进行操作。 任何一个整数都可以用二进度的方式来表示的,不同类型的整数它的位数的长度也不一样,INT8或者char是由8个2进度 位表示,IN...
  • ouyangshima
  • ouyangshima
  • 2014-10-12 19:13:13
  • 1286

字符串包含 位运算法

/* description: 长字符串s1,和短字符串s2 判断s2是否是s1的子集。 字母都是大写。 是输出true 否输出false 使用位运算法,相当于...
  • XingKong_678
  • XingKong_678
  • 2016-03-10 19:26:24
  • 717

编程技巧--位运算的巧妙运用(1)

作者:yunyu5120                这是我的这一系列文章的第一篇,主要讲述我学习过程中积累的一些编程技巧,由于我也是一个初学者,高手莫笑。这一篇主要讲解位运算的基础知识鱼与其简单应...
  • yunyu5120
  • yunyu5120
  • 2011-08-16 20:48:12
  • 15929

【Java】利用位运算原来加密可以很简单

通过位运算的“^”异或运算符把字符串与一个指定的值进行异或运算,从而改变字符串每个字符的值,这样就可以得到一个加密后的字符串。当把加密后的字符串作为程序输入内容,异或运算会把加密后的字符串还原为原有字...
  • hj7jay
  • hj7jay
  • 2017-02-16 11:10:05
  • 1689

java位运算及其四则表示

java位运算--博客园 一,Java 位运算  1.表示方法: 在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。  (1)正数的最高...
  • chx0501
  • chx0501
  • 2016-03-08 10:44:37
  • 441

基本数据类型 运算符 类型转换

浮点类型:     float   4字节   单精度       double  8字节   双精度  范围大 准确度高     Java中所有的小数默认都是double,除非有单精度标志符(f)如...
  • liusichen1204
  • liusichen1204
  • 2017-06-23 21:44:07
  • 153

位运算(篇1)不使用任何其他的数据结构检查一个字符串中是否有重复字符

实现空间有效算法以确定(从‘a’到’z’的字符)字符串是否具有所有唯一字符。不允许使用数组,散列等附加数据结构。 时间复杂度:O(n)思路: 因为从‘a’-‘z’共有26个字符,一个int有32位...
  • u013309870
  • u013309870
  • 2017-03-17 10:59:02
  • 417
收藏助手
不良信息举报
您举报文章:字符串基本运用 与 位运算
举报原因:
原因补充:

(最多只允许输入30个字)