130242014039-刘鑫-第3次实验

一、实验目的

1.理解不同体系结构风格的具体内涵。

2.学习体系结构风格的具体实践。

 

二、实验环境

硬件: (依据具体情况填写)

软件:Java或任何一种自己熟悉的语言

 

三、实验内容

上下文关键字”KWIC(Key Word in Context,文本中的关键字)检索系统接受有序的行集合:每一行是单词的有序集合;每一个单词又是字母的有序集合。通过重复地删除航中第一个单词,并把它插入行尾,每一行可以被循环地移动KWIC检索系统以字母表的顺序输出一个所有行循环移动的列表。

 

四、实验步骤:

1、体系结构图:

 

 

2

a.主程序子程序风格

b.简述体系结构各部件的主要功能,实现思想。

上述的主程序/子程序的方法,将问题分解为输入(InputStore)、移动(CircleShifter)、按字母表排序(Alphabetizer)、输出(Outputer)

InputStore : 该类处理读取文件数据,并输出到控制台。

CircleShifter : 该类实现循环移位。

Alphabetizer : 主该类对行数据进行按字母顺序排序

Outputer: 主函数调用该方法,输出到控制台

c.代码:

 

//InputStore输入类
package edu.nju.eureka;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 
 * 输入
 */
public class InputStore {

    private ArrayList<String> textLines;
    
    //对textLines进行初始化
    public InputStore(String filePath) {
        textLines = new ArrayList<String>();
        String line = new String();
        BufferedReader reader;
        try{
            reader = new BufferedReader(new FileReader(filePath));
            while((line=reader.readLine())!=null){
                textLines.add(line);
            }
            reader.close();
        }catch(IOException e){
            System.out.println("Input File Does Not Exsit!");
        }
    }
    
    //对外提供的接口
    public ArrayList<String> getTextLines(){
        return this.textLines;
    }
}

 

/**
 * CircularShifter 循环移位类
 */
package edu.nju.eureka;

import java.util.ArrayList;

/**
 * 
 * 循环移位
 */
public class CircularShifter {
    
    private ArrayList<String> shirtedLines;
    
    public CircularShifter() {
        shirtedLines = new ArrayList<String>();
    }
    
    
    private ArrayList<Integer> getShiftPosition(InputStore inputStore) {
        
        ArrayList<Integer> shiftedLineIndexes = new ArrayList<Integer>();
        
        //用来计数左移一次开始单词的position
        int counter = 0;
        for(int i=0;i<inputStore.getTextLines().size();i++){
            //每行开头需要记录
            shiftedLineIndexes.add(counter);
            for(int j=0;j<inputStore.getTextLines().get(i).length();j++){
                
                if((inputStore.getTextLines().get(i).charAt(j)==' ')&&(inputStore.getTextLines().get(i).charAt(j+1)!=' ')){
                    shiftedLineIndexes.add(counter+1);
                }
                
                counter++;
            }
        }
        return shiftedLineIndexes;
    }
    
    public void shift(InputStore inputStore) {
        
        ArrayList<Integer> shiftedLineIndexes = getShiftPosition(inputStore);
        
        int lengthCounter = 0;
        int j = 0;
        
        for(int i=0;i<inputStore.getTextLines().size();i++){
            
            lengthCounter = lengthCounter + inputStore.getTextLines().get(i).length();
            
            while(shiftedLineIndexes.get(j)<lengthCounter){
                
                char[] newStr = new char[inputStore.getTextLines().get(i).length()+1];
                int charSet = 0;
                
                //赋值
                for(int x = shiftedLineIndexes.get(j) - lengthCounter + inputStore.getTextLines().get(i).length();x<inputStore.getTextLines().get(i).length();x++){
                    newStr[charSet] = inputStore.getTextLines().get(i).charAt(x);
                    charSet++;
                }
                
                if(inputStore.getTextLines().get(i).length()- lengthCounter + shiftedLineIndexes.get(j)!=0){
                    newStr[charSet] = ' ';
                    charSet++;
                }
                
                for(int x = 0; x <(inputStore.getTextLines().get(i).length()- lengthCounter + shiftedLineIndexes.get(j));x++){
                    newStr[charSet] = inputStore.getTextLines().get(i).charAt(x);
                    charSet++;
                }
                shirtedLines.add(new String(newStr));
                
                j++;
                
                //如果所有位置记录都已经被遍历,则跳出
                if(j>=shiftedLineIndexes.size()){
                    break;
                }        
                
            }
        }
    }
    
    public ArrayList<String> getShiftedLines() {
        return this.shirtedLines;
    }
}
/**
 * Alphabetizer 字母排序类
 */
package edu.nju.eureka;

import java.util.ArrayList;
import java.util.Collections;

/**
 * 
 *  按字母排序
 */
public class Alphabetizer {

    private ArrayList<String> sortedLines;
    
    public Alphabetizer() {
        sortedLines = new ArrayList<String>();
    }
    
    public void sort(CircularShifter circularShifter) {
        Collections.sort(circularShifter.getShiftedLines());
        for(int x = 0;x<circularShifter.getShiftedLines().size();x++) {
            sortedLines.add(circularShifter.getShiftedLines().get(x));
        }
    }
    
    public ArrayList<String> getSortedLines(){
        return sortedLines;
    }
}
/**
 * Outputer 输出类
 */
package edu.nju.eureka;

/**
 * 输出类
 *
 */
public class Outputer {
    
    public void printKWIC(Alphabetizer alphabetizer) {
        for(int x = 0;x<alphabetizer.getSortedLines().size();x++){
            System.out.println(alphabetizer.getSortedLines().get(x));
        }
    }
}
/**
 * MainTest 主程序类
 */
package edu.nju.eureka;

/**
 *
 * 主程序类
 */
public class MainTest {

    public static void main(String[] args) {
        InputStore inputStore = new InputStore("Text.txt");
        CircularShifter circularShifter = new CircularShifter();
        circularShifter.shift(inputStore);
        Alphabetizer alphabetizer = new Alphabetizer();
        alphabetizer.sort(circularShifter);
        Outputer outputer = new Outputer();
        outputer.printKWIC(alphabetizer);
    }

}

 

 

3.

a.管道-过滤器模式

 

b.代码

 

/**
 *  Filter 过滤器
 */
package pipestyle;

/**
 * 过滤器有输入管道和输出管道两个组件。
 * 过滤器将输入管道的数据转换成要求的数据,并将转换好的数据写到输出管道。
 * 输入管道和输出管道是相对的,即在某个阶段输出管道接收数据,在下一阶段,
 * 输出管道便提供数据,成为输入管道,输入管道同理。每个过滤器在它的线程
 * 空间中运行
 */
public abstract class Filter implements Runnable {

    protected Pipe input;
    protected Pipe output;
    private boolean is_started = false;
    
    /**
     * 默认构造器
     * @param input 输入管道
     * @param output 输出管道
     */
    public Filter(Pipe input, Pipe output) {
        this.input = input;
        this.output = output;
    }
    
    /**
     * 调用之后则线程开始执行
     */
    public void start() {
        if(!is_started) { //防止多次调用
            is_started = true;
            Thread thread = new Thread(this);
            thread.start();
        }
    }
    
    /**
     * 线程的run方法
     */
    public void run() {
        transform();
    }
    
    /**
     * 该方法将输入管道的数据转换成要求的数据,并将转换好的数据写到输出管道
     * 子类实现该抽象方法
     */
    abstract protected void transform();
}

 

 

 

 

/**
 * Input 输入
 */
package pipestyle;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * 按行读取数据,传递给下一模块
 * 
 */
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) {
                output.write(line + '\n'); //加入换行是以便下个模块的处理
            }
            br.close();
            fr.close();
            output.closeWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

/**
 * Pipe管道
 */
package pipestyle;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;

/**
 * 一个管道对象将两个读写数据流连接起来,写数据流可以向管道中写入数据,
 * 读数据流则可以在管道中有可用数据的时候读出数据
 */
public class Pipe {

    private PipedWriter pipedWriter;
    private PipedReader pipedReader;
    /**
     * 默认构造器,初始化读和写管道,并建立它们之间的连接
     * @throws IOException 如不能建立连接则抛出IO异常
     */
    public Pipe() throws IOException {
        pipedReader = new PipedReader();
        pipedWriter = new PipedWriter();
        pipedReader.connect(pipedWriter);
    }
    
    /**
     * 从管道中读一个字符
     * @return 读取到的一个字符
     * @throws IOException 如不能从管道中读则抛出异常
     */
    public int read() throws IOException {
        return pipedReader.read();
    }
    
    /**
     * 向管道写一个字符
     * @param c 要写入的字符
     * @throws IOException 如不能向管道写则抛出异常
     */
    public void write(int c) throws IOException {
        pipedWriter.write(c);
    }
 
    /**
     * 写入字符串的某一部分
     * @param s 要写入的字符串
     * @param off 开始读取字符处的偏移量
     * @param len 要写入的总字符数
     * @throws IOException 如不能写入数据则抛出异常
     */
    public void write(String s, int off, int len) throws IOException {
        pipedWriter.write(s.toCharArray(), off, len);
    }
    
    /**
     * 写入整个字符串
     * @param s 要写入的字符串
     * @throws IOException 如不能写入数据则抛出异常
     */
    public void write(String s) throws IOException {
        pipedWriter.write(s.toCharArray());
    }
    
    /**
     * 将读管道关闭,调用该方法后,不能再从管道中读数据
     * @throws IOException 如不能关闭则抛出异常
     */
    public void closeReader() throws IOException {
        pipedReader.close();
    }
    /**
     * 将写管道关闭,调用该方法后,不能向管道中写数据
     * @throws IOException 如不能关闭则抛出异常
     */
    public void closeWriter() throws IOException {
        pipedWriter.flush();
        pipedWriter.close();
    }
    
}

 

 

/**
 * CircularShift 循环移位
 */
package pipestyle;

import java.io.CharArrayWriter;
import java.io.IOException;

/**
 * 第一行数据到来后开始运作
 * 把原始数据行循环移位,将原始行和新的移位后的行输出给下一模块
 */
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();
        }
    }

}

 

/**
 * Alphabetizer 按字母排序
 */
package pipestyle;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


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;
        }
    }

}
/**
 * Output 输出
 */
package pipestyle;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 *
 */
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();
        }
    }

}
/**
 * PipeKwic 
 */
package pipestyle;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

/**
 * 用管道/过滤器风格设计KWIC
 */
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);
            CircularShift shift = new CircularShift(in_cs, cs_al);
            Alphabetizer alpha = new Alphabetizer(cs_al, al_ou);
            Output output = new Output(al_ou, fOutput);
            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();
        }
    }

}

 

posted @ 2017-11-19 21:19  Nathan刘鑫  阅读(278)  评论(0编辑  收藏  举报