循環遍歷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序列。於是,我們經常這樣來遍歷字符串:

 

[java] view plain copy
  1. package testchar;  
  2.   
  3. public class TestChar2 {  
  4.     public static void main(String[] args) {  
  5.         String s = "\u0041\u00DF\u6771\ud801\uDC00";  
  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位編碼,也就是用兩個連續的代碼單元編碼,如上文中的\ud801\uDC00。其實,我們遍歷一個字符串,遍歷的是這個字符串中所有代碼點,而

s.length()

返回的是字符串s中代碼單元的個數。當i對應的代碼單元只是一個32位代碼點的一部分時,

s.charAt(i)

也就不能像我們希望的那樣工作了。
    package testchar;  
      
    /** 
     * 正確遍歷String 
     *  
     * @author yuncong 
     *  
     */  
    public class TestChar {  
      
        public static void main(String[] args) {  
            String s = "\u0041\u00DF\u6771\ud801\uDC00";  
            // 獲得字符串中代碼點的數量  
            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);  
                    }  
                }  
            }  
              
        }  
      
    }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM