前提・実現したいこと
パターンマッチングを使って簡単なデータベース検索がしたい
発生している問題・エラーメッセージ
条件を満たすすべての解の組み合わせを表示したいが、変数束縛によって解の組が1つしか表示できない
方針またはやり方を教えてほしい
該当のソースコード
メインクラス
問題があるのは引数で2つパターンを入力した場合です。
Java
1public static void main(String[] args) { 2 3 if(args.length == 1){ 4 5 System.out.println("検索するデータセットを選択 \n" 6 + "0 :サンプルデータセット \n" 7 + "1 :自作のデータセット \n" 8 + ":"); 9 10 Scanner scan = new Scanner(System.in); 11 int key = scan.nextInt(); 12 13 String filename = ("src/dataset_example.txt"); 14 15 switch(key) { 16 17 case 0 : filename = ("src/dataset_example.txt"); 18 19 } 20 21 try{ 22 File file = new File(filename); 23 BufferedReader br = new BufferedReader(new FileReader(file)); 24 25 String str; 26 while((str = br.readLine()) != null){ 27 28 29 if(new Matcher().matching(args[0],str)) { 30 31 System.out.println(str); 32 33 } 34 } 35 36 br.close(); 37 }catch(FileNotFoundException e){ 38 System.out.println(e); 39 }catch(IOException e){ 40 System.out.println(e); 41 } 42 43 // ****************ここまでパターンが1つの場合*********************** 44 45 }else if (args.length == 2){ 46 //System.out.println((new Matcher()).matching(args[0],args[1])); 47 48 49 System.out.println("検索するデータセットを選択 \n" 50 + "0 :サンプルデータセット \n" 51 + "1 :自作のデータセット \n" 52 + ":"); 53 54 Scanner scan = new Scanner(System.in); 55 int key = scan.nextInt(); 56 57 String filename = ("src/dataset_example.txt"); 58 59 switch(key) { 60 61 case 0 : filename = ("src/dataset_example.txt"); 62 63 } 64 65 try{ 66 File file = new File(filename); 67 BufferedReader br = new BufferedReader(new FileReader(file)); 68 69 String str; 70 71 Unifier uni = new Unifier(); 72 73 uni.unify(args[0],args[1]); 74 75 while((str = br.readLine()) != null){ 76 77 uni.unify(args[0],str); 78 uni.unify(args[1],str); 79 80 // if(uni.unify(args[0],str)) {} 81 // if(uni.unify(args[1],str)) {} 82 83 } 84 85 uni.vars.toString(); 86 87 br.close(); 88 }catch(FileNotFoundException e){ 89 System.out.println(e); 90 }catch(IOException e){ 91 System.out.println(e); 92 } 93 94 95 96 97 // ****************ここまでパターンが2つの場合************************ 98 }else {System.out.println("引数は1または2です"); 99 } 100 } 101 102 103 104 } 105 106
Unifierクラス
Java
1class Unifier { 2 StringTokenizer st1; 3 String buffer1[]; 4 StringTokenizer st2; 5 String buffer2[]; 6 HashMap<String,String> vars; 7 8 Unifier(){ 9 vars = new HashMap<String,String>(); 10 } 11 12 public boolean unify(String string1,String string2,HashMap<String,String> bindings){ 13 this.vars = bindings; 14 return unify(string1,string2); 15 } 16 17 public boolean unify(String string1,String string2){ 18 System.out.println(string1); 19 System.out.println(string2); 20 21 // 同じなら成功 22 if(string1.equals(string2)) return true; 23 24 // 各々トークンに分ける 25 st1 = new StringTokenizer(string1); 26 st2 = new StringTokenizer(string2); 27 28 // 数が異なったら失敗 29 if(st1.countTokens() != st2.countTokens()) return false; 30 31 // 定数同士 32 int length = st1.countTokens(); 33 buffer1 = new String[length]; 34 buffer2 = new String[length]; 35 for(int i = 0 ; i < length; i++){ 36 buffer1[i] = st1.nextToken(); 37 buffer2[i] = st2.nextToken(); 38 } 39 for(int i = 0 ; i < length ; i++){ 40 if(!tokenMatching(buffer1[i],buffer2[i])){ 41 return false; 42 } 43 } 44 45 46 // 最後まで O.K. なら成功 47 System.out.println(vars.toString()); 48 System.out.println("TRUE") 49 return true; 50 } 51 52 boolean tokenMatching(String token1,String token2){ 53 if(token1.equals(token2)) return true; 54 if( var(token1) && !var(token2)) return varMatching(token1,token2); 55 if(!var(token1) && var(token2)) return varMatching(token2,token1); 56 if( var(token1) && var(token2)) return varMatching(token1,token2); 57 return false; 58 } 59 60 boolean varMatching(String vartoken,String token){ 61 if(vars.containsKey(vartoken)){ 62 if(token.equals(vars.get(vartoken))){ 63 return true; 64 } else { 65 return false; 66 } 67 } else { 68 replaceBuffer(vartoken,token); 69 if(vars.containsValue(vartoken)){ 70 replaceBindings(vartoken,token); 71 } 72 vars.put(vartoken,token); 73 } 74 return true; 75 } 76 77 void replaceBuffer(String preString,String postString){ 78 for(int i = 0 ; i < buffer1.length ; i++){ 79 if(preString.equals(buffer1[i])){ 80 buffer1[i] = postString; 81 } 82 if(preString.equals(buffer2[i])){ 83 buffer2[i] = postString; 84 } 85 } 86 } 87 88 void replaceBindings(String preString,String postString){ 89 Iterator<String> keys; 90 for(keys = vars.keySet().iterator(); keys.hasNext();){ 91 String key = (String)keys.next(); 92 if(preString.equals(vars.get(key))){ 93 vars.put(key,postString); 94 } 95 } 96 } 97 98 99 boolean var(String str1){ 100 // 先頭が ? なら変数 101 return str1.startsWith("?"); 102 } 103 104} 105
試したこと
ファイルを順次読み込んでマッチングしていきました、パターン1つの場合は毎回新しくマッチングして検査すればよかったのですが
2つの場合、それまでの変数が束縛されている状態を保持しないともう1つのパターンがマッチした時に困ります
しかし、それでは最後まで変数が束縛されてしまい、解が1つしか出ません
補足情報(FW/ツールのバージョンなど)
データベースは
Taro is a student
Taro studies philosophy
Taro loves hanako
hanako is a student
・・・
というようなものに対して"?x is a student"などのパターンを与えます
"?x is a student" "?studies ?y"としたときに
x と y の組として<taro,philosophy> <hanako, informatics>などのようにすべての解を表示したいです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/22 03:39
2021/02/22 23:30
2021/02/23 07:28
2021/02/24 12:58
2021/02/25 08:53
2021/02/25 09:35
2021/02/26 03:30
2021/02/26 09:18