java平台作业7-2

7.2 存储器

There is little time left before the release of the first national operating system BerlOS. Some of its components are not finished yet — the memory manager is among them. According to the developers’ plan, in the first release the memory manager will be very simple and rectilinear. It will support three operations:

alloc n — to allocate n bytes of the memory and return the allocated block’s identifier x;
alloc pos n — to allocate n bytes of the memory from specified memory location pos and return the allocated block’s identifier x;
erase x — to erase the block with the identifier x;
defragment — to defragment the free memory, bringing all the blocks as close to the beginning of the memory as possible and preserving their respective order;
The memory model in this case is very simple. It is a sequence of m bytes, numbered for convenience from the first to them-th.

The first operation alloc n takes as the only parameter the size of the memory block that is to be allocated. While processing this operation, a free block of n successive bytes is being allocated in the memory. If the amount of such blocks is more than one, the block closest to the beginning of the memory (i.e. to the first byte) is prefered. All these bytes are marked as not free, and the memory manager returns a 32-bit integer numerical token that is the identifier of this block. If it is impossible to allocate a free block of this size, the function returns NULL.

The second operation erase x takes as its parameter the identifier of some block. This operation frees the system memory, marking the bytes of this block as free for further use. In the case when this identifier does not point to the previously allocated block, which has not been erased yet, the function returns ILLEGAL_ERASE_ARGUMENT.

The last operation defragment does not have any arguments and simply brings the occupied memory sections closer to the beginning of the memory without changing their respective order.

In the current implementation you are to use successive integers, starting with 1, as identifiers. Each successful allocoperation procession should return following number. Unsuccessful alloc operations do not affect numeration.

You are to write the implementation of the memory manager. You should output the returned value for each alloccommand. You should also output ILLEGAL_ERASE_ARGUMENT for all the failed erase commands.

Input
The first line of the input data contains two positive integers t and m (1 ≤ t ≤ 100;1 ≤ m ≤ 10000), where t — the amount of operations given to the memory manager for processing, and m — the available memory size in bytes. Then there follow tlines where the operations themselves are given. The first operation is alloc n (1 ≤ n ≤ 10000), where n is an integer. The second one is erase x, where x is an arbitrary 32-bit integer numerical token. The third operation is defragment.

Output
Output the sequence of lines. Each line should contain either the result of alloc operation procession , orILLEGAL_ERASE_ARGUMENT as a result of failed erase operation procession. Output lines should go in the same order in which the operations are processed. Successful procession of alloc operation should return integers, starting with 1, as the identifiers of the allocated blocks.

Sample test(s)
input

6 10
alloc 5
alloc 3
erase 1
alloc 6
defragment
alloc 6

output

1
2
NULL
3

心路历程

这题 真的写了好久好久,大概有,六七个小时吧!开始几次主要是没读懂题意,导致了大量的修改,然后写到半夜头昏脑涨效率就更低了。睡前刷到只有一个测试用例没通过!而且还是非保密的今早又是一个多小时的操作,终于还算完美得通过啦~

几个需要特别注意的地方:

  • 输入(待会记得写进OneNote,用于一行输入个数不确定的数字,而且数字含义不同的情况

  • 数据类型的库。Java提供了好多可以直接用的类和包,为什么不直接用!而要自己吭哧吭哧解决数组元素的增删。这单元考察的好像是集合框架,就更要用这些工具了啊喂!不然和以前用C写编程有什么区别?你根本就没用到java独特的地方嘛,学了但没学到本质

  • 函数封装功能。把所有内容写进main是一时的偷懒,但反而会带来更大的工作量

  • 一个de了很久最后才发现的严重问题:直接让自定义类的实例相等,
    就是说,不仅她们的值,她们的地址也会跟着变为相同!也就是说,如果让 myclass[1]=myclass[2]
    那么他们事实上被放进了同一个地址,此时改变myclass[1]的值,myclass[2]也会同时改变!
    请参考下面两篇文章:

  1. Java中的数组互相赋值,形参传递,地址传递

  2. Java中数组的引用赋值后共享一块内存区域,地址相同

sjm的程序

没有用包,没有自定义类,但很简洁只有78行

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T, m, n, tot = 1, tmp = 0, sta, flag = 0, las, now = 0;
        String S;
        T = scanner.nextInt();
        m = scanner.nextInt();
        S = scanner.nextLine();
        int[] base = new int[m + 1];
        while(T-- > 0){
            S = scanner.nextLine();
            String[] str = S.split(" ");
            if(str[0].charAt(4) == 'c'){
                now = 0;
                if(str.length == 2)
                    n = Integer.parseInt(str[1]);
                else{
                    now = Integer.parseInt(str[1]) - 1;
                    n = Integer.parseInt(str[2]);
                }
                tmp = flag = 0;
                sta = now;
                for (int i = now; i < m; i++) {
                    if(base[i] == 0)
                        tmp++;
                    else{
                        if(now != 0)
                            break;
                        sta = i + 1;
                        tmp = 0;
                    }
                    if(tmp == n){
                        flag = 1;
                        for (int j = sta; j <= i; j++)
                            base[j] = tot;
                    }
                }
                if(flag == 0)
                    System.out.println("NULL");
                else{
                    System.out.println(tot);
                    tot++;
                }
            }
            if(str[0].charAt(4) == 'e'){
                n = Integer.parseInt(str[1]);
                flag = 0;
                for (int i = 0; i < m; i++) {
                    if(base[i] == n){
                        base[i] = 0;
                        flag = 1;
                    }
                }
                if(flag == 0)
                    System.out.println("ILLEGAL_ERASE_ARGUMENT");
            }
            if(str[0].charAt(4) == 'a'){
                for (int i = 0; i < m; i++) {
                    if(base[i] != 0){
                        flag = 0;
                        sta = i - 1;
                        if(sta < 0)
                            continue;
                        while(base[sta] == 0){
                            flag = 1;
                            sta--;
                            if(sta < 0)
                                break;
                        }
                        base[sta + 1] = base[i];
                        if(flag != 0)
                            base[i] = 0;
                    }
                }
            }
        }
    }
}

wzh的程序

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int t=in.nextInt(),m=in.nextInt(),cnt=0;in.nextLine();
        int[] arr=new int[m+5];
        for(int i=0;i<t;i++){
            StringBuilder s=new StringBuilder(in.nextLine());
            if(s.charAt(0)=='a'){
                if(s.charAt(6)<'0'||s.charAt(6)>'9'){System.out.println("NULL");continue;}
                StringBuilder s1=new StringBuilder(s.substring(6));
                int pos=-1,num=0,len=s1.length();
                int j=0;
                while(j<len&&s1.charAt(j)!=' '){
                    num*=10;num+=s1.charAt(j)-'0';
                    j++;
                }
                if(j<len){
                    pos=num;num=0;++j;
                    while(j<len){
                        num*=10;num+=s1.charAt(j)-'0';
                        j++;
                    }
                }
                if(pos!=-1){
                    if(pos+num>m+1){System.out.println("NULL");continue;}
                    boolean ok=true;
                    for(int k=0,st=pos;k<num;k++,st++){
                        if(arr[st]!=0){ok=false;break;}
                    }
                    if(!ok)System.out.println("NULL");
                    else{
                        ++cnt;
                        for(int k=0,st=pos;k<num;k++,st++)arr[st]=cnt;
                        System.out.println(cnt);
                    }
                }
                else{
                    int lp=1,rp=1;
                    boolean ok=false;
                    while(rp<=m){
                        if(arr[rp]!=0){
                            lp=rp=rp+1;continue;
                        }
                        if(rp-lp>=num-1){ok=true;break;}
                        rp++;
                    }
                    if(ok){
                        ++cnt;
                        for(int k=lp;k<=rp;k++)arr[k]=cnt;
                        System.out.println(cnt);
                    }
                    else System.out.println("NULL");
                }
            }
            else if(s.charAt(0)=='e'){
                if(s.charAt(6)<'0'||s.charAt(6)>'9'){System.out.println("ILLEGAL_ERASE_ARGUMENT");continue;}
                boolean ok=false;
                StringBuilder s1=new StringBuilder(s.substring(6));
                int num=0,len=s1.length();
                int j=0;
                while(j<len&&s1.charAt(j)!=' '){
                    num*=10;num+=s1.charAt(j)-'0';
                    j++;
                }
                for(int k=1;k<=m;k++){
                    if(arr[k]==num){arr[k]=0;ok=true;}
                }
                if(!ok)System.out.println("ILLEGAL_ERASE_ARGUMENT");
            }
            else{
                int tot=1;
                for(int k=1;k<=m;k++){
                    if(arr[k]!=0)arr[tot++]=arr[k];
                }
                for(int k=tot;k<=m;k++)arr[k]=0;
            }
        }
        in.close();
    }
}

ljn的程序

使用了链表包,减小工作量

import java.util.LinkedList;
import java.util.Scanner;
class Main{  
 static int m;
 static int count = 0;
 static LinkedList<mem>list = new LinkedList<mem>();
 static void defragment(){
  LinkedList<mem>newlist = new LinkedList<mem>();
  int curr = 0;
  for(int i = 0; i < list.size(); i++){
   mem o = list.get(i);
   o.start = curr;
   curr = o.end = curr + o.size;
   newlist.add(o);
  }
  list = newlist;
 }
 static void alloc(int start, int n){
  int i = 0;
  while(i < list.size() && list.get(i).end < start) i++;
  if(i == list.size()) if(start + n <= m) {
   list.add(new mem(++count, n, start));
   System.out.println(count);
  } else System.out.println("NULL");
  else if(list.get(i).start < start + n) System.out.println("NULL");
  else {
   list.add(i, new mem(++count, n, start));
   System.out.println(count);
  }
 }
 static void alloc(int n){
  int last = 0;
  for(int i = 0; i < list.size(); i++){
   if(list.get(i).start-last >= n){
    list.add(i, new mem(++count, n, last));
    System.out.println(count);
    return;
   }else last = list.get(i).end;
  }
  if(last + n > m) System.out.println("NULL");
  else{
   list.add(new mem(++count, n, last));
   System.out.println(count);
  }
 }
 static void erase(int x){
  for(int i = 0; i < list.size(); i++)
   if(list.get(i).name == x) {list.remove(i); return;}
  System.out.println("ILLEGAL_ERASE_ARGUMENT");
 }
 public static void main(String[] args) {
  Scanner sc = new Scanner(System.in);
  int n = sc.nextInt(); m = sc.nextInt(); sc.nextLine();
  while(n-- > 0){
   String[] cmd = sc.nextLine().split(" ");
   if(cmd.length == 1) defragment();
   else{
    int cmd1 = Integer.valueOf(cmd[1]);
    if(cmd.length == 3)alloc(cmd1, Integer.valueOf(cmd[2]));
    else if(cmd[0].equals("alloc")) alloc(cmd1); else erase(cmd1);
   }
  }
  sc.close();
 }
}
class mem{
 int name, size, start, end;
 mem(int _name, int _size, int _start){
  name = _name;
  size = _size;
  start = _start;
  end = start + size;
 }
}

sunm的程序

使用了arraylist

import java.util.Arrays;
import java.util.Comparator;
import java.io.*;
import java.util.*;
public class Main {
 public static void main(String[] args) {
  new Main().solve();
 }
 Scanner in;PrintWriter out;
 String s;
 int ji[];
 int t, m, kk = 0;
 void a(int n,int st) {
     int id = 0, cnt = 0, ok = 0,end=m;
     if(st!=0)end=Math.min(st+n, m);
     for (int i = st; i < end; i++) {
         if (ji[i]==0)cnt++;
         else {cnt = 0;id = i + 1;}
         if (cnt == n) {
             kk++;
             ok = 1;
             for (int j = id; j < id + n; j++)
                 ji[j] = kk;
             out.println(kk);
             break;
         }
     }
     if (ok==0)out.println("NULL");
 };
 void e (int n) {
     if (n > kk || n < 1) {
         out.println( "ILLEGAL_ERASE_ARGUMENT");
         return;
     }
     int i, ok = 0;
     for (i = 0; i < m; i++)
         if (ji[i] == n)break;
     while (ji[i] == n) {ji[i++] = 0;ok = 1;}
     if(ok==0)out.println( "ILLEGAL_ERASE_ARGUMENT");
 };
 void d () {
     int id = 0;
     for (int i = 0; i < m; i++)
         if (ji[i]>0)ji[id++] = ji[i];
     for (int i = id; i < m; i++)
         ji[i] = 0;
 };
 
 int cal(String str) {
  int m=str.length(),mid=0;
  for(int i=0;i<m;i++)
   mid=(str.charAt(i)-'0')+mid*10;
  return mid;
 }
 
 public void solve() {
  in = new Scanner(System.in);out =  new PrintWriter(System.out); 
  t=in.nextInt();m=in.nextInt();int ci=0;
     ji = new int[m+1];s=in.next();
     while (in.hasNext()) {
         int n=0,st=0;
         if (s.charAt(0) == 'a') {
             st=in.nextInt();
             if(in.hasNext()) {
              s=in.next();
              if(s.charAt(s.length()-1)>='0'&&s.charAt(s.length()-1)<='9') { 
               n=cal(s);
               a(n,st-1);
               if(in.hasNext())s=in.next();
              }else a(st,0);
             }else a(st,0);
         }
         else if (s.charAt(0) == 'e') {
             n=in.nextInt();
             e(n);
             if(in.hasNext())s=in.next();
         }
         
         else {
          d();
          if(in.hasNext())s=in.next();
         }
     }
  out.flush();
 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值