8.文字列処理 8.1 C#の文字列 C#では, “ABCD”のように文字列を2重引用符で挟んで指定します。ASCIIコード体系のとき,以下のような内部形式となります。 1 1 文字 ‘A’ ナル文字 1 1 文字 ‘B’ A B C D \0 1 1 1 文字 ‘C’ 1 1 文字 ‘D’ ナル文字‘\0’

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
1 例題 ex3b ( 配列 ) 科学科プログラミング. 2 例題 : ex3b  以下の 3 つについて例題を進める ステップ 1 :配列 ステップ 2 :最小と最大 ステップ 3 :文字型の配列.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
情報生命科学特別講義III (1) 文字列マッチング
第3回:ボールを上下に動かそう! (オブジェクトの移動、一次元)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
JavaScript プログラミング入門 2006/11/10 神津.
情報処理演習C2 ファイル操作について (2).
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
アルゴリズムとデータ構造 2013年6月18日
12.3,E,-15, 12.3,E5,+,=, >,<,…,
基礎プログラミングおよび演習 第9回
プログラミング基礎I(再) 山元進.
アルゴリズムとデータ構造 2012年7月19日
アルゴリズムとデータ構造 第9回演習解答.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
アルゴリズムとデータ構造 2012年6月14日
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
第8回 プログラミングⅡ 第8回
文字列探索 2011/5/30.
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
アルゴリズムとデータ構造 2011年6月13日
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
第20章 Flyweight ~同じものを共有して無駄をなくす~
アルゴリズムとデータ構造 2011年6月14日
アルゴリズムとデータ構造 2013年7月18日
データ構造とプログラミング技法 (第10回) ー文字列照合(KMP法、BM法)ー.
第10章 char 文字列; 文字列を入力させるよ!.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
第二回 VB講座 電卓を作ろう.
プログラミング論 II 2008年10月30日 文字列
データ構造とアルゴリズム 第14回 文字列の照合.
プログラミング 4 記憶の割り付け.
アルゴリズムとプログラミング (Algorithms and Programming)
画像処理プログラムの説明.
第10章 これはかなり大変な事項!! ~ポインタ~
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
アルゴリズムとデータ構造 2011年7月12日
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
09: ポインタ・文字列 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング 4 整列アルゴリズム.
2005年度 データ構造とアルゴリズム 第6回 「ハッシュ法を用いた探索」
アルゴリズム論 (第12回) 佐々木研(情報システム構築学講座) 講師 山田敬三
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
プログラミング基礎a 第6回 C言語によるプログラミング入門 配列と文字列(その2)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
アルゴリズムとプログラミング (Algorithms and Programming)
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
09: ポインタ・文字列 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
プログラミング論 文字列
プログラミング 4 文字列.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
プログラミング演習I 2003年6月11日(第9回) 木村巌.
データ構造とアルゴリズム 第14回 文字列の照合.
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
7.集合 7.1 集合とは [集合と要素] 関東の都道府県 群馬県 栃木県 要素 埼玉県 茨城県 東京都 千葉県 神奈川県
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

8.文字列処理 8.1 C#の文字列 C#では, “ABCD”のように文字列を2重引用符で挟んで指定します。ASCIIコード体系のとき,以下のような内部形式となります。 1 1 文字 ‘A’ ナル文字 1 1 文字 ‘B’ A B C D \0 1 1 1 文字 ‘C’ 1 1 文字 ‘D’ ナル文字‘\0’

文字列の内部表現 文字列の内部形式を listBox1に表示するプログラム private string binaryScaleString(long V) { long VV=V;string S=""; for(int i=0;i<16;i++, VV /=2 ) S = ((VV % 2 ==0) ? "0" : "1") + S; return S; } private void strDump(string S) listBox1.Items.Clear(); for(int i=0;i<S.Length;i++) long V=(long)S[i]; string X = V.ToString("X"); string B = binaryScaleString(V); if(X.Length==2) X = " " + X; listBox1.Items.Add(S[i].ToString() + "\t" + X + "\t" + B); 文字列の内部表現

文字列の内部表現 Clickイベントハンドラ実行結果 private void button1_Click(object sender, System.EventArgs e) { strDump("文字列string"); }

配列による文字列 文字リテラルは,本来, その内容を自由に書き換えて使うものではありません。 ですから,C#では,stringはRead Only とみなされており, 陽に代入は許されません. 自由に入れ替える処理を記述するためには, 次のようにchar型の配列として宣言します。 なお,char型配列をstringとして扱うには, 以下の例のようにCharToString関数を使います(C, C++との違い)。 private void button2_Click(object sender, System.EventArgs e) {   char[] CH =new char[10]; CH[0]='文';CH[1]='字';CH[2]='列';   CH[3]='s' ;CH[4]='t' ;CH[5]='r' ;   CH[6]=’i' ;CH[7]='n' ;CH[8]='g';CH[9]='\0'; strDump(CharToString(CH)); }

8.2 文字列の基本操作 (1)文字列の長さ 文字列の最後はナル文字です。 ですから,ナル文字を検索することで 8.2 文字列の基本操作 (1)文字列の長さ 文字列の最後はナル文字です。 ですから,ナル文字を検索することで 文字列の長さを求めることができます。。 ナル文字 A B C D \0 private int str_len(char[] ch) {    int i=0;    while(ch[i] != '\0')i++;    return i; }

配列の大きさと文字列の長さ 文字列を格納するための配列のサイズと 文字列の長さは必ずしも一致しません。 配列の大きさと文字列の長さの違いを 以下のプログラムで確認してみましょう。 (C++,C の strlen 関数は,次のように,文字列.Lengthと書きます) private void button3_Click(object sender, System.EventArgs e) {  char[] CH =new char[12];  CH[0]='文';CH[1]='字';CH[2]='列';  CH[3]='s' ;CH[4]='t' ;CH[5]='r' ; CH[6]='i'; CH[7]='n' ;CH[8]='g';CH[9]='\0';  MessageBox.Show(CH.Length.ToString());  // 配列のサイズ=12  MessageBox.Show(str_len(CH).ToString()); // 文字列の長さ=9  MessageBox.Show(CharToString(CH).Length.ToString());                       // 文字列の長さ=9 }

(2)文字列からの文字の探索 文字列から任意の文字を探索する手続きは次のようになります。 private int 文字探索(string X, char C) {   int i=0;   while (i < X.Length && X[i] !=C)i++;   if(i < X.Length) return i;   return -1; }

文字探索のメソッド(Cのstrchr,strrchrに相当) (a) String.IndexOf 特定の文字が文字列内で最初に出現する位置を返却。先頭は0,指定した文字が見 つからない場合,–1 を返す。大文字と小文字は区別される。 string S = ”Peter Piper picked a peck"; MessageBox.Show(S.IndexOf(’p')); この例では8 と表示される。 (b)String.LastIndexOf 指定した文字列が文字列内で最後に出現する位置を返却。先頭は0,指定した文字 が見つからない場合,-1を返す。大文字と小文字は区別される。 MessageBox.Show(S.LastIndexOf(’p')); この例では21 と表示される。

(3)文字列の比較 文字列S1,S2を比較し, S1が大きければ正の整数値, 小さければ負の整数値, 等しければ0を返却する関数の処理を以下に示します。 (3)文字列の比較 private int str_cmp(string S1, string S2) { int i=0; while(i<S1.Length && i<S2.Length && S1[i]==S2[i]) i++; if (i== S1.Length && i== S2.Length) return 0; else if(I < S1.Length && I < S2.Length) return ((int)S1[i]-(int)S2[i]); else if(i<S1.Length) return 1; else return -1; } private void button5_Click(object sender, System.EventArgs e) string S1 = textBox1.Text; string S2 = textBox2.Text; MessageBox.Show(str_cmp(S1,S2).ToString());

C#の文字列比較メソッド 文字列比較のメソッドは用意されていますので, 通常は,わざわざプログラムを作る必要はありません。 たとえば,String.Compare メソッドでは, 2 つの文字列を比較します。 このメソッドでは,以下の結果を返却します。 (a) 引数1が引数2より大きいとき,正の整数 (b) 引数1が引数2より小さいとき,負の整数 (c) 引数1と引数2が等しいとき0 この他,CompareOrdinal ,CompareTo,Equals,StartsWith , EndsWith などがあります。詳しくはC#のマニュアルやヘルプを参照してください。

8.3 文字列探索 (1)文字列探索とは 文字列探索(string searching)とは, 8.3 文字列探索 (1)文字列探索とは 文字列探索(string searching)とは, ある文字列の中に,別の文字列が含まれているかどうか, 含まれている場合は,その位置を示すこと。 探索される側の文字列:テキスト(text) 探し出すための文字列:パターン(pattern)

(2)力まかせ法(単純法,素朴法) 力まかせ法(brute forth method)の手順 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 (a) P E T E R P I P E R \0 P I P \0 3文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (b) P E T E R P I P E R \0 P I P \0 1文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (c) P E T E R P I P E R \0 P I P \0 1文字目が一致しない

力まかせ法の手順2 力まかせ法(brute forth method)の手順 1 2 3 4 5 6 7 8 9 10 P E T E R 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E R \0 (d) P I P \0 1文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (e) P E T E R P I P E R \0 P I P \0 1文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (f) P E T E R P I P E R \0 P I P \0 全文字一致

力まかせ法のプログラム private int 力まかせ法(string 文字列, string パターン) {   int P1=0; int P2=0;   while(P1<文字列.Length && P2<パターン.Length)   { if(文字列[P1] == パターン[P2]){ P1++; P2++;} else { P1 = P1 - P2 + 1; P2 = 0; }   }   if(P2==パターン.Length) return(P1 - P2);   return -1; } private void button2_Click(object sender, System.EventArgs e)   string 文字列 = textBox1.Text;   string パターン = textBox2.Text;   label5.Text=力まかせ法(文字列, パターン).ToString();

(3)KMP法 力まかせ法では,不一致文字があると, パターンを移動して再びパターンの先頭から照合する。 それまでの照合結果が捨てられる。 パターンの特徴を活かし,そこまでの照合結果を有効活用する D. E. KnuthとV. R. Pratt,J. H. Morris が ほぼ同時期に考案した方法。 Knuth-Pratt-Morris 法,略してKMP法と呼ばれる。

KMP法の考え方 [例]パターン移動の際,何文字目から照合を再開するかを事前に決めておく。 1 2 3 4 5 6 7 8 9 10 (a) 1 2 3 4 5 6 7 8 9 10 (a) P S E A S E R P E R \0 S E A S E R \0 1文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (b) P S E A S E D P E R \0 S E A S E R \0 6文字目が一致しない 1 2 3 4 5 6 7 8 9 10 (c) P S E A S E R P E R \0 (3文字目から照合) S E A S E R \0

照合再開位置(1) (a) 1文字目で不一致 1 2 3 4 5 6 7 8 9 10 P ? ? ? ? ? ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 P ? ? ? ? ? ? ? ? ? ? S E A S E R \0 1文字目が一致しない 1文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 P ? ? ? ? ? ? ? ? ? ? S E A S E R \0

照合再開位置(2) (b) 2文字目で不一致 1 2 3 4 5 6 7 8 9 10 S X ? ? ? ? ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 S X ? ? ? ? ? ? ? ? ? S E A S E R \0 2文字目が一致しない 1文字ずらして 1文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 S X ? ? ? ? ? ? ? ? ? S E A S E R \0

照合再開位置(3) (c) 3文字目で不一致 1 2 3 4 5 6 7 8 9 10 S E X ? ? ? ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 S E X ? ? ? ? ? ? ? ? S E A S E R \0 3文字目が一致しない 2文字ずらして 1文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 S E X ? ? ? ? ? ? ? ? S E A S E R \0

照合再開位置(4) (d) 4文字目で不一致 1 2 3 4 5 6 7 8 9 10 S E A X ? ? ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 S E A X ? ? ? ? ? ? ? S E A S E R \0 4文字目が一致しない 3文字ずらして 1文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 S E A X ? ? ? ? ? ? ? S E A S E R \0

照合再開位置(5) (e) 5文字目で不一致 1 2 3 4 5 6 7 8 9 10 S E A S X ? ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 S E A S X ? ? ? ? ? ? S E A S E R \0 5文字目が一致しない 3文字ずらして 2文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 S E A S X ? ? ? ? ? ? S E A S E R \0

照合再開位置(6) (f) 6文字目で不一致 1 2 3 4 5 6 7 8 9 10 S E A S E X ? ? ? ? ? S E 1 2 3 4 5 6 7 8 9 10 S E A S E X ? ? ? ? ? S E A S E R \0 6文字目が一致しない 3文字ずらして 3文字目から照合を開始 1 2 3 4 5 6 7 8 9 10 S E A S E X ? ? ? ? ? S E A S E R \0

照合再開位置の設定(1) パターン同士を1文字ずつずらしながら照合する S E A S E R S E A S E R S E A S E 0 0 S E A S E R S E A S E R S E A S E R 0 0 0 S E A S E R S E A S E R S E A S E R 0 0 0 1

照合再開位置の設定(2) パターン同士を1文字ずつずらしながら照合する S E A S E R S E A S E R S E A S E 0 0 0 1 2 S E A S E R S E A S E R S E A S E R 0 0 0 1 2 0

KMP法のプログラム(1) private int KMP法(string 文字列, string パターン) {   int P1=1; int P2=0; int[] skip=new int[256];   skip[P1]=0;   while (P1<パターン.Length)   { if(パターン[P1]==パターン[P2]) skip[++P1]=++P2; else if(P2==0) skip[++P1]=P2; else P2=skip[P2];   }   P1=P2=0;   while(P1<文字列.Length && P2<パターン.Length) if(文字列[P1] == パターン[P2]){ P1++; P2++;} else if(P2 == 0) P1++;    else P2=skip[P2];   if(P2==パターン.Length) return(P1 - P2);   return -1; }

KMP法のプログラム(2) private void button3_Click(object sender, System.EventArgs e) { string 文字列 = textBox1.Text; string パターン = textBox2.Text; label5.Text=KMP法(文字列, パターン).ToString(); }

(4)BM法 照合をパターンの末尾から行う方法。 一致しない文字を見つけた場合, 事前に用意した表により移動量を決める。 R. S. BoyerとJ. S. Moore によるアルゴリズム Boyer-Moore 法,略してBM法と呼ばれる。

BM法の考え方(1) [例]パターンの後から照合し,ずらしてみよう。 1 2 3 4 5 6 7 8 9 10 P E T E R P I 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E R \0 (a) P I P R \0 不一致 (b) P I P R \0 1文字ずらしても不一致 (c) P I P R \0 2文字ずらしても不一致 (d) P I P R \0 3文字ずらしても不一致 パターン中にない文字をテキスト中に見つけたら, そこまでの文字は,すべてスキップできる。

BM法の考え方(2) [例]一致している場合,1文字前に戻る 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E R \0 (a) P I P E \0 一致 (b) P I P E \0 不一致 (c) P I P E \0 1文字ずらしても不一致 (d) P I P E \0 2文字ずらしても不一致 3文字ずれることになる。

BM法の考え方(3) [例]一致している場合 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E R \0 (a) 1 2 3 4 5 6 7 8 9 10 P E T E R P I P E R \0 (a) P I P E \0 一致 P I P E \0 (b) 一致 P I P E \0 (c) 一致 P I P E \0 一致 (d)

スキップテーブル (各文字に出会ったときずらす量) 最初,以下の表を作成しておく。    パターン文字数をN,パターンの最後に出現する位置の添え字をKとする。    ■パターン中にない場合 N    ■パターン中にある場合 N-K-1 K 1 2 3 P I P E 2 1 (Eのときは,一致の処理) A B C D E F G H I J K L M 4 4 4 4 4 4 4 2 4 4 4 4 N O P Q R S T U V W X Y Z 4 4 1 4 4 4 4 4 4 4 4 4 4

BM法のプログラム(1) private int BM法(string 文字列, string パターン) { int P1=0; int P2=0; int txtLen = 文字列.Length; int patLen = パターン.Length; int[] skip=new int[char.MaxValue+1]; for(P1 =0; P1 <= char.MaxValue; P1++) skip[P1]=patLen; for(P1 =0; P1 <= patLen - 1;P1++) skip[パターン[P1]]=patLen - P1 -1; // このとき,P1= patLen-1であることに注意 while(P1<文字列.Length) P2=patLen - 1; while(文字列[P1] == パターン[P2]) if (P2==0) return(P1); P1--; P2--; } P1 += skip[文字列[P1]]; return -1;

BM法のプログラム(2) private void button4_Click(object sender, System.EventArgs e) {   string 文字列 = textBox1.Text;   string パターン = textBox2.Text;   label5.Text=BM法(文字列, パターン).ToString(); }