SiteMap

2013年4月26日金曜日

檢查字串中 xxx 出現了多少次


/* 目標:檢查字串中 xxx 出現了多少次


 *
 * 情境:有一個字串裡面都是英文字, 請檢查a-z各出現多少次
 * 方法1
 * 將字串裏頭的字元取出, 然後檢查他的ASCII值,
 * ASCII值符合的話, 該ASCII值的計數+1
 *
 * 取巧的方法, 因為英文字母的ASCII碼是連續的26個int
 * 大寫26個, 小寫26個, 共52個
 * 因為是連續的int, 所以可以用for去宣告
 *
 */
public class IO_StringSearch {
static String strTemplate = "a1111";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// new IO_StringSearch().Q1fix(strTemplate);
new IO_StringSearch().Q2(strTemplate);
}

public void Q1(String strInput){
/* 宣告一個int陣列共有27個元素
* 並初始化元素為0
*/
int []count = new int[27];
for (int i = 0; i < count.length; i++) {
count[i]=0;
}
/* 基本概念
* 當 取出的字元 為 a 的時候
* count[a]++
* a的ASCII碼為97
* 所以上面可以替換為
* 當 取出的int為 97 的時候
* count[97]++ //這裡的意思是陣列count第97個元素其值++
*
* 光計算小寫a出現多少次,陣列就要至少宣告到97!!
* 好吧, 減掉97的話, count[a]就會等於count[0]
* 接下去到z不就只要宣告一個長度26的陣列
* 所以...
* 當取出的字元為a 的時候
* count[(int)a-97]++
*
* a是我們從一個字串裡面取出來的單一字元,
* 所以如果把a用char變數(姑且就命名為cx吧)取代的話..
* 當取出的字元為cx的時候
* count[(int)cx-97]++
*
* 而字串本身就是一個字元陣列
* 所以...
* 假設傳入的字元陣列為ch[]
* 把cx換成ch[i], i為從1到字元陣列長度任意一個數
* ex: 一個字串的長度為4, "abcd", 那麼他所構成的字元陣列
* 就是4, char[] ch = {'a','b','c','d'};
* 所以...
* 當取出的字元為ch[i]的時候
* count[(int)ch[i]-97]++
*
* 到了這裡, 除了作為基準用的-97以外,
* 檯面上的值已經換成了變數, 實作!!
*/
/* strInput.toCharArray(), 把字串strInput轉變為一個字元陣列
 * .length 長度
 * 他是這樣變化的
 * 01 strInput.toCharArray().length
 *    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 * 02 char[].length  //char[]表示匿名字元陣列
 *    ¯¯¯¯¯¯
 */
for (int i = 0; i < strInput.toCharArray().length; i++) {
/*
* 當i=0的時候, 取出strInput第一個位置的字元
* 將其轉為int, 再減掉97, 然後陣列count相對應位置的元素計數+1
* ex:
* 當i=0的時候, 字串strInput的第一個位置的字元為b
* 將b轉為int, 其值為98, 減掉97, 結果為1
* 則 count[1] = count[1] + 1
* 簡寫為 count[1]++
*
* 代表意義為字串strInput到第一個字元位置為止, b出現了1次
*/
char[] ch = strInput.toCharArray();
count[(int)ch[i]-97]++;
/* 不過String本身就有提供方法
* strInput.length() - 回傳strInput的長度
* strInput.charAt(i) - 回傳strInput內位於i位置的字元
* 所以這個forloop可以改寫成 ... 請看Q1fix()
*/
}
}
/* 修改過的Q1
* 這樣只能計算a-z, 萬一有a-z以外的符號呢 {}|)(_+ 都有可能會出現在字串中
* 詳細的先不討論, 直接排除吧
*/
public void Q1fix(String strInput){
int count[] = new int[27];
for (int i = 0; i < strInput.length(); i++) {
/* 把範圍限制在a-z(97-122)之間
* 而其他符號的計數則算在一起
*/
if ((int)strInput.charAt(i)>=97 && (int)strInput.charAt(i)<=122) {
count[(int)strInput.charAt(i)-97]++;
} else {
count[26]++;//注意這裡不是27而是26
}
}
dpg(count);//輸出
}
/* 好吧, 其實Q1fix只能計算小寫的a-z
* 如果source裡面含有大寫的A-Z呢?
* 在Q1fix裡面會全部歸到count[26]裡面 (汗)
*
* 全部轉成大寫或者小寫
*
* 大寫計算一遍, 小寫計算一遍, 然後
* 用  count[]++
*
*/
public void Q2(String strInput){
int count1[] = new int[27];
int count2[] = new int[27];
for (int i = 0; i < strInput.length(); i++) {
if ((int)strInput.charAt(i)>=65 && (int)strInput.charAt(i)<=90) {
count1[(int)strInput.charAt(i)-65]++;
} else if ((int)strInput.charAt(i)>=97 && (int)strInput.charAt(i)<=122) {
count2[(int)strInput.charAt(i)-97]++;
} else {
count1[26]++;
}
}

for (int i = 0; i < count2.length; i++) {
count1[i] += count2[i];
}
dpg(count1);
}


/* 輸出用
*
* 為了美觀, 每5個 x[y] 斷行 一次
* 陣列最後一個拿來塞其他符號的計數另外用一行
* Other[y]來表示
*
*/
public void dpg(int[] count){
System.out.println("各個英文字母的出現次數:");
for (int i = 0; i < count.length; i++) {
if (i != count.length-1) {
System.out.print((char)(i+97)+"["+count[i]+"] ");
} else {
System.out.print("\nOther "+"["+count[i]+"]");
}
if (i%5==4) {
System.out.println();
}
}
}
}

直接到http://pastebin.com/TSQRHJKZ看程式碼

0 件のコメント: