犬ぶよツールズ制作記録

Javaによる研究生活のためのパッケージ、犬ぶよツールズ。
その開発と保守のための備忘録

RegrexTextFilter追記

2008-07-10 22:34:47 | about
(概要)
RegrexTextFilterについての追記です。

(内容)
● Javaの正規表現について
Pattern (Java 2 プラットフォーム SE v1.4.0)に完全な説明があります。

● RegrexTextFilterの設定ファイルについて
replaceタグのbefore属性に与えられる文字列は、
XMLパーサによって読み取られてStringオブジェクトになった後、
Javaの正規表現と解釈されます。これを図にすると次のようになります。

これから2つの点に気を付けなければいけないことがわかります。
+ マッチしたい文字列に「&」、「<」、「"」が含まれている時は、XMLの実体参照を使って、
それぞれ「&amp;」、「&lt;」、「&quot;」と書く。
+ マッチしたい文字列に「\」、「.」、「+」、「?」、「(」、「)」、「{」、「|」、「$」、「^」が含まれる時は
どれも「\」によってエスケープする。

これらの2点にさえ気を付ければ、正規表現による強力な置換機能を利用できます。

※Javaのプログラム中に文字リテラルとして正規表現を書く場合、
「\」にマッチさせるには「\\\\」と書かなければなりません。
文字リテラルからStringオブジェクトを作る時に「\」がエスケープ文字になるからです。
これに対し、XMLパーサによって読み取られた文字列は、文字リテラルではありません。
ですから、「\」にマッチさせるには「\\」で済みます。

● 例題
以下の二重引用符で囲んだ文字列にマッチさせるには、RegrexTextFilterの設定ファイルにどう書けばよいでしょうか。

Can you replace " "?
Can you replace "-"?
Can you replace ","?
Can you replace "}"?
Can you replace "	"?

Can you replace "."?
Can you replace "+"?
Can you replace "?"?
Can you replace "("?
Can you replace ")"?
Can you replace "{"?
Can you replace "$"?
Can you replace "^"?
Can you replace "|"?

Can you replace "\"?
Can you replace "\s"?
Can you replace "\d"?
Can you replace "\n"?
Can you replace "\t"?
Can you replace "\g"?

Can you replace ">"?
Can you replace "="?
Can you replace "/"?
Can you replace "!"?
Can you replace ";"?

Can you replace "&"?
Can you replace "<"?
Can you replace """?

Can you replace "&amp;"?
Can you replace "&lt;"?
Can you replace "&quot;"?

If you replace the followings, it failed. 
You should not replace "1".
You should not replace "d".



答えは以下の設定ファイルに含まれています。


<?xml version="1.0" encoding="UTF-8" ?>
<!-- This file is test.xml -->

<regrex>

	<!-- Use <start> tag to insert strings at the begining of document inside the regrex tag -->
	<start>
		<line value="#This file is generated by RegrexTextFilter with test.xml. " />
	</start>

	<!-- Javaの正規表現で使う記号ですが、エスケープは不要です。-->
	<replace before="^.*&quot;( )&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(-)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(,)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(})&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\t)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	
	<!-- Javaの正規表現で使う記号なので、エスケープが必要です。-->
	<replace before="^.*&quot;(\.)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\+)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\?)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\()&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\))&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\{)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\$)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\^)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\|)&quot;.*$" after="I can replace &quot;$1&quot;. " />

	<!-- “\”は常にエスケープが必要です。-->
	<replace before="^.*&quot;(\\)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\\s)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\\d)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\\n)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\\t)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(\\g)&quot;.*$" after="I can replace &quot;$1&quot;. " />

	<!-- XMLで使う記号ですが、エスケープは不要です。-->
	<replace before="^.*&quot;(>)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(=)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(/)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(!)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(;)&quot;.*$" after="I can replace &quot;$1&quot;. " />

	<!-- XMLで使う記号なので、エスケープが必要です。-->
	<replace before="^.*&quot;(&lt;)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(&quot;)&quot;.*$" after="I can replace &quot;$1&quot;. " />

	<!-- “&”は常にエスケープが必要です。-->
	<replace before="^.*&quot;(&amp;)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(&amp;amp;)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(&amp;lt;)&quot;.*$" after="I can replace &quot;$1&quot;. " />
	<replace before="^.*&quot;(&amp;quot;)&quot;.*$" after="I can replace &quot;$1&quot;. " />

</regrex>



この設定ファイルで変換した場合、結果は以下のようになります。


#This file is generated by RegrexTextFilter with test.xml. 
I can replace " ". 
I can replace "-". 
I can replace ",". 
I can replace "}". 
I can replace "	". 
I can replace ".". 
I can replace "+". 
I can replace "?". 
I can replace "(". 
I can replace ")". 
I can replace "{". 
I can replace "$". 
I can replace "^". 
I can replace "|". 
I can replace "\". 
I can replace "\s". 
I can replace "\d". 
I can replace "\n". 
I can replace "\t". 
I can replace "\g". 
I can replace ">". 
I can replace "=". 
I can replace "/". 
I can replace "!". 
I can replace ";". 
I can replace "&". 
I can replace "<". 
I can replace """. 
I can replace "&amp;". 
I can replace "&lt;". 
I can replace "&quot;". 
If you replace the followings, it failed. 
You should not replace "1".
You should not replace "d".



● 付録
test.txtとtest.xmlをダウンロードして、


> java jp.inubuyo.cell.RegrexTextFilter -c test.xml test.txt result.txt


とするとresult.txtが生成されるばすです。

test.txt
test.xml
result.txt
改行コードはシステムに合わせて変更する必要があります。

Inubuyo Permutation (ver. 1.0 release)

2008-07-09 17:58:29 | news
● 概要
Javaの配列に置換を作用させるためのライブラリです。
詳細はInubuyo Permutationに書かれています。

● 動作環境
Java。JRE 1.4以上。

(動作確認)
+ J2SE 1.5.0 on Mac OS X

● 配布について
jarファイルです。
classファイルが含まれています。
ソースコードは同梱していません。

● 利用条件
フリーです。
再配布不可。
jarファイルに含まれるclassを使用したプログラムを公開する場合には
こちらを経由して別途入手してもらうようにしてください。

● ダウンロード
jp.inubuyo.brain.disc.perm-1.0.jar (8,863 bytes)

● 内容
以下のクラスを含んでいます。
+ Permutation
+ Permutations

また、Permutationの子クラスとして以下を含んでいます。
+ ArrayPermutation
+ Transposition
+ CyclicPermutation
+ Identity

Inubuyo Permutation

2008-07-04 00:15:28 | about
(概要)
順序を入れ替える操作を置換と言います。
Javaにおいては、配列の要素の並べ替えがこれに当たります。
置換をオブジェクトとして表し、配列に作用させるのが自然です。
犬ぶよツールズでは、これを行うためのパッケージ、Inubuyo Permutationを提供します。

(内容)
● 置換とは
置換は数学的な概念です。
置換の概念を知らない人にもInubuyo Permutationの動作がわかることを目指し、
Javaの配列を例に、置換がどのようなものか説明します。
置換の概念を知っている人には、不正確でくどい説明に思えるかもしれません。

長さが3のObjectの配列

Object array = new Object[]{obj1, obj2, obj3};

を考えましょう。
もちろん、

array[0] = obj1
array[1] = obj2
array[2] = obj3

です。
これらの要素の順番を変える操作が置換です。

+ その1
array[0]とarray[1]を入れ替えると

array[0] = obj2
array[1] = obj1
array[2] = obj3

になります。
この操作を実現するメソッドとして

public static void swap(Object[] array, int index1, int index2){
	Object tmp = array[index1];
	array[index1] = array[index2];
	array[index2] = tmp;
}

といったものをよく見かけます。
このメソッドを使って、

swap(array, 0, 1);

とすれば、array[0]とarray[1]の入れ替えが実現できます。

このように2つの要素を入れ替える操作は、
互換と呼ばれ、置換の一種です。


+ その2
こんどはobj3を先頭に持ってきてみましょう。

array[0] = obj3
array[1] = obj1
array[2] = obj2

となります。これは2つの要素の入れ替えよりも複雑で、

array[0]にarray[2]だったもの
array[1]にarray[0]だったもの
array[2]にarray[1]だったもの

が移動しています。
このような操作も置換です。

+ その3

一般的には、置換はintの配列 perm: int[] を使って、

array[i]にarray[perm[i]]だったもの(*)

が移動する、というように指定できます。
上のその2に挙げた例では、

perm[0] =2
perm[1] =0
perm[2] =1

となります。

配列 perm: int[] によって指定される置換を実現するメソッドは
例えば次のようなものになります。

public static void act(Object[] array, int[] perm){
	Object[] tmp = new Object[array.length];
	System.arraycopy(array, 0, tmp, 0, array.length);
	for(int i=0; i <perm.length; i++){

● 置換を表すオブジェクト
置換を表すクラスPermutationとそのオブジェクトを
Inubuyo Permutationでは次のように扱えます。

// 置換が作用する配列
Object objctArray = new Object[]{obj1, obj2, obj3};

//obj3を先頭に移動する置換をインスタンス化
Permutation aPermutation = new ....

// 置換を作用させる
aPermutation.act(objectArray);
// 結果、
// objectArray[0] = obj3
// objectArray[1] = obj1
// objectArray[2] = obj2


// 置換が作用する別の配列
double doubleArray = new double[]{1.0, 2.0, 3.0};

// 同じ置換を作用させる
aPermutation.act(doubleArray);
// 結果、
// doubleArray[0] = 3.0
// doubleArray[1] = 1.0
// doubleArray[2] = 2.0



● 置換の積
1つの配列に2つの置換を続けて作用させることができます。

+ 具体例
例えば、array[0]とarray[1]を入れ替えるPermutationのインスタンスperm1と
array[2]を先頭に移動するPermutationのインスタンスperm2があったとき、

Object array = new Object[]{obj1, obj2, obj3};
perm1.act(array);
perm2.act(array);

とするような場合です。
詳しく見ると、

Object array = new Object[]{obj1, obj2, obj3};
perm1.act(array);//obj2, obj1, obj3 になる
perm2.act(array);//obj3, obj2, obj1 になる


この結果は、始めの順序でarray[0]とarray[2]を入れ替えたもの
になっています。ですから、
array[0]とarray[2]を入れ替えるPermutationのインスタンスperm3を使うと

Object array = new Object[]{obj1, obj2, obj3};
perm3.act(array);//obj3, obj2, obj1 になる

と、perm1とperm2を使った場合と同じ結果になります。

+ 一般論
2つの置換を連続して作用させると、結果はあるひとつの置換を作用させたのとの同じになります。
そして、2つの置換とその順番で、結果の置換は決まってしまいます。
これは置換の積と呼ばれる演算になります。

Inubuyo Permutationでは、この積を計算するメソッドproduct()も提供します。

perm3 = perm2.product(perm1); 

のようにして積を求めることができます。

積を求めるメソッドを使うと、複数の置換を作用させる場合に処理を早められることがあります。

(仕様)
● Permutation
置換を表す抽象クラスです。
+ 配列に作用する、以下のメソッドを持ちます。
    + act(Object[]): Object[]
    + act(double[]): double[]
    + act(int[]): int[]
    + act(boolean[]): boolean[]
    + act(float[]): float[]
    + act(long[]): long[]
    + act(char[]): char[]
    + act(short[]): short[]
これらのメソッドの戻り値は引数に与えられた配列そのものです。戻り値を返すことで
perm2.act(perm1.act(array));

といった記法が可能になります。
これらのメソッドは引数がnullだった場合NullPointerExceptionを投げます。
これらのメソッドは指定された配列の長さが短すぎる場合ArrayIndexoutOfBoundsExceptionを投げます。

+ 置換の積を計算する以下のメソッドを持ちます。
    + product(Permutation): Permutation

積の順序に注意してください。

Object array = new Object[]{obj1, obj2, obj3};
perm2.act(perm1.act(array));

というコードと

Object array = new Object[]{obj1, obj2, obj3};
perm3 = perm2.product(perm1); 
perm3.actOn(array);

は全く同じ結果になります。
perm2.product(perm1)とperm1.product(perm2)は一般に等しくありません。

+ 逆の置換を返す以下のメソッドを持ちます。
    + inverse(): Permutaion
次の2つのコード

perm.act(perm.inverse().act(array));
perm.inverse().act(perm.act(array));

は実行するとどちらの場合もarrayの順番は結果として変わりません。

+ 置換をint[]型により(*)の方法で表すための以下のメソッドを持ちます。
    + toArray(): int[]
    + toArrayPermutation(): ArrayPermutation

+ 何次の対称群に含まれるかを示す以下のメソッドを持ちます。
    + includedIn(): int

+ このクラスの子クラスは以下のメソッドをオーバーライドします。
    + toString(): String
    + equals(Object): boolean
    + hashCode(): int
equals(Object)は指定されたObjectが同じクラスでかつ置換として等しい場合にtrueを返します。
置換として等しいか調べるにはPermutations.areEqual(Permutation, Permutation): booleanを使ってください。

+ 恒等置換を表す定数 ID: Permutation を持ちます。

● ArrayPermutation extends Permutation
置換をint[]型で表したものに対応するPermutationを構成するクラスです。
このクラスはすべての置換を表すことができる点で他のPermutationの子クラスと異なっているため、
特別な役割を果たします。

● Transposition extends Permutation
互換を表すクラスです。

● CyclicPermutation extends Permutation
巡回置換を表すクラスです。

● Permutations
ユーティリティクラスです。

+ product(Permutation, Permutation): ArrayPermutation
積として確実にArrayPermutationのインスタンスが欲しい場合にはこれを使用します。

+ isID(Permutation): boolean
指定された置換が恒等置換かどうか調べます。

+ areEqual(Permutation, Permutation): boolean
指定された2つの置換が置換として等しいか調べます。
配列に作用させた結果が同じになる場合にtrueを返します。

● パッケージ
以上のクラスをjp.inubuyo.brain.disc.permパッケージに入れます。


(参考文献)
+ ウィキペディア「対称群」

現在アーカイブがダウンロードできません

2008-07-01 23:30:20 | status
当サイトで公開しているjarファイルは、都合上、
別のサーバー上に置いてあります。
現在(2008/7/1以降)、それらのjarファイルがダウンロードできない状態になっています。

今週末にはダウンロードできる状態にするつもりです。

ダウンロードをご希望の方には申し訳ありませんが、
しばらくお待ちください。