2

我正在编写一个程序来模拟内存碎片。输入文件告诉什么时间段需要输入。

一个示例文件是:

ñ  
C 200  
1 2 3  
2 3 4  
磷 2 3 1  
R  
乙

whereC是内存大小,P是顺序中的段(大小,开始时间和寿命),并且R(应该)打印出一份报告,显示内存中的哪些段,任何孔以及在哪里。

这个赋值的规则之一是创建事件的链表,其中段的插入和删除被创建为事件,我需要遍历事件列表。更新:我有一些不同的东西,但我确定它不会将我的事件插入到事件列表中。我不明白为什么。有谁知道我的逻辑在哪里?

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class TestEventList{
    public static void main(String[] args){
    //read file
    File file = new File("b.txt");

    try {
        Scanner scanner = new Scanner(file);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();

            //send it to interpret file method:
            interpretFile(line);
        }
    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
    }  //end try-catch
}

public static void interpretFile(String command) {
    EventList evtList = new EventList();

    Scanner sc = new Scanner(command);


    char initialCommand = command.charAt(0);

    if (initialCommand == 'N') {
        System.out.println("Name");
    } else {
    }//end else
    //file error

    char commandCode = command.charAt(0);
    String skip = sc.next();  //skips next character to get to integers
    switch (commandCode) {
    case 'C':/*create Memory! which means, create Event!
                Form: Event(int startTime, Segment memSegment)*/
        int size = sc.nextInt();

        Segment defaultMemoryNode = new Segment(size, 100, false );
        /*create event node*/
        Event insertDefaultNode = new Event(0, defaultMemoryNode);
        /*insert this event*/
        evtList.insertEvent(insertDefaultNode);

        break;

    case 'P':

            int segmentSize = sc.nextInt();
            int segmentStart = sc.nextInt();
            int segmentLife = sc.nextInt();

            int segmentExpiration = segmentLife + segmentStart;

            Segment memorySegment = new Segment(segmentSize, segmentExpiration, true );
            Event addSegment = new Event(segmentStart, memorySegment);
            evtList.insertEvent(addSegment);

            memorySegment.occupied = false;

            Event removeSegment = new Event(segmentExpiration, memorySegment);
            evtList.insertEvent(removeSegment);

            break;

    case 'R':
        evtList.traverseEventList();

        break;
    case 'E':
        System.exit(0);
        }//end switch

}//end interpretfile method
}  //end class T.E.L.

/*This class has-a Linked List, has-a memoryNode, has-a Segment*/
class MemoryList{

 private Node memoryNode = new Node();
 private Segment memorySegment = new Segment();
 private LinkedList memoryList = new LinkedList();
 Node head;
 Node current;

public MemoryList(){
   super();
}
   /*define blocks and holes*/
   public void insertBlock(Segment memorySegment) {
    current = head;
    if (current == null) {
        memoryList.Add(memorySegment);
        System.out.println(memorySegment.size);
        }
    else {
        System.out.println("Checking for room");
        System.out.println(current.getSize());
        int invalidFit=0;
        if(current.getStatus() == false && current.getSize()>=memorySegment.size){
            System.out.println("Verified space");
            int freeSpace = current.getSize() - memorySegment.size;
            memoryList.Add(memorySegment);
            createHole(freeSpace);
            current = current.next;
         }  //end if
         else {
            current = current.next;

        } //end else
    }//end else
  }  //end insert block

  public void removeBlock(Segment expiredSegment){
    current = head;
    //search for segment

    while(current.next != null){
        if(current.getTimetoLeave() == expiredSegment.timeToLeave
                && current.getSize() == expiredSegment.size){

        memoryList.Remove(expiredSegment);
        int freespace = expiredSegment.size;
        createHole(freespace);
    }
        else{
            current = current.next;
        }
    }//end while
}

    private void createHole(int space) {
    Node hole = new Node(space, 100, false);
    memoryList.Add(hole);
    //test if there are two holes together. if so, mergeHoles.
    }

   *Merge 2 Consecutive Holes*/
   private void mergeHoles(Node a, Node b) {
   //getPrev(a);  //find previous of node a
   //use the size through the end of a's prev to
   //get start of prev.next (a)+

   //make a point to b.next?
  } //end mergeHoles

  public void traverseMemoryList(){
    current = head;

    if(current == null){
        System.out.println("Memoryless");
    }
    else{
        while(current.next != null){
            if(memoryNode.getStatus() == false){
                System.out.println("Hole");
                current = current.next;
            }
        }
        System.out.println("Segment of size " + current.getSize());
        current = current.next;
    }
   }

} //end MemoryList

class MemoryNode extends Node{
   public MemoryNode(){
    super();
   }


}
class Segment{
  int size;
  int timeToLeave;
  boolean occupied;

  /*constructor*/
  public Segment(){

  }

public Segment(int newSize, int newTime, boolean isOccupied){
    this.size = newSize;
    this.timeToLeave = newTime;
    this.occupied = isOccupied;
 }

}

class Node {
     private int size;
     private int timeToDepart;
     boolean occupied;  // True if segment, false if hole
     Node next;
     public Object data;  //data in a node

    public Node() {
    }

    public Node(int segmentSize, int timeToLeave, boolean type) {
    this.size = segmentSize;
    this.timeToDepart = timeToLeave;
    this.occupied = type;

    }

    public int getSize() {
    return size;
    }

    public void setSize(int segmentSize) {
        size = segmentSize;
    }

    public int getTimetoLeave() {
        return timeToDepart;
    }

     public void setTimetoLeave(int timeToLeave) {
            timeToDepart = timeToLeave;
    }

    public void setStatus(boolean type) {
        occupied = type;
    }

    public boolean getStatus() {
        return occupied;
    }

}  //end Node

/* class LL has-a Node*/
class LinkedList{
  private Node listNode= new Node();

   Node current;
   Node head;
   Node prev;

   int size;

/*Constructors:*/
public LinkedList() {
    super();
}

public LinkedList(int j, int k, boolean l) {
    super();  //essentially the same as a node
}

/*LL proprietary methods*/
 /*test if the list is empty, to avoid NullPointerException*/
public boolean isEmpty() {
    return head == null;
}
//insert method:

public void Add(Object data1) {
    listNode.data = data1;

    /*special case: list is empty*/
    if (isEmpty()) {
        listNode.next = head;
        head = listNode;
        head.data = listNode.data;
    }

    else{
        current = head;

        while(current.next != null)
    {
        current.data = data1;
        current.next = null;
        head = current;
    }
        current.data = data1;
        current.next = head; //newNode now points to head
        head = current;      //now newNode is the head
    }
}

public void Remove(Object delData) {
    /*pointers*/

    //special case: if head is the removed node;
    if (current.data == delData) {
        head = current.next;
    } else {
        prev = head;  //it's not the head, keep moving.
        current = current.next;

        while (current.next != null) {  //reached end of list
            if (current.data == delData) {      //if
                prev.next = current.next;       //just skip the current node
            } else {
                prev = current;          //now prev is that node
                current = current.next;  //current is the next node

            }
        }  //end while
        //what if current.next = null (it's at the end)?
        if (current.next == null && current.data == delData) {
            prev.next = null;

        }
    }//end else
}
public void traverse(){
    if(head== null){
        System.out.println("no elements to show");
    }
else{
    current = head;
    while(current.next != null){
        current = current.next;
    }

  }}
  }// end LL class

 /*class EventList has-an Event, is-a LinkedList*/
class EventList{
   private Event event = new Event();
   private LinkedList evtList = new LinkedList();
   private MemoryList memList = new MemoryList();
   Node current;
   Node head;
   int time;  //set to the most recent time

   /*constructor*/
   public EventList(){
    super();

  }

  public void actionOfEvent(Event event1){
    Segment p = event.getMemorySegment();
    if(p.occupied == true){
        insertSegment(event1);
    }
    else
        removeSegment(event1);
   }

  //a linked list to control creation of events
  public void insertEvent(Event event) {
    current = head;
    if(current == null){

        evtList.Add(event);
        System.out.println("Added 1st event " + event.startTime);
    }
    else{
        while(current.next != null){
            if(event.startTime <= event.getTime()){
                //if the event start was before the current time...
                evtList.Add(event);
                current = current.next;
            }
            else{
                current = current.next;
            }

        }//end while
        evtList.Add(event);
        System.out.println("Added 2nd event");
    }
   }//end insertEvent

  public void traverseEventList(){
    current = head;

    if(current == null){
        System.out.println("At time " + event.getTime());
        System.out.println("uneventful");
       }
    else{
        while (current.next != null){
        Segment segment1 = event.getMemorySegment();
        if(segment1.occupied = true){
            memList.insertBlock(segment1);
            System.out.println(segment1.size + " inserted");
        }

        else{
            memList.removeBlock(segment1);
            System.out.println(segment1.size + " removed from memory.");
        }


        }
      }
   }

  public void insertSegment(Event addEvent){
    addEvent.getMemorySegment();
    memList.insertBlock(addEvent.getMemorySegment());
    }
  public void removeSegment(Event expEvent){

}

} //end eventList

 /*class Event is-a Node*/
class Event{

   int startTime;
   Segment memoryNode;
   int time;

   public Event(){
       super();
   }

   //pretty much the same as Node.
   public Event(int newStartTime, Segment newMemNode){
      super();
      this.startTime = newStartTime;
      this.memoryNode = newMemNode;
   }

   public void setTime(int newStartTime){
      time = newStartTime;
   }

   public int getTime(){
    return time;
   }

   public void setMemorySegment(Segment newMemNode){
       memoryNode = newMemNode;
   }

   public Segment getMemorySegment(){
       return memoryNode;
   }

}//end class Event

class Report{
   int currentTime= 0;


    //this creates and prints the segments/holes in the list at curTime

}    
4

2 回答 2

1

只是一些(其他)评论

设计

你使用了很多继承。这真的有必要吗?稍后,对于生产代码,您应该考虑使用组合而不是继承和针对接口的代码。这将消除许多丑陋的依赖关系并提高可维护性。现在你有

EventSequenceList is-a MemoryList is-a LinkedList is-a Node

仅从名称来看,我怀疑 LinkedList 真的是一个节点。我希望 在树或图中有一个节点,即使在那里它通常也是一个关系。

命名

有时您会打破 Java 命名约定:方法名称不应以大写字母开头(如Add)。有时您使用单字母变量名称(就像在大多数构造函数中一样)。

有时,方法名并不能告诉我们该方法实际上在做什么(例如iterpretFile它实际上不解释文件,而只解释可能已从文件中读取的单个命令)


我越看这个作业,我就越有感觉,你迟早会被你的设计卡住(迟早)。根据我阅读的内容,需要什么:

  • 一个事件模型类。一个类,表示插入或删除事件。
  • 一种内存模型类。一个类,代表整个内存
  • 一个段模型类。表示段的类。一个内存类一个列表或一个段数组
  • 一个包含所有事件的链表。此自定义链表可能能够在正确的位置插入事件
  • 一个报告课。可以创建和打印报告的类。
  • 一个输入文件解析器。它将使用输入
    • 创建一个内存类(具有适当数量的段)
    • P从行创建插入和删除事件
    • 在链表中插入事件

绝对不需要继承。


编辑 - 回应您的最后评论

一个内存有一个单元数组。单元格被索引,从 0 开始。它们没有链接,所以我实际上看不出有任何理由在LinkedList这里使用 a。内存模型可能如下所示:

public class Memory {
  private int[] cells;
  public Memory(int size) { cells = new int[size]; }
  public void store(int index, int value) { 
    if (index < 0 || index >= size) throw new IllegalArgumentException("..");
    cells[index] = value;
  }
  public int read(int index) {
    if (index < 0 || index >= size) throw new IllegalArgumentException("..");
    return cells[index];
  }
}

可以看作是内存的子类。在现实生活中,如果可能,内存管理器会向内存管理器请求一个段,然后管理器分配一个区域。段是完全独立的,它们之间没有链接,这里没有使用 LinkedList。快速草稿:

public class MemoryManager {
  private Memory managedMemory;
  public MemoryManager(Memory memory) { this.memory = memory; }
  public Segment getSegment(int size) {
    int startAddress = allocateSegment(int size);
    if (startAddress != -1) {
      return new Segment(this, startAddress, size);
    }
    return null;
  }
}

public class Segment extends Memory {
  private MemoryManager memoryManager;
  private int startAddress;  // usually - a handle, so that the memoryManager can
                             // relocate the segment - we keep it simple
  public Segment(MemoryManager memoryManager, int startAdress, int size) {
    super(size);
    this.memoryManager = memoryManager;
    this.startAddress = startAddress;
  }

现在回到事件。

这个赋值的规则之一是创建事件链表[ eventList = new EventList<Event>()] ,其中段的插入和删除被创建为事件[ new Event(EventType.INSERT, int time, Segment segment)); new Event(EventType.DELETE, int time, Segment segment);] ,我需要遍历事件列表[ for(Event event:eventList)]。

这就是任务。实现一个Event类,实现一个EventList类,实现一个小枚举EventType。挑战在于实现一种insert方法,在正确的位置(时间戳)EventClass为一行插入两个事件。P

于 2011-06-28T06:05:31.747 回答
1

我运行了你的代码,你似乎从来没有打电话:

setMemoryNode();

这导致 NullPointerExceptions。

还:

多个事件实例中的一些是由这些行引起的:

EventSequenceList expiredNode = new EventSequenceList(newMemNode,
1, expir, 1, true);
insertEvent(expiredNode);

当我看到更多时,我将对其进行编辑。

于 2011-06-28T05:59:22.207 回答