字元與字串 方煒 台大生機系.

Slides:



Advertisements
Similar presentations
MATLAB 程式設計入門篇 第十章:字元與字串 張智星 (Roger Jang) 台大資工系 多媒體檢索實驗室.
Advertisements

司 法 考 试 题 2002年——2009年.
2011年会计初级职称全国统考 初级会计实务 教案 主讲:高峰 2010年12月.
财经法规与会计职业道德 Company Logo.
高职高专院校人才培养工作水平评估指标体系解读
2013届高考复习方案(第一轮) 专题课件.
行政诉讼法.
财产行为税 是以纳税人拥有的财产数量或财产价值为征税对象或为了实现某种特定的目的,以纳税人的某些特定行为为征税对象而开征的税种。包括房产税、城镇土地使用税、车船税、土地增值税、资源税、印花税、城市维护建设税、 契税、耕地占用税等九个税种。由于其税收收入基本上为地方政府财政收入,所以又称为地方税。 除财产行为税以外,还有流转税、所得税两大类税收。
第十六专题 近代以来世界的科学 技术和文学艺术
服务热线: 菏泽教师招聘考试统考Q群: 菏泽教师统考教育基础模拟题解析.
南美洲 吉林省延吉一高中 韩贵新.
新准则框架与首次执行 企业会计准则 主讲人:陈清宇.
2011年广西高考政治质量分析 广西师范大学附属外国语学校 蒋 楠.
知识回顾 1、通过仔细观察酒精灯的火焰,你可以发现火焰可以分为 、 、 。 外焰 内焰 焰心 外焰 2、温度最高的是 。
岳阳市教学竞赛课件 勾股定理 授课者 赵真金.
会计学 第九章 财务会计报告.
财经法规与会计职业道德 (3) 四川财经职业学院.
Matlab教學 Speaker:林昱志 Date:2012/10/18.
1012 MATLAB 教學 彭奕翔 2013/02/27.
補充: Input from a text file
第一章 民法概述 一、民法概念 P4 二、民法的调整对象 三、民法的分类 四、民法的渊源 P10 五、民法的适用范围(效力范围)
第七章 财务报告 财务报告 第一节 财务报告概述 一、财务报告及其目标: 1、概念:财务报告是指企业对外提供的反映企业某一特定日期
程設一.
发展心理学 王 荣 山.
第十课 创新意识与社会进步 1.辩证的否定观:辩证否定、形而上学的否定观
勾股定理 说课人:钱丹.
政治第二轮专题复习专题七 辩 证 法.
第二章 负债 1、负债的概念:是指过去的交易或事项形成的、预 期会导致经济利益流出企业的现时义务。 2、负债的分类 流动负债 短期借款
第四章第一节 增值税法律制度2 主讲老师:梁天 经济法基础.
Matlab及其应用 鲍文 哈尔滨工业大学 先进动力控制与可靠性研究所
第七章 财务报告 主讲老师:王琼 上周知识回顾.
经济法基础习题课 第7讲 主讲老师:赵钢.
課程名稱:程式設計 授課老師:________
黃聰明 國立臺灣師範大學數學系 其它的資料型態與繪圖型態 黃聰明 國立臺灣師範大學數學系 T.-M.Huang.
張智星 清大資工系 補充內容:方煒 台大生機系
范洪源 臺灣師範大學數學系 MATLAB 基本功能介紹 范洪源 臺灣師範大學數學系.
Matlab M檔案 方煒 台大生機系.
張智星 (Roger Jang) 清大資工系 多媒體檢索實驗室
數學與電腦 的初相識 汪群超 個人網址: 變有不可者三,有不可不變者三: 能力未至不可變也、 學識未敷不得變也、 功侯未到不能變也。
第七章 字符串处理 7.1 字符阵列 7.2 字符串单元阵列 7.3 字符串比较 7.4 字符串搜索与取代 7.5 字符串与数值之间的变换
C 語言簡介 - 2.
張智星 清大資工系 多媒體檢索實驗室 第九章: 矩陣的處理與運算 張智星 清大資工系 多媒體檢索實驗室.
黃聰明 國立臺灣師範大學數學系 MATLAB 基本功能介紹 黃聰明 國立臺灣師範大學數學系
人教版数学四年级(下) 乘法分配律 单击页面即可演示.
引 言.
Introduction to MATLAB
第九章: 矩陣的處理與運算 張智星 (Roger Jang)
算法与程序设计 周少品.
第26讲 解直角三角形的应用 考点知识精讲 中考典例精析 举一反三 考点训练.
MATLAB 程式設計入門篇 初探MATLAB
第2章 MATLAB程序设计 编者.
3.3勾股定理的简单应用 初二数学备课组 蔡晓琼.
乘法公式 (1) 乘法分配律 (2) 和的平方公式 (3) 差的平方公式 (4) 平方差公式.
Speaker: Liu Yu-Jiun Date: 2009/4/29
張智星 (Roger Jang) 清大資工系 多媒體檢索實驗室
MATLAB 程式設計入門篇 初探MATLAB
经济法基础习题课 主讲:赵钢.
異質陣列 (Cell Arrays) 方煒 台大生機系.
第五章 相交线与平行线 三线八角.
MATLAB 程式設計入門篇 初探MATLAB
会计基础 第二章 会计要素与会计等式 刘颖
第四章 基本平面图形 线段、射线、直线.
第六章 类属B树索引技术 对基于树的索引方法给出一种通用算法。该算法是建立在类属B树的概念之上开发的。它将类型系统开放,使系统能支持用户自定义的数据类型、函数和某些特殊的查询谓词的集合。并且,将新的数据类型、函数、查询谓词等登记到数据库管理系统中,
MATLAB 程式設計 程式除錯 方煒 台大生機系.
分配律 ~ 觀念 15 × 15 × + 15 × 乘法公式 蘇德宙 老師 台灣數位學習科技股份有限公司
結構、檔案處理(Structure, File)
坚持,努力,机会留给有准备的人 第一章 四大金融资产总结 主讲老师:陈嫣.
Arguments to the main Function and Final Project
變數與資料型態  綠園.
MATLAB 程式設計入門篇 程式除錯 張智星 (Roger Jang)
Presentation transcript:

字元與字串 方煒 台大生機系

字元(Characters)與字串(Strings) MATLAB 處理字串的相關指令大部分都放在:{MATLAB 根目錄}\toolbox\matlab\strfun 其中的「strfun」就是代表「String Functions」。 若要查詢與字元和字串相關的指令,可在 Command Window內輸入: help strfun 或是 help strings

字元與字串的基本概念 數個字元(Characters)可以構成一個字串(Strings) 一個字串是被視為一個列向量(Row Vector)進行儲存 此一字串中的每一字元(含空白字元),是以其 ASCII 碼的形式存放於此列向量中的每一個元素(Element)

字元與字串的基本概念 Matlab 用「單引號」來界定字串變數,多個字串變數可直接並排,以得到一個新字串變數,例如: 範例: string01.m str3 = I like MATLAB, JavaScript, and Perl! str1 = 'I like MATLAB,'; % 建立字串變數 str1 str2 = ' JavaScript, and Perl!'; % 建立字串變數 str2 str3 = [str1 str2] % 直接並排str1 及 str2,以建立str3

字元與字串的基本概念 欲輸入含有單引號的字串,可重覆單引號的使用 若要計算字串變數的長度(即組成字元的個數),可用 length 指令 範例: string02.m I’ve got a date! 16 sentence = 'I''ve got a date!' length(sentence) % 計算字串變數 sentence 的長度

字串和ASCII double 指令: 檢視字串變數的儲存內容(即 ASCII 內碼) char 指令: 將 ASCII 內碼轉回字串形式 範例: string03.m sentence2 = I've got a date! sentence = 'I''ve got a date!'; sentenceAscii = double(sentence); %檢視 sentence 的 ASCII 碼 sentence2 = char(sentenceAscii) % 將 ASCII 碼轉回字串形式

ASCII: American Standard Code for Information Interchange http://home.educities.edu.tw/wanker742126/asm/ap04.html

字元的儲存 sentence = 'I''ve got a date!'; 無論是中文或英文,每一個字元都會佔用兩個位元組(2 Bytes),故在上頁中,字串變數 sentence 總共由 16 個字元構成,佔用的記憶體總計為三十二個位元組(32 bytes) whos 指令: 檢視字串變數 sentence 所佔用儲存空間(whos 變數) 範例: string04.m sentence = 'I''ve got a date!'; whos sentence % 檢視工作空間內變數 sentence 佔用記憶體大小 Name Size Bytes Class sentence 1x16 32 char array Grand total is 16 elements using 32 bytes

字元的儲存 MATLAB 是以兩個位元組來儲存一個字元,所以也可以支援 Big5 的中文碼,而且 Big5 中文的 ASCII 內碼都會大於數字 128 範例: string05.m chinese = '今日事,今日畢'; abs(chinese) % 檢驗中文內碼 ans = 42165 42217 43206 41281 42165 42217 45734

字元的儲存 chinese = '今日事,今日畢'; x = chinese+1 由於 MATLAB 將字串以其相對應之 ASCII 內碼(即數字形式)儲存成一列向量,故若對此字串直接進行數值運算,MATLAB 會先將此字串轉成數值,再進行一般數值向量的運算 範例: string06.m chinese = '今日事,今日畢'; x = chinese+1 x = 42166 42218 43207 41282 42166 42218 45735

字元與字串的基本概念-eval eval 指令: 直接“執行”某一特定字串,其效果就如同直接在 MATLAB 指令視窗內輸入此一特定字串 範例: string07.m str = 'x = [1 2 3]; y = x.^2'; eval(str) y = 1 4 9

字元與字串的基本概念-eval eval 指令特別適用於在 for - loop 內自動產生有規律的變數名稱 範例: string08.m Name Size Bytes Class x3 3x3 72 double array x4 4x4 128 double array x5 5x5 200 double array x6 6x6 288 double array Grand total is 86 elements using 688 bytes x3 , x4 , x5 , x6 都是在 for - loop 中產生的變數,分別代表維度為 3×3、4×4、5×5、6×6 的魔方陣 clear all % 清除所有變數 for i = 3:6 eval(['x', int2str(i) , '= magic(' , int2str(i) , ') ; ']); end whos x*

字串的判斷 class 或 ischar 指令: 判斷某一個變數是否為字串 範例: string09.m 字串變數所佔用的空間是同長度雙精準(Double)數值變數的四分之一 chinese = '今日事,今日畢'; out1 = class(chinese) % out1 的值是 “char”,代表chinese 是字串變數 x = chinese+1; out2 = ischar(x) % out2 的值是 0,代表 x 不是一個字串變數

一個變數來儲存多個字串 第一種方法是使用二維字元陣列(Two Dimensional Character Arrays) 必須先確認每個字串(即每一橫列)的長度一樣,否則就必須在短字串結尾補上空白字元 範例: string10.m departments = ee cs econ departments = ['ee '; 'cs '; 'econ'] % 注意空白字元的使用

一個變數來儲存多個字串 用char 指令儲存多個字串 範例: string11.m 得到結果和前一個範例一樣; . departments = char('ee', 'cs', 'econ') % 注意「()」及「,」的使用 departments = ee cs econ

一個變數來儲存多個字串 從二維字元陣列抽取出字串時,切記要使用 deblank 指令來移除尾部的空白字元 範例: string12.m . departments = char('ee', 'cs', 'econ'); dept1 = departments(1,:); % (1,:)代表第一列的元素 dept2 = deblank(dept1); % 使用 deblank 指令來移除尾部的空白字元 len1 = length(dept1) % 顯示變數 dept1 的長度=4 len2 = length(dept2) % 顯示變數 dept2 的長度=2 len1 = 4 len2 = 2

一個變數來儲存多個字串 範例:string13.m 當字串的長度差異甚大,那麼使用二維字元陣列來儲存多個字串,將造成記憶體空間的浪費。 可改為使用「異質陣列」: 使用大括號框住多個字串, 範例:string13.m cellData = {'ee', 'cs', 'econ'}; % 以異質陣列 celldata 來儲存多個字串 dept = cellData{3} % 印出第三個字串(必須使用大括號) dept = econ

一個變數來儲存多個字串 範例:string14.m 當字串的長度差異甚大,那麼使用二維字元陣列來儲存多個字串,將造成記憶體空間的浪費。 可改為使用「異質陣列」: 使用大括號框住多個字串, 或用cellstr指令將字元陣列轉換成異質陣列 範例:string14.m departments = char('ee', 'cs', 'econ'); cellData = cellstr(departments); leng = length(cellData{2}) % 顯示異質陣列 cellData 第二個元素長度 leng = 2

測試是否相同 範例:string15.m 用cellstr指令將字元陣列轉換成異質陣列 再用 char 轉回字元陣列,還會一樣嗎? dept1 = char('ee', 'cs', 'econ'); % dept1 是一個字元陣列 cellData = cellstr(dept1); % 將 dept1 轉成一個異值陣列 cellData dept2 = char(cellData); % 將 cellData 轉換成字元陣列 dept2 isequal(dept1, dept2) % 測試 dept1 和 dept2 是否相等 ans = 1

字串的比較 strcmp 指令: 用於比較字串內容的異同 不相等回傳0,相等回傳1 範例: string16.m str1 = 'today'; str2 = 'tomorrow'; str3 = 'today'; out1 = strcmp(str1, str2) % 比較兩字串 str1 和 str2 = 0 out2 = strcmp(str1, str3) % 比較兩字串 str1 和 str3 = 1 out1 = out2 = 1

字串的比較 strncmp 指令: 用於比較字串的前 n 個字元 範例: string17.m str1 = 'today'; str2 = 'tomorrow'; strncmp(str1, str2, 2) % 比較 str1 及 str2 兩字串的前 2 個字元 ans = 1

字串的比較 strcmp 及 strncmp 亦可用於字串異質陣列 範例: string18.m A = {'台北', '台中', '高雄'}; % 建立字串異質陣列 A B = {'台北', '台南', '花蓮'}; % 建立字串異質陣列 B out1 = strcmp(A, B) % 比較字串異質陣列 A 與 B 的每個元素是否相同 out2 = strncmp(A, B, 1) % 比較字串異質陣列 A 與 B 的每個元素的的第一個字元是否相同 out1 = 1 0 0 out2 = 1 1 0

字串的尋找 findstr 指令: 尋找在某一個長字串中的子字串(substrings),並傳回其起始位置 範例: string19.m pattern = '網球'; position = findstr(string, pattern) position = 9

字串的尋找及代換 strrep 指令: 用於字串尋找及代換,例如: newString = strrep(string, pattern, pattern2) 範例: string20.m string = '我最喜歡的運動是網球'; pattern = '網球'; pattern2 = '足球'; newString = strrep(string, pattern, pattern2) newString = 我最喜歡的運動是足球

字串的分解 strtok 指令: 根據一給定的分界字元(Delimiting Characters),將一字串拆解成數個字串,預設分界字元為空白字元 strvcat 指令: 將拆解下來的字串內容(即儲存在字串變數 chopped 中) 加到二維字元陣列 parsed 中 範例: string21.m input_string = 'ee cs econ stat me'; remainder = input_string; parsed = ''; % 建立一空字元陣列 while (any(remainder)) [chopped, remainder] = strtok(remainder); parsed = strvcat(parsed, chopped); end parsed parsed = ee cs econ stat me

中文字串 讀入中文字串時,將每一個中文字的 2-byte 分開來讀,造成兩個中文字變成四個字串元素 可使用 length 指令來看字串長度 範例: string22.m fid = fopen('tbig5.txt'); line = fgetl(fid) % 讀取一列檔案內容並顯示於command window fclose(fid); leng=length(line) % 顯示字串變數長度 line = 我是Roger leng = 9

中文字串 讀入中文字串時,將每一個中文字的 2-byte 分開來讀,造成兩個中文字變成四個字串元素 可使用 double 指令來看內碼 範例: string23.m fid = fopen('tbig5.txt'); line = fgetl(fid); % 讀取一列檔案內容 fclose(fid); double(line) % 顯示字串內碼 ans = 167 218 172 79 82 111 103 101 114

中文字串 讀入中文字串時,將每一個中文字的 2-byte 分開來讀,造成兩個中文字變成四個字串元素 xlate 指令: 將中文的 2-byte 「結合」在一起 範例: string24.m fid = fopen('tbig5.txt'); line = fgetl(fid); % 讀取一列檔案內容 fclose(fid); line2 = xlate(line) % 使用 xlate 將被拆開的中文結合在一起 leng = length(line2) % 顯示字串長度 line2 = 我是Roger leng = 7

Note xlate 在 control與 compiler toolbox 中 沒有此些工具箱便無法執行

中文的大五碼 中文的大五碼是由兩個位元組所構成,但不幸的是,在當初編碼的過程中,可能考慮欠周詳,因此把「直槓」(“|”)也編成某些字的大五碼的一部份,因此造成在字串處理上的極大不方便。(例如 Perl 的 Regular Expressions 碰到含有一直槓的大五碼就會出問題;使用 ODBC 來執行 SQL Command 時,若碰到含有一直槓的大五碼,也會出問題。此外,若用這些出問題的大五碼來當檔案或目錄名稱,則在使用 FTP 來進行檔案傳輸時,也會遇到麻煩而無法傳輸。) 常用的大五碼的內碼範圍是介於(含) ‘A440’ 和 ‘C67E’ 之間。舉個例子來說,「會」這個字是由兩個byte組成(B7 和 7C),把 B77C 轉成十進位就變成46972,的確是落在上述的Big5範圍之內,而「7C」就是「直槓」的ASCII 內碼。 如果大五碼的中文字包含「反斜線」("\"),也會出現許多問題。這是為什麼許如芸和許志安的 MP3 歌曲檔案名稱,都不會出現「許」這個字了的原因

function out = isbig5(str) % isbig5: 測試字串是否為大五碼常用字 請寫一個函數 isbig5.m,可以判斷給定的字串中,有哪幾個字元是屬於大五碼的常用字。例如 isbig5('我是Roger') 應該傳回的答案是 [1 1 0 0 0 0 0],代表前兩個字元是大五碼常用字,而後五個字元不是。常用的大五碼的內碼範圍是介於(含) 'A440' 和 'C67E' 之間。 function out = isbig5(str) % isbig5: 測試字串是否為大五碼常用字 % 假設送進來的字串已經經過了 xlate 的處理 out = (hex2dec('a440') <= str) & (str <= hex2dec('c67e'));

寫一個 MATLAB 程式big5withBackSlash.m,列出所有包含反斜線的大五碼中文字。共有幾個? function big5withBackSlash % 找出包含 "\" 的大五碼中文字 range=hex2dec('a440'):hex2dec('c67e'); offendingChar='\'; k=0; for i=1:length(range) numRep=i-1+range(1); % fprintf('%d/%d ===> %s\n', i, length(range), char(numRep)); strRep=dec2hex(numRep); if hex2dec(strRep(1:2))==abs(offendingChar) | hex2dec(strRep(3:4))==abs(offendingChar) k=k+1; %fprintf('"%s" = "%s" + "%s"\n', char(numRep), char(hex2dec(strRep(1:2))), char(hex2dec(strRep(3:4)))); fprintf('%d. %s\n', k, char(numRep)); end fprintf('大五碼常用字中,共有 %d 個字會包含「%s」的內碼!\n', k, offendingChar);

請寫一段 MATLAB 程式 big5withVerticalBar 請寫一段 MATLAB 程式 big5withVerticalBar.m ,來印出含有一直槓的所有中文字。 請問共有幾個這樣的中文字?只要在大五碼常用字的範圍內,找含有「7C」這個 byte的中文字,就是答案 function big5withVerticalBar.m % 找出包含 "|" 的大五碼中文字 range=hex2dec('a440'):hex2dec('c67e'); offendingChar='|'; k=0; for i=1:length(range) numRep=i-1+range(1); % fprintf('%d/%d ===> %s\n', i, length(range), char(numRep)); strRep=dec2hex(numRep); if hex2dec(strRep(1:2))==abs(offendingChar) | hex2dec(strRep(3:4))==abs(offendingChar) k=k+1; %fprintf('"%s" = "%s" + "%s"\n', char(numRep), char(hex2dec(strRep(1:2))), char(hex2dec(strRep(3:4)))); fprintf('%d. %s\n', k, char(numRep)); end fprintf('大五碼常用字中,共有 %d 個字會包含「%s」的內碼!\n', k, offendingChar);

字串與數值的轉換 int2str 指令: 將整數型態的資料轉換成字串資料 例如:y = int2str(x), x為整數, y 為字串 範例: string25.m x = 13462; y = int2str(x) % 將整數型態的資料轉換成字串資料 length(y) % 檢視 y 的長度 y = 13462 ans = 5

字串與數值的轉換 num2str 指令: 將實數轉為字串 範例: string26.m str1 = num2str(pi) % 實數轉為字串,預設有效位數是 4 位 str2 = num2str(pi, 10) % 增加小數以下有效位數到 10 位 str1 = 3.1416 str2 = 3.141592654

字串與數值的轉換 num2str 指令: 將實數轉為字串 範例: string27.m x = 0:0.1:2*pi; y = sin(x); plot(x,y) str = ['\leftarrow (', num2str(2.5), ', ', num2str(sin(2.5)), ')']; text(2.5, sin(2.5), str)

數值轉換 dec2hex 指令: 將 10 進位數值資料轉換成 16 進位的字串表示法 範例: string28.m y = dec2hex(x) y = 402 更多類似指令如 : hex2num, hex2dec, bin2dec….

字串陣列的轉換 mat2str 指令可將矩陣轉換為字串,此字串若再經由 eval 指令的使用,可再變回原先的矩陣 範例: string29.m A = [1 2 1; 3 5 6 ]; B = mat2str(A) % 將矩陣 A 轉成字串 B A2 = eval(B) % 再將字串 B 轉回矩陣 A2 isequal(A, A2) % 測試 A 和 A2 是否相等 B = [1 2 1;3 5 6] ans = 1

字串與數值的結合 sprintf 指令: 結合數值或字串,以產生新字串 (%s-印出字串,%g-印出數值,可使用 %f 或加上控制印出位數大小的數字 ) 範例: string30.m str = '圓周率'; newString = sprintf('「%s」是 %g', str, pi) newString = 「圓周率」是 3.14159

字串與數值的結合 sscanf 可依給定的格式來解析出所要的字串或數值 str = '2 4.7 5.2'; 範例: string31.m str = '2 4.7 5.2'; mat = sscanf(str, '%f') mat = 2.0000 4.7000 5.2000

設計一個函數capalize.m 用法如下: outputStr = capalize(inputStr) 函數 capalize 會將此字串中,每個字(Word)的第一個字母改成大寫,其餘則為小寫,並將多個空格代換成一個空格,outputStr 則是最後的輸出字串。 當輸入是 'you are my sunshine' 時,所得到的輸出字串是 'You Are My Sunshine'。

function out = capalize(in) %capalize: Capitalize each word of a given sentence % Usage: out = captalize(in) % Multiple spaces are reduced to a single space too. if nargin<1, selfdemo; return; end if isempty(in), out = ''; return; end i = 1; [token, rem] = strtok(in); while ~isempty(token) extracted{i} = token; i = i+1; [token, rem] = strtok(rem); for i = 1:length(extracted), string = extracted{i}; new_string = [upper(string(1)), string(2:end)]; extracted{i} = new_string; out = extracted{1}; for i = 2:length(extracted), out = [out, ' ', extracted{i}]; % ====== Self demo function selfdemo input = 'this is A test for Me too'; output = feval(mfilename, input); fprintf('input = %s\n', input); fprintf('output = %s\n', output);

HW:補強 capalize.m 當輸入是 ‘you are mY sUNshine’時,

設計一個函數split.m 可以將一個字串,依照給定的分界字元(Delimiter),拆解成一個字串異值陣列 用法如下:outputStr = split(string, delimiter) 其中 string 是輸入字串,delimiter 是分界字元,輸出 output 則是一個由字串形成的異值陣列。 split('This-is-a-test', '-') 所產生的結果是 {'This', 'is', 'a', 'test'}。

function tokenList = split(str, delimiter) % Split a string based on a given delimiter % % tokenList = split(str, delimiter) if nargin==0; selfdemo; return; end tokenList = {}; remain = str; i = 1; while ~isempty(remain), [token, remain] = strtok(remain, delimiter); tokenList{i} = token; i = i+1; end function selfdemo str='This-is-a-test'; tokenList=feval(mfilename, str, '-'); str fprintf('After running "tokenList=split(str, ''-'')":\n'); tokenList

設計一個 函數 countrows.m 可以計算在一個字串二維陣列中,每一個字串出現的次數 其用法如下: [rows, count] = countrows(A) 當 A=['cd '; 'ab '; 'abc'; 'ab '; 'cd '; 'ab '; 'de '] 時,所得到的 rows 是 ['ab '; 'cd '; 'de '; 'abc'],count 是 [3; 2; 1; 1] 代表在字串陣列 A 中,'ab ' 出現 3 次,'cd ' 出現 2 次,'de ' 出現 1 次,'abc' 出現 1 次。

countrows.m % ======= Subfunction ========== function selfdemo A = ['一台';'八爪'; '三光'; '人性'; '八爪'; '三光'; '八爪']; fprintf('Original string matrix:\n'); disp(A); fprintf('After sorting and finding counts of unique rows:\n'); [uniq_row, count] = countrows(A); for i = 1:length(count), fprintf('%s ==> %g\n', uniq_row(i, :), count(i)); end fprintf('Original cell array of strings:\n'); A = {'abc';'acd';'ad';'a';'bc';'ad';'acd';'acd'}; fprintf('%s ==> %g\n', uniq_row{i}, count(i)); function [uniq_row, count] = countrows(A) % COUNTROWS Unique element counts for a given matrix. % [uniq_row, count] = countrow(A) % A: input matrix where each row is viewed as an "element" % uniq_row: sorted listing of unique row in A % count: counts for each returned unique row % If A is a cell array of strings, then the output uniq_row is also a % cell array of strings. if nargin == 0, selfdemo; return, end cellstr_input = 0; if iscellstr(A), A = char(A); cellstr_input = 1; end term = sortrows(A); tmp1 = term; tmp1(end+1, :) = tmp1(end, :) + 1; tmp2 = tmp1(1:end-1, :) - tmp1(2:end, :); index = find(sum(abs(tmp2)') ~= 0); uniq_row = term(index, :); count = diff([0, index])'; % Rearrange according to decending order of counts [count, index] = sort(count); count = flipud(count); index = flipud(index); uniq_row = uniq_row(index, :); % Return cell array of string if given cell array of string if cellstr_input, uniq_row = cellstr(uniq_row);

設計一個 函數 str2ngram.m 可以傳回在一個輸入字串中,所存在的「n-字詞」 用法如下:ngramArray = str2ngram(string, n) 當 n = 2 時,此函數可以傳回由「二字詞」(Bigrams,任何相鄰兩個字)所形成的字串陣列 當 n = 3 時,此函數可以傳回由「三字詞」(Trigrams,任何相鄰三個字)所形成的字串陣列 依此類推。例如,str2ngram('網路上的芳鄰', 3) 所傳回的字串陣列是是 ['網路上'; '路上的'; '上的芳'; '的芳鄰']。

str2ngram.m function ngram = str2ngram(str, n) % Extract n-gram from a given string or cell string % Usage: ngram = str2ngram(str, n) % str: a single string or a cell string if nargin<1; selfdemo; return; end if nargin<2; n=2; end if isstr(str) ngram=char(buffer2(str, n, n-1)'); end if iscell(str) ngram=[]; for i=1:length(str) ngram=[ngram; str2ngram(str{i}, n)]; % ====== Sub-function ====== function out = buffer2(y, frameSize, overlap) % BUFFER2 Frame blocking, This is almost the same as % "buffer“ except that there is no leading zeros y = y(:); step = frameSize-overlap; frameCount = floor((length(y)-overlap)/step); out = zeros(frameSize, frameCount); for i=1:frameCount, startIndex = (i-1)*step+1; out(:, i) = y(startIndex:(startIndex+frameSize-1)); end % ====== Self demo ===== function selfdemo str = {'網路上的芳鄰', '清華大學ABCD'}; for i=1:length(str) fprintf('str{%d}=%s\n', i, str{i}); trigram = feval(mfilename, str, 3); fprintf('Trigram of the above string is: \n'); disp(trigram);

設計一個遞迴函式 combine.m 可對輸入字串進行組合 combine('abcd', 2) 所傳回的字串矩陣是 ab ac ad bc bd cd 此字串矩陣的每一列代表從輸入字串任取兩個字元時,所有可能的組合。

combine.m if n==1, out = obj(:); return; end function out = combine(obj, n) % out = combine(obj, n) returns combinations % of obj with n distinct elements. % For instance: combine([1 2 3 4 5], 2) or combine('abcde', 3). if n==1, out = obj(:); return; end if n==length(obj), out = obj(:)'; return; end out = []; for i = 1:length(obj)-1, first = obj(i); tail = obj(i+1:length(obj)); tail_combinat = combine(tail, n-1); loop_out = [first*ones(size(tail_combinat,1), 1), tail_combinat]; out = [out; loop_out]; end

設計一個 遞迴函式 permute2.m 可對輸入字串進行排列。 permute2('abc', 2)所傳回的字串矩陣是 ab ac ba bc ca cb 此字串矩陣的每一列代表輸入字串所有可能的排列。

permute2.m function out = permute2(obj, n) % out = permut(obj, n) returns permutation of obj with n elements. % All elements of obj is assumed to be distinct. % If n is not given, length(obj) is used instead. % For instance: permute([2 3 4 5], 2) or permute('abcde‘, 3). if nargin == 1, n = length(obj); end if length(obj) == 1, out = obj; return elseif n == 1, out = obj(:); return; end out = []; for i = 1:length(obj), first = obj(i); remainder = obj; remainder(i) = []; remainder_permute = permute(remainder, n-1); loop_out = [first*ones(size(remainder_permute,1),1), remainder_permute]; out = [out; loop_out];

combine 與 permute2 之比較 combine(‘abc’,2) ab ac bc permute2('abc', 2) ab ac ba bc ca cb combine([1 2 3],2) 1 2 1 3 2 3 3 2 permute2([1 2 3], 2) 1 2 1 3 2 1 2 3 3 1 3 2

讀入 news.txt (大約六千則新聞),並列出最常出現的 10 個二字詞及其出現次數,請將結果按出現次數由高而低來印出。 設計一個程式 getNgramStat.m 讀入 news.txt (大約六千則新聞),並列出最常出現的 10 個二字詞及其出現次數,請將結果按出現次數由高而低來印出。 請對「三字詞」、「四字詞」及「五字詞」進行類似的運算。 在進行統計時,這些 n-字詞不能包含大五碼的標點符號,也不能包含英文字母。

getNgramStat.m % 統計 n-gram (bigram, trigram 等)在一篇文章出現的次數 filename='news.txt'; string=fileread(filename); string=xlate(string); % 將兩個 byte 合成一個單位 string=string(isbig5(string)); % 只保留中文常用字 for n=2:5 fprintf('Collect %g-grams...\n', n); ngram=str2ngram(string, n); fprintf('Sort %g %g-grams...\n', size(ngram,1), n); [uniqNgram, count] = countrows(ngram); fprintf('Display %d distinct n-grams according to counts...\n', size(uniqNgram,1)); for i = 1:10 fprintf('%d/%d: %s ===> %g\n', i, size(uniqNgram,1), uniqNgram(i, :), count(i)); end

使用者自建的 fileread 函數 function contents = fileread(fileName); %FILEREAD Read the contents of a file and put it into a cell string if nargin==0, selfdemo; return; end fid = fopen(fileName); if fid<0, error('Cannot open file!'); end lineNum = 1; while 1 line = fgetl(fid); if ~isstr(line), break, end contents{lineNum} = xlate(line); lineNum = lineNum+1; fclose(fid); if exist('contents')~=1 contents=[]; % ====== self demo function selfdemo fileName = [mfilename, '.m']; contents = feval(mfilename, fileName); fprintf('The contents of "%s":\n', mfilename); for i=1:length(contents), fprintf('%s\n', contents{i});

writeOutputFile.m 值得細讀的程式工具 功能:將本章使用的所有 string*.m 程式的螢幕輸出,存入 output/*.txt 或 *.jpg 檔案內

使用者自建的 filewrite 函數 function filewrite(cellStr, fileName); %FILEWRITE Write a cell string to a file if nargin==0, selfdemo; return; end fid = fopen(fileName, 'w'); if fid<0, errorMessage=['Cannot open "', fileName, '"!']; error(errorMessage); end for i=1:length(cellStr), fprintf(fid, '%s\r\n', cellStr{i}); fclose(fid); % ====== self demo function selfdemo fileName = [tempdir, 'test.txt']; fprintf('fileName=%s\n', fileName); cellStr={'This', 'is', 'a', 'test.'}; fprintf('cellStr = '); disp(cellStr); feval(mfilename, cellStr, fileName); fprintf('The contents of "cellStr" have been written to "%s":\n', fileName); type(fileName);