- - PR -
File Structure#2
1
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2003-03-16 11:20
また、分かりにくい質問ですが、HeapAreaとRecordクラスをテストしたところ、この二つのクラスはちゃんと走るのですが、Distributorのクラスを使って、ファイルの読み書きをすると、infinite loopに入ってしまいます。原因は、レコードの読み込みと書き込みにあり、HeapAreaが値を受け取らないためです。どうしたら、Heapを作ることができるのでしょうか。
このクラスが問題 ヒープが値を受け取りません。 public class Distributor { public Distributor(String inFile, String filePref, int n, int mSize,Sortable seedRec) { this.bSize=mSize; this.fib = new Fibonacci(n); this.heap= new HeapArea(this.bSize); try{ this.inStream = new BufferedReader(new FileReader(inFile)); this.outStream=new BufferedOutputStream[n]; for(int i=0;i<n;i++){ String filename=filePref+(i+1); this.outStream[i]= new BufferedOutputStream(new FileOutputStream(filename),this.bSize);//buffer sizeを指定します。 } inStream.close(); }catch(FileNotFoundException e){ }catch(IOException e){ } this.seedRec=seedRec; this.runs=n; }//end of constructor /** * The main control flow of the replacement selection algorithm in this. */ public void distribute(){ try{ int[] tally =new int[this.runs]; int[] go = this.fib.next(); this.seedRec.readObject(this.inStream);//レコード読み込み while(!this.seedRec.isSeparator(this.seedRec)){ for(int i = 0; i <this.runs ; i++){ while(go[i]-tally[i]>0){ this.heap = new HeapArea(this.bSize);//ここでsalaryの高い順に整列 this.heap.put(this.seedRec);//値を置いていく Sortable nextItem; Sortable outputItem = this.heap.findMax(); while(this.heap.getSize()> 0){//この部分でinfinite loopに入ってしまいます。 if(this.heap.findMax().compareTo(outputItem)>0){ outputItem = this.heap.deleteMax(); this.seedRec.writeObject(this.outStream[i]); if( this.inStream.ready()){// data in the input stream nextItem = this.seedRec.createObject(); if(nextItem.compareTo(outputItem)<0||nextItem.compareTo(outputItem)==0){ this.heap.insert(nextItem); }else{ seedRec.writeSeparator(this.outStream[bSize]); this.heap.toss(nextItem); }//end of else tally[i]++; System.out.println(tally[i]); }//end of ready }//end of comp }//end of while(primary Heap size<= 0) int n = this.heap.getSAreaSize();//secondary areaにある値をprimary areaへ押し上げる this.heap.fixHeap(n); }//end of while(go - pos) }//end of runs }//end of while(isSeparator) }catch(Exception e){ e.printStackTrace(); } }//end of distribute ヒープのクラス Distributorクラスがなければ上手く走る public class HeapArea { /** * param size is the capacity(number of records) of the heap area. */ public HeapArea(int size) { this.size = size; this.hSize=0; this.sSize=0; this.inOrder = true; getArray(this.size-1); this.area[ 0 ] = null; } /** * Insert into the primary heap, maintaining heap order. * x the item to insert. * exception: * NotInOrder if the primary heap has not been established */ public void insert(Sortable x)throws NotInOrder{ if(!this.inOrder){ put(x); return; } checkSize(); // Percolate up int hole = ++this.hSize; area[ 0 ] = x; for( ; x.compareTo(area[ hole / 2 ] ) > 0; hole /= 2 ) area[ hole ] = area[ hole/2 ]; area[ hole ] = x; } /** * Insert into the heap area, without maintaining heaporder. * @param x the item to insert. */ public void put(Sortable x){ //checkSize(); hSize=hSize+1; area[hSize]=x; //this.area[++this.hSize]=x; if(hSize>=2){ if((x.compareTo(this.area[this.hSize/2])) > 0) this.inOrder=false; } } /** * Insert into the secondary area(without maintaining heap order. * x the item to insert */ public void toss(Sortable x){ checkSize(); this.area[++this.sSize]=x; this.inOrder=false; } /** * Find the greatest item in the heap. * ensure: * return the greatest item. * exception: * Underflow if the primary heap heap is logically empty, false otherwise. */ public Sortable findMax()throws Underflow, NotInOrder{ if(this.isEmpty()) throw new Underflow("Empty binary heap"); if(!this.inOrder) fixHeap(); return this.area[1]; } /** * Remove the greatest item from the primary heap and adjust the heap * @return the greatest item. * @exception: * Underflow if the primary heap is empty, or NotInOrder if the primary * heap has not been fixed. */ public Sortable deleteMax() throws Underflow, NotInOrder{ Sortable maxItem = findMax(); area[1]=area[this.hSize--]; percolateDown(1); return maxItem; } /** * Re-establish the heap order for the data collection in the area in linear time. */ public void fixHeap(){ for( int i = this.hSize / 2; i > 0; i-- ) percolateDown( i ); inOrder = true; } /** * Re-establish the heap order for the size n at the beginning of the array * for the items in the last n cells in linear time. */ public void fixHeap(int n){ if(n !=size){ if(n>=size/2){ for(int i=1;i<=sSize-n;i++) put(area[area.length-i]); } hSize=n; sSize=0; fixHeap(); } } /** * ensure: * return true if the primary heap is logically empty, false otherwise. */ public boolean isEmpty(){ return hSize==0; } /** * Make the entire array including the heap logically empty. */ public void makeEmpty(){ this.hSize=this.sSize=0; } /** * @reutrn the number of node in the primary heap. * exception: * NotInOrder id the primary heap not been established. */ public int getPHeapSize()throws NotInOrder{ return this.hSize+1; } /** * @return the number of nodes in the secondary storage area. */ public int getSAreaSize(){ return this.sSize; } public int getSize(){ return this.size; } /** * Internal method to percolate down in the heap. * @param hole the index at which the percolate begins. */ private void percolateDown(int hole){ int child; Sortable tmp = area[hole]; for( ; hole*2 <= hSize ; hole = child){ child = hole*2; if(child != hSize && (area[child+1].compareTo(area[child])>0)) child++; if(area[child].compareTo(tmp)>0) this.area[hole]=this.area[child]; else break; } this.area[hole]=tmp; } /** * Private method to allocate the heap array. * Includes an extra spot for the sentinel. * @param newMaxSize the capacity of the heap. */ private void getArray( int newMaxSize ){ this.area = new Sortable[ newMaxSize + 1 ]; } /** * Private method that doubles the heap array if full. */ private void checkSize( ) { if( this.hSize == area.length - 1 ) { Sortable [ ] oldArray = area; this.getArray( hSize * 2 ); for( int i = 0; i < oldArray.length; i++ ) this.area[ i ] = oldArray[ i ]; } } private int hSize;//Number of elements in heap private int sSize;//Number of items the secondary area private boolean inOrder;//True if heap order is guaranteed in the primary heap private Sortable[] area;//The array holding heap and secondary area private int size; } //このクラスは出来上がり public class Fibonacci { public Fibonacci(int k) { this.order=k; init(); } public int[] next(){ int tmp = this.array[0]; //first number of the fibonacci for(int i=0; i < this.array.length-1 ; i++) { //add the numbers array[i] = tmp + array[i+1]; } this.array[array.length-1]=tmp; return array; } public void display(){ for(int i=0; i<this.array.length; i++){ System.out.println(this.array[i]); } } public void init(){ this.array = new int[this.order]; for(int i=1; i < this.order ; i++){ array[i]=0; } array[0]=1; } //インターフェース、Recordクラスでimplementする public interface Sortable { public int compareTo(Sortable obj);//return negative 0, or positive if this<,=orobj public Sortable createObject();//the factory method public boolean isSeparator(Sortable obj);//return true if obj is a separator record public void readObject(Reader r)throws IOException;//to read from raw data file public void readObject(InputStream is)throws IOException;//to read from runs public void writeObject(OutputStream os)throws IOException; public void writeSeparator(OutputStream os)throws IOException; public String toString();//to a format for display } //レコードクラス おかしいところはないように思われる。 public class Record implements Sortable{ private int id; private float salary; private String name; public Record() { super(); } public Record(int id, float salary, String name) { this.id = id; this.salary = salary; this.name = name; } public int getID(){ return this.id; } public float getSalary(){ return this.salary; } public String getName(){ return this.name; } public int compareTo(Sortable obj) { Record r = (Record)obj; return (int)(this.salary - r.salary); } public String toString() { return (getID() +" "+ getSalary() +" "+ getName()); } public void readObject(InputStream is)throws IOException{//to read from runs DataInputStream dis = new DataInputStream(is); this.id=dis.readInt(); this.salary=dis.readFloat(); int nameCount=dis.readInt(); this.name = DataIO.readFixedString(4,dis); } public void readObject(Reader r)throws IOException{ String s=""; try{ BufferedReader br = new BufferedReader(r); s= br.readLine(); if(s==null) return; StringTokenizer lineTokenizer = new StringTokenizer(s); int id = Integer.parseInt(lineTokenizer.nextToken()); float salary = Float.parseFloat(lineTokenizer.nextToken()); String name = lineTokenizer.nextToken(); }catch(IOException e){} } public boolean isSeparator(Sortable obj){ Record rd=(Record)obj; return (rd.salary == -1); } public void writeObject(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); try { dos.writeInt(this.id); dos.writeFloat(this.salary); dos.write(this.name.length()); dos.writeChars(this.name); } catch (Exception e) { //throw e; } } public void writeSeparator(OutputStream os)throws IOException{ DataOutputStream dos = new DataOutputStream(os); String s = "|"; try { dos.writeInt(-1); dos.writeFloat(-1); dos.write(-1); dos.writeChars(s); dos.flush(); } catch (Exception e) { //throw e; } } public Sortable createObject(){//the factory method return new Record(this.id,this.salary,this.name); } } |
1
