一、实验目的
1.理解不同体系结构风格的具体内涵。
2.学习体系结构风格的具体实践。
二、实验环境
硬件: (依据具体情况填写)
软件:Java或任何一种自己熟悉的语言
三、实验内容
“上下文关键字”KWIC(Key Word in Context,文本中的关键字)检索系统接受有序的行集合:每一行是单词的有序集合;每一个单词又是字母的有序集合。通过重复地删除航中第一个单词,并把它插入行尾,每一行可以被“循环地移动”。KWIC检索系统以字母表的顺序输出一个所有行循环移动的列表。
尝试用不同的策略实现这个系统。选择2-3种体系结构风格来实现。
四、实验步骤:
要求写具体实现代码,并根据实际程序,画出程序的总体体系结构图和算法结构图,以及运行结果截图。
1、体系结构图:
2、简述体系结构各部件的主要功能,实现思想。
例如:
上述的主程序/子程序的方法,将问题分解为输入(Input)、移动(Shifter)、按字母表排序(Alphabetizer)、输出(Output)。
Input: 将读取到的每行的数据保存到实现LineStorage接口的数据结构中去
shifter:主函数调用该方法,该方法对characters中的每行的数据进行循环移位,并将移位得到的新行保存到实现LineStorage的数据结构中去
alphabetizer: 对circularShift中得到的行数据进行按字母顺序排序
Output:output方法迭代调用alphabetizer里面的方法得到按字母顺序排好序的行数据,并输出
Characters:实现字符的处理。读取一行就用Characters抽象数据类型将该行存放,直到文件读完为止
3、写出主要的代码
/** * */ package adtstyle; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import adtstyle.impl.*; /** * 用抽象数据类型设计KWIC * @author cx * @version 2017年11月17日 */ public class ADTKwic { /** * @param args */ public static void main(String[] args) { File fInput = new File("input.txt"); File fOutput = new File("output.txt"); Input input = new Input(); Characters characters = new CharactersImpl(); input.input(fInput, characters); CircularShift circularShift = new CircularShiftImpl(); circularShift.setup(characters); Alphabetizer alphabetizer = new AlphabetizerImpl(); alphabetizer.alph(circularShift); Output output = new Output(); output.output(fOutput, alphabetizer); //将结果直接输出 try { FileReader frInput = new FileReader(fInput); FileReader frOutput = new FileReader(fOutput); BufferedReader brInput = new BufferedReader(frInput); BufferedReader brOutput = new BufferedReader(frOutput); System.out.println("-----------------------Solution 3: ADT------------------------"); System.out.println("---------------Input---------------"); while(brInput.ready()) { System.out.println(brInput.readLine()); } System.out.println("--------------Output---------------"); while(brOutput.ready()) { System.out.println(brOutput.readLine()); } brInput.close(); brOutput.close(); frInput.close(); frOutput.close(); } catch (IOException e) { e.printStackTrace(); } } }
/** * */ package adtstyle; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; /** * * @author cx * */ public class Input { private FileReader fr; private BufferedReader br; /** * 每读取一行就用Characters抽象数据类型将该行存放,直到文件读完为止 * @param fInput 输入文件 * @param characters 存放读到的每行的数据 */ public void input(File fInput, Characters characters) { try { fr = new FileReader(fInput); br = new BufferedReader(fr); while(br.ready()) { characters.addLine(br.readLine()); } br.close(); fr.close(); } catch(IOException e) { e.printStackTrace(); } } }
/** * */ package adtstyle.impl; import java.util.ArrayList; import java.util.List; import adtstyle.LineStorage; /** * @author cx * */ public class LineStorageImpl implements LineStorage{ private List<String[]> lines = new ArrayList<String[]>(); public void addLine(String[] line) { lines.add(line); } public void addWord(int lineIndex, String word) { String[] curLine = lines.get(lineIndex); String[] newLine = new String[curLine.length + 1]; for(int i = 0; i < newLine.length - 1; i++) { newLine[i] = curLine[i]; } newLine[newLine.length - 1] = word; lines.set(lineIndex, newLine); } public void deleteLine(int lineIndex) { lines.remove(lineIndex); } public void deleteWord(int lineIndex, int wordIndex) { String[] curLine = lines.get(lineIndex); String[] newLine = new String[curLine.length - 1]; for(int i = 0; i < wordIndex; i++) { newLine[i] = curLine[i]; } for(int j = wordIndex; j < newLine.length; j++) { newLine[j] = curLine[j + 1]; } lines.set(lineIndex, newLine); } public void deleteWord(int lineIndex) { deleteWord(lineIndex, lines.get(lineIndex).length - 1); } public String[] getLine(int lineIndex) { return lines.get(lineIndex); } public String getLineAsString(int lineIndex) { String[] curLine = lines.get(lineIndex); String newLine = ""; for(int i = 0; i < curLine.length; i++) { newLine += curLine[i]; if(i != curLine.length - 1) newLine += " "; } return newLine; } public int getLineCount() { return lines.size(); } public String getWord(int lineIndex, int wordIndex) { return lines.get(lineIndex)[wordIndex]; } public int getWordCount(int lineIndex) { return lines.get(lineIndex).length; } public void insertLine(int lineIndex, String[] line) { lines.add(lineIndex, line); } public void insertWord(int lineIndex, int wordIndex, String word) { String[] curLine = lines.get(lineIndex); String[] newLine = new String[curLine.length + 1]; for(int i = 0; i < wordIndex; i++) { newLine[i] = curLine[i]; } newLine[wordIndex] = word; for(int j = wordIndex + 1; j < newLine.length; j++) { newLine[j] = curLine[j - 1]; } lines.set(lineIndex, newLine); } public void setLine(int lineIndex, String[] line) { lines.set(lineIndex, line); } public void setWord(int lineIndex, int wordIndex, String word) { String[] curLine = lines.get(lineIndex); curLine[wordIndex] = word; lines.set(lineIndex, curLine); } public void addLine(String line) { String[] words = line.split(" +|\t+"); List<String> list = new ArrayList<String>(); for(int i = 0; i < words.length; i++) list.add(words[i]); addLine(list.toArray(new String[0])); } public List<String[]> getAllLines() { return lines; } public void setAllLines(List<String[]> lines) { this.lines.clear(); this.lines = lines; } }
/** * */ package adtstyle.impl; import java.util.Comparator; import java.util.List; import adtstyle.Alphabetizer; import adtstyle.CircularShift; import adtstyle.LineStorage; /** * @author cx * */ public class AlphabetizerImpl implements Alphabetizer { private LineStorage lineStorage = new LineStorageImpl(); public AlphabetizerImpl() {} public AlphabetizerImpl(LineStorage lineStorage) { this.lineStorage = lineStorage; } public LineStorage getLineStorage() { return lineStorage; } public void setLineStorage(LineStorage lineStorage) { this.lineStorage = lineStorage; } public void addLine(String[] line) { lineStorage.addLine(line); } public void alph(CircularShift circularShift) {//快速排序 List<String[]> lines = circularShift.getAllLines(); qSort(lines, 0, lines.size() - 1, new Comparator<String[]>() { public int compare(String[] o1, String[] o2) { if(o1[0].compareToIgnoreCase(o2[0]) == 0) return 0; else if(o1[0].compareToIgnoreCase(o2[0]) > 0) return 1; else return -1; } }); setAllLines(lines); } public String[] getLine(int lineIndex) { return lineStorage.getLine(lineIndex); } public int getLineCount() { return lineStorage.getLineCount(); } public void setLine(int lineIndex, String[] line) { lineStorage.setLine(lineIndex, line); } public String getLineAsString(int lineIndex) { return lineStorage.getLineAsString(lineIndex); } public List<String[]> getAllLines() { return lineStorage.getAllLines(); } public void setAllLines(List<String[]> lines) { lineStorage.setAllLines(lines); } //下面是快速排序算法 public static <T> void qSort(List<T> a, int p, int r, Comparator<? super T> c) { if(p < r) { int q = partition(a, p, r, c); qSort(a, p, q - 1, c); qSort(a, q + 1, r, c); } } private static <T> int partition(List<T> a, int p, int r, Comparator<? super T> c) { int i = p; int j = r + 1; while (true) { while (c.compare(a.get(++i), a.get(p)) <= 0) if (i == r) break; while (c.compare(a.get(p), a.get(--j)) <= 0) if (j == p) break; if (i >= j) break; swap(a, i, j); } swap(a, j, p); return j; } private static <T> void swap(List<T> a, int i, int j) { T temp = a.get(i); a.set(i, a.get(j)); a.set(j, temp); } }
/** * */ package adtstyle; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; /** * @author cx * */ public class Output { private FileWriter fw; private BufferedWriter bw; /** * output方法迭代调用alphabetizer里面的方法得到按字母顺序排好序的行数据,并输出 * @param fOutput 输出文件 * @param alphabetizer 方便output方法调用alphabetizer里面的方法 */ public void output(File fOutput, Alphabetizer alphabetizer) { try { fw = new FileWriter(fOutput); bw = new BufferedWriter(fw); for(int i = 0; i < alphabetizer.getLineCount(); i++) { String line = alphabetizer.getLineAsString(i); bw.write(line); bw.write("\r\n"); } bw.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } }
/** * */ package adtstyle.impl; import adtstyle.Characters; import adtstyle.LineStorage; /** * @author cx * */ public class CharactersImpl implements Characters { private LineStorage lineStorage = new LineStorageImpl(); public CharactersImpl() {} public CharactersImpl(LineStorage lineStorage) { this.lineStorage = lineStorage; } public LineStorage getLineStorage() { return lineStorage; } public void setLineStorage(LineStorage lineStorage) { this.lineStorage = lineStorage; } public void addLine(String[] line) { lineStorage.addLine(line); } public void deleteLine(int lineIndex) { lineStorage.deleteLine(lineIndex); } public String[] getLine(int lineIndex) { return lineStorage.getLine(lineIndex); } public String getLineAsString(int lineIndex) { return lineStorage.getLineAsString(lineIndex); } public int getLineCount() { return lineStorage.getLineCount(); } public void insertLine(int lineIndex, String[] line) { lineStorage.insertLine(lineIndex, line); } public void setLine(int lineIndex, String[] line) { lineStorage.setLine(lineIndex, line); } public void addLine(String line) { lineStorage.addLine(line); } }
4、显示结果:
二、管道/过滤器的风格
1、体系结构图:
2、简述体系结构各部件的主要功能,实现思想。
管道/过滤器模式是将组件分散并组合,头尾相连,由四个组件输入、循环移动、排序、输出构成。首先由输入发起而后组件的输出是下一个组件的输入,类似流水线的一种操作。
3、写出主要的代码
/** * */ package pipestyle; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; /** * 用管道/过滤器风格设计KWIC * @author CX * @version 2017年11月17日 */ public class PipeKwic { public static boolean is_completed = false; /** * @param args */ public static void main(String[] args) { try { File fInput = new File(System.getProperty("user.dir") + "\\input.txt"); File fOutput = new File("output.txt"); // System.out.println(System.getProperty("user.dir")); Pipe in_cs = new Pipe(); Pipe cs_al = new Pipe(); Pipe al_ou = new Pipe(); Input input = new Input(fInput, in_cs); // input.transform(); CircularShift shift = new CircularShift(in_cs, cs_al); // shift.transform(); Alphabetizer alpha = new Alphabetizer(cs_al, al_ou); // alpha.transform(); Output output = new Output(al_ou, fOutput); // output.transform(); input.start(); // run it ! shift.start(); alpha.start(); output.start(); // 将结果直接输出 FileReader frInput = new FileReader(fInput); FileReader frOutput = new FileReader(fOutput); BufferedReader brInput = new BufferedReader(frInput); BufferedReader brOutput = new BufferedReader(frOutput); System.out.println("-----------------------Solution 1: Pipe/Filter------------------------"); System.out.println("---------------Input---------------"); while(brInput.ready()) { System.out.println(brInput.readLine()); } System.out.println("--------------Output---------------"); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } while(brOutput.ready()) { System.out.println(brOutput.readLine()); } brInput.close(); brOutput.close(); frInput.close(); frOutput.close(); } catch (Exception e) { e.printStackTrace(); } } }
/** * */ package pipestyle; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /** * 按行读取数据,传递给下一模块 * @author cx * @version 2017年11月17日 */ public class Input extends Filter { private FileReader fr; public Input(File fInput, Pipe output) { super(null, output); try { fr = new FileReader(fInput); } catch (FileNotFoundException e) { e.printStackTrace(); } } /** * 按行从输入文件fr中读取数据,并将数据写到输出管道output中 */ @Override protected void transform() { BufferedReader br = new BufferedReader(fr); try { String line; while((line = br.readLine()) != null) { // System.out.println("input"); // System.out.println(line); output.write(line + '\n'); //加入换行是以便下个模块的处理 } br.close(); fr.close(); output.closeWriter(); } catch (IOException e) { e.printStackTrace(); } } }
/** * */ package pipestyle; import java.io.CharArrayWriter; import java.io.IOException; /** * 第一行数据到来后开始运作 * 把原始数据行循环移位,将原始行和新的移位后的行输出给下一模块 * @author cx * @version 2017年11月17日 */ public class CircularShift extends Filter { private static final String ignore = "a#$an#$and#$as#$is#$the#$of#$"; //一些噪音词汇 public CircularShift(Pipe input, Pipe output) { super(input, output); } /** * */ @Override protected void transform() { try { CharArrayWriter writer= new CharArrayWriter(); //缓冲当前行 int c = -1; while((c = input.read()) != -1) { if(c == 10) { //回车,表示writer中取得了一行数据 String curLine = writer.toString();//存储从输入管道中取得的当前行 String[] words = curLine.split(" +|\t+"); //将当前行分解成多个单词 for(int i = 0; i < words.length; i++) { if(ignore.indexOf((words[i] + "#$").toLowerCase()) != -1)//去掉噪音词汇打头的行 continue; String shift = ""; for(int j = i; j < (words.length + i); j++) { shift += words[j % words.length]; if (j < (words.length + i - 1)) shift += " "; } shift += "\r\n"; output.write(shift); writer.reset(); } } else writer.write(c); } input.closeReader(); output.closeWriter(); } catch (IOException e) { e.printStackTrace(); } } }
/** * */ package pipestyle; import java.io.CharArrayWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * @author cx * */ public class Alphabetizer extends Filter { public Alphabetizer(Pipe input, Pipe output) { super(input, output); } /** * */ @Override protected void transform() { List<String> lines = new ArrayList<String>(); CharArrayWriter writer = new CharArrayWriter(); try { int c = -1; while((c = input.read()) != -1) { writer.write(c); // System.out.print((char) c); if(c == 10) { String curLine = writer.toString(); lines.add(curLine); writer.reset(); } } sort(lines); for(String s : lines) { output.write(s); } input.closeReader(); output.closeWriter(); } catch (IOException e) { e.printStackTrace(); } } private void sort(List<String> lines) { //堆排序 int size = lines.size(); for (int i = (size / 2 - 1); i >= 0; i--) siftDown(lines, i, size); for (int i = (size - 1); i >= 1; i--) { Object tmp = lines.get(0); lines.set(0, lines.get(i)); lines.set(i, (String) tmp); siftDown(lines, 0, i); } } private void siftDown(List<String> lines, int root, int bottom) { int max_child = root * 2 + 1; while (max_child < bottom) { if ((max_child + 1) < bottom) if (((String) lines.get(max_child + 1)) .compareTo((String) lines.get(max_child)) > 0) max_child++; if (((String) lines.get(root)).compareTo((String) lines .get(max_child)) < 0) { Object tmp = lines.get(root); lines.set(root, lines.get(max_child)); lines.set(max_child, (String) tmp); root = max_child; max_child = root * 2 + 1; } else break; } } }
/** * */ package pipestyle; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; /** * @author cx * */ public class Output extends Filter { private FileWriter fw; /** * @param input 输入管道 * @param output 输出文件 */ public Output(Pipe input, File fOutput) { super(input, null); try { fw = new FileWriter(fOutput); } catch (IOException e) { e.printStackTrace(); } } /** * */ @Override protected void transform() { BufferedWriter bw = new BufferedWriter(fw); try { int c = -1; while((c = input.read()) != -1) { bw.write(c); } input.closeReader(); bw.flush(); bw.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } }
4、显示结果