2013年7月31日 星期三

反轉字串Array.Reverse

本章將示範 如何 反轉字串
林哲健

健哲林

在順便練習利用StringBuilder來輸出

來看程式碼!

private void txt_input_TextChanged(object sender, EventArgs e)
       {
            char[] P_chr = txt_input.Text.ToCharArray();//從字串中得到字節陣列
            Array.Reverse(P_chr, 0, txt_input.Text.Length);//反轉字節陣列
                        //陣列物件,起始,反轉的數量
            txt_output.Text = //將字節陣列轉換為字串並輸出
                //字串使用StringBuilder().Append(string) 輸出
                new StringBuilder().Append(P_chr).ToString();
        }


本章也沒啥好說的 註解就可以解釋一切

不浪費記憶體的StringBuilder

前一章節中了解了字串是不可改變的物件
我們知道 頻繁使用字串 更換字串
字串只是不段指向新的記憶體位置
而原本的記憶體位置將會造成,垃圾收集器的負擔

如果系統龐大 將會消耗很多記憶體即造成垃圾收集器的壓力

在這邊可以使用StringBuilder來操作字串
也不會產生新的字串物件

下面來示範 使用StringBuilder玩弄字串

private void btn_true_Click(object sender, EventArgs e)
        {
            StringBuilder P_stringbuilder = //建立字串處理對像
                new StringBuilder(txt_string.Text);
            for (int i = 0; i < P_stringbuilder.Length; i++)//開始循環
                if (P_stringbuilder[i] == ',')//判斷是否出現(,)號
                {//找到","在指定的字元位置上將指定物件的字串表示插入這個執行個體。
                    //插入換行Environment.NewLine
                    P_stringbuilder.Insert(++i,//向字串內新增換行符
                        Environment.NewLine);
                }
            //得到分行後的字串
            txt_Lines.Text = P_stringbuilder.ToString();
            bool P_bl = "abc" == "abc";
            MessageBox.Show(P_bl.ToString());
        }


活用StringBuleder將可以解決記憶體浪費的問題

VB.NET 變數Value & Reference 探討記憶體交換

本文章 簡單易懂 我就一字不漏剪下貼上拉
本文出處


蠻有趣的議題 ...(我個人認為啦)
相信大家都知道 ...在新版本的高階語言
有關於 Reference 型態的變數 String Array Decimal
String 字串 都是不可改變的
所以 再做連結、更改字串的動作是非常的耗費記憶體 ...
怎麼說呢 ... 簡單來講好了

1 Dim s as String = "測試用文字"
2 s += "新增的文字"
非常簡單的兩行
學問可大了 ...
首先 .NET 會跟Windows老大要一個 記憶體空間
Windows 會給.NET一段記憶體位址 (0x????????) 的記憶體堆疊位址(heap) 代號為 s(基本上學 C++的會比較懂這個)
然後 把"測試用文字" 放到這段 記憶體位址裡面(一字2Byte 所以總共佔了10Byte
s所儲存的 是 (假設 0x2c000001) 而不是直接儲存文字
第二行相信大家都沒有問題 ... 把s 原本的值 在接上 "新增的文字" 這五個字 結果會是 "測試用文字新增的文字"
可是 這背後 .NET 到底做了什麼呢!? ..
由於新版高階語言的規定,字串是不得改變的
所以 再做字串連結的時候 .NET 會先要一段記憶體 來存放 "新增的文字" (10Byte)(假設是 0x7a010368)
然後 再把兩個字串做連結 ... 由於字串不得改變的原理 ...
.NET 會在要另一個記憶體位址 (假設0x99asd217) 再把上面 "測試用文字新增的文字" 放到這個記憶體位址裡面(20Byte)
然後 再把 0x99asd217 給 s
光是做一個這麼簡單的動作 ... 總共就使用了40Byte 而且在40Byte裡面還有 20Byte 的記憶體是浪費掉的 ...
如果有興趣做實驗 以下有個小小的試驗 ...

1 Dim Watch As New Stopwatch
2 Watch.Start()
3 Dim s As String = ""
4 For x As Integer = 0 To 100000
5 s += x.ToString() & Environment.NewLine()
6 Next
7 Watch.Stop()
8 Dim i As Integer = Watch.ElapsedMilliseconds / 1000
9 Watch.Reset()
做 10萬字 連字串 ...
基本上 測試過 至少都要1分鐘左右以上電腦比較慢的 甚至要到5分鐘 ...
而且 在工作管理員裡面 會發現 實體記憶體慢慢的再被吃掉 ...
好了 以上只是一個小小的測試 ...
基於上面這個原理 ...
來看我們下面的例子
1 Dim s1 As String = "測試用文字"
2 Dim s2 As String
3 s2 = s1
4 s2 = "新增的文字"

這段程式 執行出來之後 ... s1 和 s2 各會是多少呢?
別急 先想一想再看答案 ...
答案

神奇嗎...
再來一個更神奇的 ..
1 Dim i As Integer() = New Integer() {90, 80, 70, 60, 50}
2 Dim j As Integer()
3 j = i
4 j(0) = 10
5 j(1) = 20

執行的結果是什麼呢 ??
i 陣列 五個值是多少? j陣列 五個值是多少?
一樣 先思考一下 再看答案囉 ...
答案
再來 用 Value 型態的
value 型態的變數 如 Integer Char Byte 等等 ...
是直接儲存再記憶體data.bss 而不是heap
所以 在我們宣告以下
1 Dim i As Integer = 10
2 Dim j As Integer
3 j = i
4 j = 20

這邊 應該不難理解 ...
i 出來會是 10
j 出來 會是 20
因為 他們都是再同一個記憶體區段 ...
第三行 j = i 是把 i的值(10) Copy 給 j
所以 記憶體內 有 i = 10 , j = 10
再來 我把 j 指定為 20
就變成了 i = 10 , j = 20 是 不會互相引響的~
以上 ...
Phoenix 8/7
DotBlogs Tags: .NET

2013年7月29日 星期一

中文轉羅馬拼音 完整示範



在製作 中文轉羅馬拼音之前 必須先了解其中的原理!
當我們再輸入 鍵盤同時 將傳送一組 字串
比如說  要將 林哲健 轉成 羅馬拼音

首先收到這組字串 林哲健
在個別將國字 做比對 林=xup6  哲=xup6 健=ru04
再用這組字串 轉換成注音 變成 ㄌ一ㄣˊ  ㄓㄜˊ ㄐㄧㄢˋ
再將注音 正規化 去除 ˇ ˋˊ ˙
 然後 開始比對 注音 將得到羅馬拼音
ㄌ一ㄣ= LIN
ㄓㄜ    =je
ㄐㄧㄢ=Jian

那麼 中文字 10萬多個字 及 很多種比對資料
甚至更多 我們要如何將資料
有效率的存取與調用呢??
這時就 必須使用到 SQL 資料庫

在收集資料 比較痛苦一點
網路上雖然有很多 羅馬拼音 與 注音的 資料表
但是卻很少 英文 與注音 的比對的資料表
這裡可能要辛苦找一下

接下來資料有了 整理成一個 Access檔
 Access檔 裡面有三個 資料表 我大概 講解一下

第一個  字轉Key 有國字 及 鍵盤碼
比如   尺   = t3 建=ru04 帥=gj94

第二個  符號轉注音 有 符號 與 注音
比如    1= ㄅ  Q=ㄆ A=ㄇ

第三個 注音轉拼音  有注音 與 羅馬拼音
比如 ㄌ一ㄣ= LIN    ㄓㄜ =je   ㄐㄧㄢ=Jian

簡單來說 我們只是把 資料 輸入進去 經由 比對 再把結果送出
原理就這麼簡單!!
儘管簡單 收集資料卻很痛苦 不過做完很有成就感  !
開始來看範例吧


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Data;
using System.Data.OleDb;
namespace ChineseToABC
{
    public partial class Frm_Main : Form
    {
        //首先 建立 全域的connection連線物件
        OleDbConnection conn = new OleDbConnection
                (//連線物件+來源
                "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + "中文轉羅馬.accdb"
                );
        //再來 建立 全域性的 SQL查詢指令字串
        string SelectCmd;
        //存放比對結果的字串
        string re = "";// 存放 輸入的英文+符號數字
        string OKGO = "";//存放 注音
        string STAR = "";//存放 羅馬拼音

        public Frm_Main()
        {
            InitializeComponent();
        }

     




來看上列程式碼 一樣 註解 已經 很清楚了!
基於備忘 還是在特別說一次好了
首先!!
程式啟動同時 會先 宣告 全域物件
為了要多次比對字串 為了方便
宣告全域 資料庫connection連線物件 conn
SQL指令需要多次變化也宣告全域selectedCmd
以及 三個 字串 存放 羅馬 注音 與 英文字
如果像是 中文名子三個國字以上
由於資料庫國字是個別處理 全域的字串可以方便累加上去


在事件觸發之前  先講解一下 視窗控制元件 防備忘
三個  label1~3 分別為 1英文字符號 2注音 3羅馬
一個 textbox1 輸入中文用
一個 BUTTON2 觸發用

OK! 假如現在 在 textbox1 中 輸入:林
按下 BUTTON2
來看下列程式碼!

private void button2_Click(object sender, EventArgs e)
        {
            re = "";  //清除上一次使用的字串
            OKGO = "";//清除上一次使用的字串
            STAR = "";//清除上一次使用的字串
            if (textBox1.Text != string.Empty)//判斷是否空直
            {
                GO(textBox1.Text);//呼叫副程式(帶摻數)
            }
            else
            {
                MessageBox.Show("請輸入中文字");
            }
        }
s sss

re okgo star 這些字串 先歸零 因為 上一次 觸發 字串中還殘留 收尋結果
if (textBox1.Text != string.Empty)判斷是否是空值
不是直接呼叫 GO(textBox1.Text)副程式
並且 帶入剛剛在textBox1.Text輸入的中文

再來 來看 GO() 副程式 如何運作

private void GO(string x)
        {
            for (int i = 0; i <= x.Length - 1; i++)
            {
                conn.Open();//開啟資料庫
                //string SelectCmd2="Select*form 注音轉符號 Whrer 符號='"++"'";
                SelectCmd = "Select*from 字轉KEY Where 字='" + x[i] + "'";//設定查詢語法並加入輸入的中文x
                //將查詢x那一列的所有資料
                OleDbCommand Cmd = new OleDbCommand(SelectCmd, conn);//建立命令加入 語法+連線物件
                OleDbDataReader reader = Cmd.ExecuteReader();//ExecuteReader()是將Command查詢語法傳入connection中
                while (reader.Read())
                //OleDbDataReader 的預設位置在第一個資料錄之前。因此,您必須呼叫 Read 以開始存取任何資料。
                {
                    re += reader["欄位2"].ToString()+"  ";
                    TOTO(reader["欄位2"].ToString());
                }
                label1.Text = "你輸入的KEY是:" + re;
                conn.Close();
            }
        }


來看GO(string x)中的x
是剛剛輸入的textBox1.Text
而第一個 for (int i = 0; i <= x.Length - 1; i++)
是要來判斷 幾個國字 方便 個別搜尋資料庫 假設只有一個字"林"
conn.Open();
再來開啟在全域宣告的資料庫
SelectCmd = "Select*from 字轉KEY Where 字='" + x[i] + "'";
將x[0] 帶入 查詢第一個字 假設是"林"

OleDbCommand Cmd = new OleDbCommand(SelectCmd, conn)
建立命令物件  他需要 命令物件+連線物件

OleDbDataReader reader = Cmd.ExecuteReader()
再來將 命令 傳送給 連線物件 再指派給OleDbDataReader 讀取用

while (reader.Read())
                {
                    re += reader["欄位2"].ToString()+"  ";
                    TOTO(reader["欄位2"].ToString());
                }

reader.Read此方法 為 是否讀取到資料   裡面有資料將回傳 true
re是將 查詢到的資料 的隔壁叫(欄位2)裡的值放入re中
欄位一是:"林" 欄位二是: "XUP6"
而 (累加)+= 是因為 如果 有1個字以上 將會累加到re上
最後再把re 給label!!

再來 TOTO(reader["欄位2"].ToString()); 將查詢結果
再次呼叫副程式!
而本程式週期 因再次呼叫了 副程式
所以要等TOTO()執行完回傳 數據
才能將 此區塊結束!!

注意喔!! 此區況 尚未結束 所以
label1.Text = "你輸入的KEY是:" + re;
                conn.Close(); 
這部分 都尚未執行!!

再來我們來看TOTO()中 做了甚麼處理
我們知道TOTO(reader["欄位2"].ToString());
帶入的參數 是一組 林的 "XUP6" key碼
而在TOTO() 裡面只是將 key轉成 注音 而已
來看下列程式碼!

private void TOTO(string s)
        {
            string yy = "";
            char[] arr = s.ToCharArray(0, s.Length);
            foreach (char c in arr)
            {
                SelectCmd="Select*from 注音轉符號 Where 符號='"+c+"'";
                OleDbCommand Cmd = new OleDbCommand(SelectCmd, conn);
                OleDbDataReader reader = Cmd.ExecuteReader();
                while (reader.Read())
                {
                    yy += reader["注音"];
                }
            }
            OKGO += yy+"  ";
            label2.Text = "你輸入的注音是:" + OKGO;
            end(yy);

        }





來看 TOTO(string s)
"s"是剛剛傳入的 "XUP6"
再來為了將每一個字元做 資料庫獨立搜尋
我們利用ToCharArray 將字串 放進 char[]陣列中
s.ToCharArray(0, s.Length);
s是字串0是起始位置 S.Length是 s字串長度
然後轉成char

然後 再利用foreach (char c in arr)
將arr[]陣列 放進c
在來 foreach區塊內
修改全域的SQL指令 SelectCmd  將c套入指令中!
SelectCmd="Select*from 注音轉符號 Where 符號='"+c+"'";
再來 建立OleDbCommand 和 OleDbDataReader
OleDbCommand Cmd = new OleDbCommand(SelectCmd, conn);
OleDbDataReader reader = Cmd.ExecuteReader();

然後一樣 reader.Read() =true 啟動!
while (reader.Read())
{
yy += reader["注音"];
}

然後在foreach區塊內 C[]會不斷變化
使得while區塊內的yy會不斷累加!!
直到 將字元完整收巡完畢 才跳出區塊
來看剩下的程式碼
OKGO += yy+" ";
label2.Text = "你輸入的注音是:" + OKGO;
end(yy);

將查詢結果 累加OKGO 
為何累加?  因為 TOTO(string s)只將一子字轉成注音
等等還會有第二個字 第三個字 送入這TOTO()
全域的OKGO 將會 把結果累加成一個完整的 名子
label2 將答案顯示
end(yy) 將注音 傳送給!第三個副程式
再來我們來看看end(yy) 中的程式碼
是如何轉 羅馬拼音的


private void end(string er)
        {
            string pattern = "[ˇˋˊ˙]";//把ˇˋˊ˙濾掉
            string replacement = "";//如果找到ˇˋˊ˙替代成空字元
            Regex rgx = new Regex(pattern);//建立正規化 套入pattern過濾條件
            string result = rgx.Replace(er, replacement);//er是注音result是已將ˇˋˊ˙濾掉的字串

            SelectCmd = "Select*from 注音轉拼音 Where 注音='" + result + "'";
            OleDbCommand Cmd = new OleDbCommand(SelectCmd, conn);
            OleDbDataReader reader = Cmd.ExecuteReader();
            while (reader.Read())
            {
                STAR += reader["羅馬拼音1"]+"  ";
            }
            label3.Text = "轉羅馬的英文是:" + STAR;
        }


sas as a

string er是上一個副程式 所搜尋的結果 是注音
但是 資料庫中 比對的注音 並無ˇˋˊ˙
所以我們在這邊需要用到一個 過濾方法
叫做 正規化
原理是將 ㄌ一ㄣˊ 轉成 ㄌ一ㄣ
然後再比對資料庫
此 副程式 只有多了正規化 其他都 大同小異
後續不做介紹
此程式結束後 將 遞迴到GO()
而TOTO()已經運算結果回傳完畢 跳出區塊
關閉資料庫 CONN.CLOSE
在跳出 FOR迴圈
如果FOR迴圈中的X還有其他字元 將會在執行一次上續動作
private void GO(string x)
{
for (int i = 0; i <= x.Length - 1; i++)

直到i=字元長度 中指for迴圈



完!

2013年7月28日 星期日

中文轉拼音與Regex isMatch ToCharArray 運用

此程式為範例 中文字轉 羅馬  的效果 稱不上準確
而且資料不夠準確+完整 所以這範例只能讓使用者
知道運行原理  下一章將會補上 "中文轉羅馬的完整程式"
首先 先在 windows 設計模式 加入 2個 textbox
一個用於輸入文字叫 txt_Chinese
一個用於輸出文字叫 txt_PinYin

為了讓使用者 在輸入時 觸發!
因次我們必須讓 txt_Chinese這控制項觸發事件為TextChanged

Ps:在設計模式中 可以點選txt_Chinese然後右下角 有一個閃電
       並且挑選 需要的觸發事件 即可


因此我們就可以在每次輸入文字時 同時觸發程式!
來看程式碼吧!

 private void txt_Chinese_TextChanged(object sender, EventArgs e)
       {
           //呼叫PinYin.cs檔的GetABC方法並且帶入使用者輸入的"字"
            txt_PinYIn.Text = //呼叫拼音類的GetABC方法得到拼音字串
                new PinYin().GetABC(txt_Chinese.Text);
        }


當使用者開始輸入文字到txt_Chinese時將會觸發TextChanged事件
而我們由這事件的觸發 開始程序!
來看程式區塊中txt_PinYin.Text= new PinYin().GetABC(txt_Chinese.Text)
txt_PinYin.text輸出的結果
等於PinYin.cs檔案中的方法叫GetABC(?)
而GetABC(txt_Chinese.Text)
將傳送txt_Chinese.Text字串給 GetABC

接下來我們來瞧瞧使用者在txt_Chinese輸入的中文 送入GetABC(txt_Chinese)
會發生啥事  

看程式碼吧

 public string GetABC(string str)//str=控制項中的txt_Chinese.Text
    {
        //先宣告正規化 條件式驗證輸入是否為中文字
        Regex reg = new Regex("^[\u4e00-\u9fa5]$");//  \u4e00~\u9fa5是unicode中文範圍
        byte[] arr = new byte[2];//定義2byte字 節陣列 等等要存放unicode的
        string pystr = "";//定義字串變數用於返回拼音
        char[] mChar = str.ToCharArray();//取得中文字對應的字符陣列unicode 16bit會轉成10進位以char呈現
        return GetStr(mChar, pystr, reg, arr);//返回取得到的中文字拼音
    }

其實 註解已經 很清楚了 str是txt_Chinese
首先 建構 正規化Regex 函式 並且將要比對的規則運算式模式 套入方法中
Regex reg = new Regex("^[\u4e00-\u9fa5]$");
而字串中的\u4e00-\u9fa5 代表unicode中文範圍
正規化 將用來比對 使用者輸入是否是個中文字

再來宣告 byte陣列 2個  待會是要將中文的big碼
16Bit已各分8bit存入 byte中

二來
string pystr 是要將最終答案的結果回傳給初始呼叫副程式的地方

三來
char[] mChar = str.ToCharArray();
char 字元陣列利用ToCharArray()取str一個字元 並且陣列存入
如果str有兩字元 講會有 兩個char陣列

最後
return GetStr(mChar, pystr, reg, arr)
return 回傳給 TextChanged事件中 呼叫的副程式
但是
return 回傳是一個GetStr副程式
所以必須將GetStr裡的程序跑完才能回傳給TextChanged事件中的
GetABC(txt_Chinese.Text)
注意看 GetStr(mChar, pystr, reg, arr)方法中帶入的參數
我們下一段將介紹GetStr中的程序 
來看下面GetStr()程式碼

private string GetStr(char[] mChar, string pystr, Regex reg, byte[] arr)
    {
        int asc = 0, M1 = 0, M2 = 0;//宣告3個整數
        for (int j = 0; j < mChar.Length; j++)//mChar.Lenth看有幾個字char
        {
            if (reg.IsMatch(mChar[j].ToString()))//reg正規化條件中mChar的字是否府和unicode中文字範圍內
            {
                //假如mChar[j] = 陳, unicode 是38515  big 是B3AF  ,big碼將分成2位元組=179.175
                arr = System.Text.Encoding.Default.GetBytes(mChar[j].ToString());
                M1 = (short)(arr[0]);
                M2 = (short)(arr[1]);
                asc = M1 * 256 + M2 - 65536;
                if (asc > 0 && asc < 160)
                {
                    pystr += mChar[j];//條件相符直接印到pystr
                }
                else//不然 再進行選識
                {
                    switch (asc)
                    {
                        case -9254:
                            pystr += "Zhen"; break;
                        case -8985:
                            pystr += "Qian"; break;
                        case -5463:
                            pystr += "Jia"; break;
                        case -8274:
                            pystr += "Ge"; break;
                        case -5448:
                            pystr += "Ga"; break;
                        case -5447:
                            pystr += "La"; break;
                        case -4649:
                            pystr += "Chen"; break;
                        case -5436:
                            pystr += "Mao"; break;
                        case -5213:
                            pystr += "Mao"; break;
                        case -3597:
                            pystr += "Die"; break;
                        case -5659:
                            pystr += "Tian"; break;
                        default://casw 條件不府 再進行下列 比對
                            for (int i = (getValue.Length - 1); i >= 0; i--)
                            {   //比對(getValue[i]陣列中 有無小於或等於asc
                                if (getValue[i] <= asc)//判斷中文字的拼音區編碼是否在指定範圍內
                                {
                                    //比對成功的i值 直接對應getStr[i]中的答案 最後 印出
                                    pystr += getStr[i];//如果不超出範圍則取得對應的拼音
                                    break;
                                }
                            }
                            break;
                    }
                }
            }
            else//如果不是中文字
            {
                pystr += mChar[j].ToString();//如果不是中文字則返回
            }
        }
        return pystr;// 最後 回傳pystr給txt_PinYIn.Text
    }




一開始 for (int j = 0; j < mChar.Length; j++)
 迴圈中來判斷mChar幾個字

if (reg.IsMatch(mChar[j].ToString()))
是使用正規化來Match判斷mChar[j]是否是一個中文字元

條件達成後
arr = System.Text.Encoding.Default.GetBytes(mChar[j].ToString());
特別說一下
arr 目前是空的將可放入2個byte   而這2byte 取自於 中文字元big碼的2byte 16bit
System.Text.Encoding是因為沒有宣告命名空間所以重系統呼叫
而Default預設編碼為DBCS 取雙位元組 而.GetBytes是放進byte[]中!

再來後面的演算法 就無需再介紹
因為這字典檔 並非一個完整的羅馬字符
下面演算法 將不停比對 陣列中的數直 是否與字典檔案相同
字典檔案如下

 //定義拼音區編碼陣列
    private static int[] getValue = new int[]
            {
                -20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,
                -20032,-20026,-20002,-19990,-19986,-19982,-19976,-19805,-19784,-19775,-19774,-19763,
                -19756,-19751,-19746,-19741,-19739,-19728,-19725,-19715,-19540,-19531,-19525,-19515,
                -19500,-19484,-19479,-19467,-19289,-19288,-19281,-19275,-19270,-19263,-19261,-19249,
                -19243,-19242,-19238,-19235,-19227,-19224,-19218,-19212,-19038,-19023,-19018,-19006,
                -19003,-18996,-18977,-18961,-18952,-18783,-18774,-18773,-18763,-18756,-18741,-18735,
                -18731,-18722,-18710,-18697,-18696,-18526,-18518,-18501,-18490,-18478,-18463,-18448,
                -18447,-18446,-18239,-18237,-18231,-18220,-18211,-18201,-18184,-18183, -18181,-18012,
                -17997,-17988,-17970,-17964,-17961,-17950,-17947,-17931,-17928,-17922,-17759,-17752,
                -17733,-17730,-17721,-17703,-17701,-17697,-17692,-17683,-17676,-17496,-17487,-17482,
                -17468,-17454,-17433,-17427,-17417,-17202,-17185,-16983,-16970,-16942,-16915,-16733,
                -16708,-16706,-16689,-16664,-16657,-16647,-16474,-16470,-16465,-16459,-16452,-16448,
                -16433,-16429,-16427,-16423,-16419,-16412,-16407,-16403,-16401,-16393,-16220,-16216,
                -16212,-16205,-16202,-16187,-16180,-16171,-16169,-16158,-16155,-15959,-15958,-15944,
                -15933,-15920,-15915,-15903,-15889,-15878,-15707,-15701,-15681,-15667,-15661,-15659,
                -15652,-15640,-15631,-15625,-15454,-15448,-15436,-15435,-15419,-15416,-15408,-15394,
                -15385,-15377,-15375,-15369,-15363,-15362,-15183,-15180,-15165,-15158,-15153,-15150,
                -15149,-15144,-15143,-15141,-15140,-15139,-15128,-15121,-15119,-15117,-15110,-15109,
                -14941,-14937,-14933,-14930,-14929,-14928,-14926,-14922,-14921,-14914,-14908,-14902,
                -14894,-14889,-14882,-14873,-14871,-14857,-14678,-14674,-14670,-14668,-14663,-14654,
                -14645,-14630,-14594,-14429,-14407,-14399,-14384,-14379,-14368,-14355,-14353,-14345,
                -14170,-14159,-14151,-14149,-14145,-14140,-14137,-14135,-14125,-14123,-14122,-14112,
                -14109,-14099,-14097,-14094,-14092,-14090,-14087,-14083,-13917,-13914,-13910,-13907,
                -13906,-13905,-13896,-13894,-13878,-13870,-13859,-13847,-13831,-13658,-13611,-13601,
                -13406,-13404,-13400,-13398,-13395,-13391,-13387,-13383,-13367,-13359,-13356,-13343,
                -13340,-13329,-13326,-13318,-13147,-13138,-13120,-13107,-13096,-13095,-13091,-13076,
                -13068,-13063,-13060,-12888,-12875,-12871,-12860,-12858,-12852,-12849,-12838,-12831,
                -12829,-12812,-12802,-12607,-12597,-12594,-12585,-12556,-12359,-12346,-12320,-12300,
                -12120,-12099,-12089,-12074,-12067,-12058,-12039,-11867,-11861,-11847,-11831,-11798,
                -11781,-11604,-11589,-11536,-11358,-11340,-11339,-11324,-11303,-11097,-11077,-11067,
                -11055,-11052,-11045,-11041,-11038,-11024,-11020,-11019,-11018,-11014,-10838,-10832,
                -10815,-10800,-10790,-10780,-10764,-10587,-10544,-10533,-10519,-10331,-10329,-10328,
                -10322,-10315,-10309,-10307,-10296,-10281,-10274,-10270,-10262,-10260,-10256,-10254
            };
    //定義拼音陣列
    private static string[] getStr = new string[]
            {
                "A","Ai","An","Ang","Ao","Ba","Bai","Ban","Bang","Bao","Bei","Ben",
                "Beng","Bi","Bian","Biao","Bie","Bin","Bing","Bo","Bu","Ba","Cai","Can",
                "Cang","Cao","Ce","Ceng","Cha","Chai","Chan","Chang","Chao","Che","Chen","Cheng",
                "Chi","Chong","Chou","Chu","Chuai","Chuan","Chuang","Chui","Chun","Chuo","Ci","Cong",
                "Cou","Cu","Cuan","Cui","Cun","Cuo","Da","Dai","Dan","Dang","Dao","De",
                "Deng","Di","Dian","Diao","Die","Ding","Diu","Dong","Dou","Du","Duan","Dui",
                "Dun","Duo","E","En","Er","Fa","Fan","Fang","Fei","Fen","Feng","Fo",
                "Fou","Fu","Ga","Gai","Gan","Gang","Gao","Ge","Gei","Gen","Geng","Gong",
                "Gou","Gu","Gua","Guai","Guan","Guang","Gui","Gun","Guo","Ha","Hai","Han",
                "Hang","Hao","He","Hei","Hen","Heng","Hong","Hou","Hu","Hua","Huai","Huan",
                "Huang","Hui","Hun","Huo","Ji","Jia","Jian","Jiang","Jiao","Jie","Jin","Jing",
                "Jiong","Jiu","Ju","Juan","Jue","Jun","Ka","Kai","Kan","Kang","Kao","Ke",
                "Ken","Keng","Kong","Kou","Ku","Kua","Kuai","Kuan","Kuang","Kui","Kun","Kuo",
                "La","Lai","Lan","Lang","Lao","Le","Lei","Leng","Li","Lia","Lian","Liang",
                "Liao","Lie","Lin","Ling","Liu","Long","Lou","Lu","Lv","Luan","Lue","Lun",
                "Luo","Ma","Mai","Man","Mang","Mao","Me","Mei","Men","Meng","Mi","Mian",
                "Miao","Mie","Min","Ming","Miu","Mo","Mou","Mu","Na","Nai","Nan","Nang",
                "Nao","Ne","Nei","Nen","Neng","Ni","Nian","Niang","Niao","Nie","Nin","Ning",
                "Niu","Nong","Nu","Nv","Nuan","Nue","Nuo","O","Ou","Pa","Pai","Pan",
                "Pang","Pao","Pei","Pen","Peng","Pi","Pian","Piao","Pie","Pin","Ping","Po",
                "Pu","Qi","Qia","Qian","Qiang","Qiao","Qie","Qin","Qing","Qiong","Qiu","Qu",
                "Quan","Que","Qun","Ran","Rang","Rao","Re","Ren","Reng","Ri","Rong","Rou",
                "Ru","Ruan","Rui","Run","Ruo","Sa","Sai","San","Sang","Sao","Se","Sen",
                "Seng","Sha","Shai","Shan","Shang","Shao","She","Shen","Sheng","Shi","Shou","Shu",
                "Shua","Shuai","Shuan","Shuang","Shui","Shun","Shuo","Si","Song","Sou","Su","Suan",
                "Sui","Sun","Suo","Ta","Tai","Tan","Tang","Tao","Te","Teng","Ti","Tian",
                "Tiao","Tie","Ting","Tong","Tou","Tu","Tuan","Tui","Tun","Tuo","Wa","Wai",
                "Wan","Wang","Wei","Wen","Weng","Wo","Wu","Xi","Xia","Xian","Xiang","Xiao",
                "Xie","Xin","Xing","Xiong","Xiu","Xu","Xuan","Xue","Xun","Ya","Yan","Yang",
                "Yao","Ye","Yi","Yin","Ying","Yo","Yong","You","Yu","Yuan","Yue","Yun",
                "Za", "Zai","Zan","Zang","Zao","Ze","Zei","Zen","Zeng","Zha","Zhai","Zhan",
                "Zhang","Zhao","Zhe","Zhen","Zheng","Zhi","Zhong","Zhou","Zhu","Zhua","Zhuai","Zhuan",
                "Zhuang","Zhui","Zhun","Zhuo","Zi","Zong","Zou","Zu","Zuan","Zui","Zun","Zuo"
           };



比對結果通常都 差很多~
比GOOGLE翻譯還差 所以不做介紹

下一章 將有完整的 中文轉羅馬拼音