zoukankan      html  css  js  c++  java
  • 循环遍历Java字符串字符的规范方法——类似python for ch in string

    比如我将string作为CNN 文本处理输入:

          float [] input = new float[maxLength]; // 1 sentence by maxLenWords
            // int[] input = new int[batchSize * maxLength]; // 1 sentence by maxLenWords
            int i = 0;
            final int length = subdomain.length();
            for (int offset = 0; offset < length; ) {
                final int codepoint = subdomain.codePointAt(offset);
    
                // do something with the codepoint
                if(vocabMap.containsKey(codepoint)) {
                    input[i] = vocabMap.get(codepoint);
                } else {
                    Log.e(TAG, "not found char in dict, check code point:" + codepoint + " subdomain:"+subdomain + " offset:" +offset);
                }
                i += 1;
                offset += Character.charCount(codepoint);
            }

    其中,vocabMap为词汇表。构建方法:

             Gson gson = new GsonBuilder().setPrettyPrinting().create();
                Type type = new TypeToken<Map<String, Integer>>(){}.getType();
                Map<String,Integer> tmpMap = gson.fromJson(json, type);
                vocabMap = new HashMap<Integer, Integer>();
                maxLength = tmpMap.get("__MAX_DOC_LEN__");
                volcabSize = tmpMap.get("__VOLCAB_SIZE__");
                for (String s: tmpMap.keySet()) {
                    if (getPointLength(s) == 1) {
                        vocabMap.put(s.codePointAt(0), tmpMap.get(s));
                    } else {
                        Log.e(TAG, "****Check dict key:" + s + " point:" + s.codePointAt(0) + " point lenth=" + getPointLength(s));
                    }
                }
                Log.e(TAG, "load dict OK. maxLength:" + maxLength + " volcabSize:" + volcabSize + " DictSize:" + (vocabMap.size()));        

    注意每一次迭代都是int。

    下面是详细解释:

    循环遍历Java字符串的字符的规范方法:

    final int length = s.length();
    for (int offset = 0; offset < length; ) {
       final int codepoint = s.codePointAt(offset);
    
       // do something with the codepoint
    
       offset += Character.charCount(codepoint);
    }
    http://stackoverflow.com/questions/1527856/how-can-i-iterate-through-the-unicode-codepoints-of-a-java-string
     

    Java 正确遍历字符串

    from:http://blog.csdn.net/l294265421/article/details/47281023
     

    Java字符串是一系列的Unicode字符序列,但是,它却常常被误认为是char序列。于是,我们经常这样来遍历字符串:

    1. package testchar;  
    2.   
    3. public class TestChar2 {  
    4.     public static void main(String[] args) {  
    5.         String s = "u0041u00DFu6771ud801uDC00";  
    6.         for(int i = 0; i < s.length(); i++) {  
    7.             System.out.println(s.charAt(i));  
    8.         }  
    9.     }  
    10. }  
    然后,得到了意料之外的结果:

    A

    ß

    ?

    ?

    之所以会这样,是因为Unicode字符和Java的char类型不能等同起来。实际上,Java中的char类型能表示的字符只是Unicode字符的子集,因为char只有16位,也就是说,它只能表示65536(2的16次方)个字符,但实际的Unicode字符数超过这个数字。在Java中,用UTF-16编码char和String中的字符,一个字符对应的编码值被称为一个代码点。有的代码点用16位编码,被称为一个代码单元,像char表示的那些字符;有的代码点用32位编码,也就是用两个连续的代码单元编码,如上文中的ud801uDC00。其实,我们遍历一个字符串,遍历的是这个字符串中所有代码点,而

    s.length()

    返回的是字符串s中代码单元的个数。当i对应的代码单元只是一个32位代码点的一部分时,

    s.charAt(i)

    也就不能像我们希望的那样工作了。
        package testchar;  
          
        /** 
         * 正确遍历String 
         *  
         * @author yuncong 
         *  
         */  
        public class TestChar {  
          
            public static void main(String[] args) {  
                String s = "u0041u00DFu6771ud801uDC00";  
                // 获得字符串中代码点的数量  
                int cpCount = s.codePointCount(0, s.length());  
                for (int i = 0; i < cpCount; i++) {  
                    int index = s.offsetByCodePoints(0, i);  
                    int cp = s.codePointAt(index);  
                    if (!Character.isSupplementaryCodePoint(cp)) {  
                        System.out.println((char) cp);  
                    } else {  
                        System.out.println(cp);  
                    }  
                }  
          
                System.out.println("-------------------");  
          
                for (int i = 0; i < s.length(); i++) {  
                    int cp = s.codePointAt(i);  
                    if (!Character.isSupplementaryCodePoint(cp)) {  
                        System.out.println((char) cp);  
                    } else {  
                        System.out.println(cp);  
                        i++;  
                    }  
                }  
                  
                System.out.println("-------------------");  
                  
                // 逆向遍历字符串  
                for(int i = s.length() - 1; i >= 0; i--) {  
                    int cp = 0;  
                    // 当i等于0的时候,只剩下一个代码单元,不可能是辅助字符  
                    if (i == 0) {  
                        cp = s.codePointAt(0);  
                        System.out.println((char)cp);  
                    } else {  
                        // 只有在i大于0的时候才可以退,并且  
                        // 因为剩下的代码单元大于2,所以接下  
                        // 来访问的两个代码单元可能表示辅助  
                        // 字符;  
                        // 退一个代码单元  
                        i--;  
                        cp = s.codePointAt(i);  
                        if (Character.isSupplementaryCodePoint(cp)) {  
                            System.out.println(cp);  
                        } else {  
                            // 如果cp不是辅助字符,就回到遍历的正常位置  
                            i++;  
                            cp = s.codePointAt(i);  
                            System.out.println((char)cp);  
                        }  
                    }  
                }  
                  
            }  
          
        }  
  • 相关阅读:
    面试题11:旋转数组的最小数字(C++)
    2019.9.20学习内容及随堂笔记
    2019.9.19学习内容及小结
    2019.9.18(day39)学习内容及小结
    2019.9.17学习内容及随堂笔记
    2019.9.16学习内容及随堂笔记
    2019.9.12(day36)学习内容及笔记
    2019.9.11学习内容及随堂笔记
    2019.9.10学习内容及随堂笔记
    2019.9.9学习内容及随堂笔记
  • 原文地址:https://www.cnblogs.com/bonelee/p/8474077.html
Copyright © 2011-2022 走看看