PDA

Visualizza versione completa : Uso di SortedLinkedList


aduri
25-08-2006, 13.41.33
Questo e' l'ultimo esercizio x me il piu' difficoltoso

Il testo originale del prof. e' il seguente:
3. Scrivere una classe (che contiene il main()) in cui creare un oggetto di tipo
SortedLinkedList, lista di oggetti Process. La sequenza di processi “in ingresso al sistema” è contenuta nel
file processes.txt: ogni riga contiene i dati di un processo, cioè il pid, il nome e la memoria occupata.
Eseguire le seguenti operazioni:
• Leggere una riga del file ed inserire il processo nella lista.
• Se la quantità di memoria utilizzata da tutti i processi supera un valore di soglia
(100000) eliminare dalla lista il processo che in quel momento occupa più memoria
(utilizzare gli iteratori, oggetti Iterator).
• Salvare su file il numero di processi presenti nel sistema e la quantità di memoria
utilizzata da tutti i processi in ogni istante (“ad ogni lettura di una riga”).
Fare i grafici dell’occupazione di memoria e del numero di processi (in ogni istante).
Commentare.
Valutare il costo computazionale per mantenere la lista ordinata e per eliminare il processo che occupa più memoria.

Ho problemi ad approcciare alla soluzione.
Vorrei innanzitutto capire come impostare il problema.
Ho creato una classe UsaProcesses che legge i record simili a processes.
la classe SortedLinkedList l'avevo gia' implementata precedentemente:


Codice:

import java.util.*;
public class SortedLinkedList extends LinkedList
{
private static int elementi;
public static void main ( String []args )
{
if(args.length > 0)
elementi = Integer.parseInt(args[0]);
else
elementi = 21;
System.out.println( "Prova su " + elementi + "elementi." );
SortedLinkedList l = new SortedLinkedList();
// riempi la lista di numeri a caso tra -30 e +30
ListIterator it_aggiunta = l.listIterator();
Random generatore=new Random();
for ( int i = 0; i < elementi; i++ )
{
int segno=generatore.nextInt(2);// 0 o 1
int n=generatore.nextInt(31);
if(segno==0)
l.add(new Integer(- n ));
else
l.add(new Integer(n));
}
// stampa tutti i valori
System.out.println( "Collezione completa:" );
stampaCollezione( l );
}
private static void stampaCollezione
( Collection c )
{
Iterator i = c.iterator();
while ( i.hasNext() )
{
System.out.println( i.next() );
}
}
@Override
public boolean add(Object o){
Comparable c=(Comparable)o;//bisogna usare il cast a Comparable
ListIterator it=listIterator();
Comparable c2=null;
if(it.hasNext())
c2=(Comparable)it.next();
else{
it.add(c);
return true;
}
while(it.hasNext() && c2.compareTo(c)>0) //<0 x ordine crescente
c2=(Comparable)it.next();
//uscito dal while ho raggiunto la posizione di inserimento perchè il compareTo() non da più <0
//ora posso usare per inserire in questa posizione il metodo add di ListIterator ma bisognerebbe
//tornare indietro di una posizione per essere sicuri che l'inserimento sia in ordine se il compareTo() >0
if(c2.compareTo(c)<0)//>0 x ordine crescente
it.previous();
it.add(c);
return true;
}
}

Allego il file processes.txt

Scusate per la lungaggine

aduri
29-08-2006, 11.41.51
Ho ripreso un codice MyFile.java che avevo sviluppato per un'altra applicazione ed ho cercato di adattarla a questo problema.
Sono andato un po' avanti ed ora non mi da' errore di compilazione ma non fa quello che pensavo facesse. :mm:
Mi elenca il file non ordinato e dopo il file ordinato in ordine crescente relativo al campo memoria ma non mi rimuove l'ultimo in fondo o perlomeno non mi visualizza a video l'elenco senza l'ultimo record. :wall:
In ogni caso manca ancora nell'implementazione il controllo sulla memoria quando supera 100000.

allego codice aggiornato:


import java.util.*;
import java.io.*;
import javax.swing.JOptionPane;//utility pannello di dialogo

class MyFile {
public int memoria;
public int pid;
public String nome;

MyFile (String linea)
{
String aTmp[] = linea.split("\t");
this.memoria = Integer.parseInt(aTmp[2]);
this.nome = aTmp[1];
this.pid = Integer.parseInt(aTmp[0]);
}

MyFile (int memoria, String nome)
{
this.pid = pid;
this.memoria = memoria;
this.nome = nome;
}

public static void main(String[] args) throws IOException
{
Keymemoria keymemoria = new Keymemoria();
// KeyNome keyNome = new KeyNome();
Vector v = new Vector();// creo Vector (array dinamico)
// Carico file da processes.txt
//String nomeFile=JOptionPane.showInputDialog("Digita il nome del file da leggere");
String nomeFile="processes.txt"; //altro modo di input file diretto da codice

BufferedReader fileLettura;

try {
fileLettura = new BufferedReader(new FileReader(nomeFile));
while(true) {
String linea = fileLettura.readLine();
if(linea==null) {
break;
} else {
v.add( new MyFile(linea) );
}
}
} catch(FileNotFoundException e) {// gestisco le eccezioni
System.out.println("Il file "+nomeFile + " non esiste o non puo' essere aperto");
} catch(IOException e) {
System.out.println("errore di lettura "+e);
}

MyFile[] a = new MyFile[v.size()];
for( int i = 0; i < v.size(); i++ ) {
a[i] = (MyFile)v.get(i);
}
System.out.println ("------------------");
System.out.println ("Array non ordinato: ");
System.out.println ("pid nome memoria");
for (int k = 0; k < a.length; k++) {
System.out.println (a[k].pid + " " + a[k].nome+ " " + a[k].memoria);

}
System.out.println ("------------------");
System.out.println ("Array ordinato rispetto alla dimensione della memoria: ");
System.out.println ("pid nome memoria");
Arrays.sort (a, keymemoria);
for (int k = 0; k < a.length; k++) {
System.out.println (a[k].pid + " " + a[k].nome+ " " + a[k].memoria);

}
System.out.println ("------------------");
//Implemento la ricerca binaria per dimensione
System.out.println ("");

}
}

class Keymemoria implements Comparator {
public int compare (Object MyFile1, Object MyFile2)
{
int memoria1 = ((MyFile) MyFile1).memoria;
int memoria2 = ((MyFile) MyFile2).memoria;
return (memoria1 < memoria2 ? -1 : (memoria1 == memoria2 ? 0 : 1));
}
}

class ScanDeleteLast {
SortedLinkedList l = new SortedLinkedList();
ListIterator it = l.listIterator();

public void scandel() {
while(it.hasNext())
it.next();
// toglie l’ultimo elemento traversato
it.remove(); // rimuove record con memoria maggiore
System.out.println(it.next());

}
}

Grazie x l'aiuto

aduri
30-08-2006, 22.48.19
Ho tirato giu' questo codice (e' diverso dal precedente ma rispetta le richieszte del prof) che ordina il file processes.txt devo ora fargli il controllo sulla memoria, la rimozione del record con max memoria e la scrittura del nuovo file.
Qualcuno mi puo' dare qualche consiglio su come approcciare la soluzione?
import java.util.*;
import java.lang.*;
import java.io.*;
import javax.swing.JOptionPane;//utility pannello di dialogo
class Processo implements Comparable{
private int pid;
private String name;
private int memoria;
public Processo(int pid,String name,int mem){
this.pid=pid;
this.name=name;
memoria=mem;
}
public int compareTo(Object o){
Processo p=(Processo)o;
return this.memoria-p.memoria;//ordina in base alla quantità di memoria in ordine crescente
}
public String toString(){
return ""+pid+" "+name+" "+memoria;
}
}
public class EsProcesso{
public static void main(String[] args) throws IOException
{
//String nomeFile=JOptionPane.showInputDialog("Digita il nome del file da leggere");
//altro modo di input file diretto da codice
String nomeFile="processes.txt";
BufferedReader fileLettura=null;
SortedLinkedList lista=new SortedLinkedList();
try {
try{
fileLettura = new BufferedReader(new FileReader(nomeFile));
String linea=fileLettura.readLine();
while(linea!=null) {
String[] tmp=linea.split("\t");
Processo p=new Processo(Integer.parseInt(tmp[0]),tmp[1],Integer.parseInt(tmp[2]));
lista.add( p);
linea=fileLettura.readLine();//per far girare il ciclo
}
}finally{ fileLettura.close();}
}catch(FileNotFoundException e) {// gestisco le eccezioni
System.out.println("Il file "+nomeFile + " non esiste o non puo' essere aperto");
}catch(IOException e) {
System.out.println("errore di lettura "+e);
}
Iterator it=lista.iterator();
while(it.hasNext())
System.out.println((Processo)it.next());//cosi posso vedere tutta la lista
}
}

miciomao
02-09-2006, 00.41.15
Mi dispiace io non so come aiutarti :(
sembra una cosa gajarda però :)

aduri
05-10-2006, 13.13.19
Non sono ancora riuscito a schiodarmi;
ho problemi a richiamare i metodi GetMemoria() e RemoveMaggiore().


import java.util.*;
import java.lang.*;
import java.io.*;
import javax.swing.JOptionPane;//utility pannello di dialogo
class Processo implements Comparable{
private int pid;
private String name;
private int memoria;
public Processo(int pid,String name,int mem){
this.pid=pid;
this.name=name;
memoria=mem;
}
public int compareTo(Object o){
Processo p=(Processo)o;
return this.memoria-p.memoria;//ordina in base alla quantità di memoria in ordine crescente
}
public String toString(){
return ""+pid+" "+name+" "+memoria;
}

public int GetMemoria(){
return this.memoria;
}
public void RemoveMaggiore(){
SortedLinkedList lista=new SortedLinkedList();
Iterator it1=lista.iterator();// in questa riga ho creato un nuovo
//l'oggetto iterator it1 che agisce sull'oggetto list di sortedlinkedlist (idem come sopra)
Processo p = (Processo) it1.next(); // ottengo il processo
memoria -= p.memoria; // aggiorno la memoria occupata
// rimuovo il processo dalla lista
}


}

public class EsProcesso{
public static void main(String[] args) throws IOException
{
//String nomeFile=JOptionPane.showInputDialog("Digita il nome del file da leggere");
//altro modo di input file diretto da codice
String nomeFile="processes.txt";
BufferedReader fileLettura=null;
SortedLinkedList lista=new SortedLinkedList();
try {
try{
fileLettura = new BufferedReader(new FileReader(nomeFile));
String linea=fileLettura.readLine();
while(linea!=null) {
String[] tmp=linea.split("\t");
Processo p=new Processo(Integer.parseInt(tmp[0]),tmp[1],Integer.parseInt(tmp[2]));
lista.add( p);
linea=fileLettura.readLine();//per far girare il ciclo
}
}finally{ fileLettura.close();}
}catch(FileNotFoundException e) {// gestisco le eccezioni
System.out.println("Il file "+nomeFile + " non esiste o non puo' essere aperto");
}catch(IOException e) {
System.out.println("errore di lettura "+e);
}
Iterator it=lista.iterator();
while(it.hasNext())
System.out.println((Processo)it.next());//cosi puoi vedere tutta la lista
// e stampare a video
}
Processo p1= new Processo();// creo nuovo oggetto Processo

// sembra che richieda di implementare il costruttore dell'oggetto
// ma non e' gia' istanziato come public nella classe processo?
// sembra che non riconosca i 2 metodi seguenti

while(p1.GetMemoria()>100000){ //che dovrebbe incrementare il metodo GetMemoria()
// rimuovi il processo che occupa più memoria
p1.RemoveMaggiore(); //che dovrebbe incrementare il metodo RemoveMaggiore()
}
}


Scusate la lunghezza.

Saluti e grazie per l'aiuto

emsmail
07-10-2006, 21.48.47
Premetto che non ho ancora avuto modo di leggere tutto il tuo codice, ma mi sono concentrato nella lettura del testo del problema...

Devi prima di tutto creare la classe della lista linkata, magari usando come attributo un object (oppure con java 5 i generici), cosi in progetti futuri la potrai riciclare, implementando tutte le interfacce opportune e la serializzazione.
Poi crei una classe che definisce il tipo Processo, che contenga i dati di processo, serializzata e magari con una funzione di comparazione.
Poi crei una classe che rappresenta il sistema in cui leggi il processo dal file, lo inserisci nella lista linkata, memorizzando la sommatoria dello spazio dei processi e il processo di dimensione maggiore. Con il verificarsi del superamento del limite di spazio, ricerchi nella lista il processo e lo elimini. Alla fine di ogni iterazione stampi il contenuto della lista in un file.... fino all' EOF.

Spero che questa linea guida ti sia di aiuto.....

aduri
10-10-2006, 17.09.57
Sono riuscito a risolvere il problema ma....
qualcuno puo' aiutarmi a capire come scrivere su file la lista proc.

Grazie[:)]


import java.util.*;
import java.lang.*;
import java.io.*;


class Processo implements Comparable{
private int pid;
private String name;
private int memoria;

public Processo(int pid,String name,int mem){ // costruttore
this.pid=pid;
this.name=name;
memoria=mem;
}

public int compareTo(Object o){
Processo p=(Processo)o;
return this.memoria-p.memoria;//ordina in base alla quantità di memoria in ordine crescente
}

public int getMemoria(){
return this.memoria;
}
public String toString(){
return ""+pid+" "+name+" "+memoria;
}
} //chiudo la classe processo


public class EsProcesso
{ // classe col main
public static void main(String[] args) throws IOException
{
String nomeFile="processes.txt";
BufferedReader fileLettura=null;
SortedLinkedList lista=new SortedLinkedList();
try {
try{
fileLettura = new BufferedReader(new FileReader(nomeFile));
String linea=fileLettura.readLine();
while(linea!=null) {
String[] tmp=linea.split("\t");
// convertiamo le stringhe in intero con parseInt e valueOf x il contrario
Processo p=new Processo(Integer.parseInt(tmp[0]),tmp[1],Integer.parseInt(tmp[2]));
lista.add( p);
linea=fileLettura.readLine();//per far girare il ciclo
}
}finally{ fileLettura.close();}
}catch(FileNotFoundException e) {// gestisco le eccezioni
System.out.println("Il file "+nomeFile + " non esiste o non puo' essere aperto");
}catch(IOException e) {
System.out.println("errore di lettura "+e);
}

Iterator it1=lista.iterator();

while(it1.hasNext()) // fino a che trova un elemento stampa i record
{
Processo proc = (Processo)it1.next();
System.out.println(proc.toString());//e cosi puoi vedere tutta la lista
}

// codice analisi memoria
while(true)
{
Iterator iter = lista.iterator();
int memtot = 0;
while(iter.hasNext())
{
Processo proc = (Processo)iter.next();
memtot += proc.getMemoria();
}
if(memtot >= 100000)
{
System.out.print("Limite di memoria raggiunto, ");
//elimina il processo più grande che è nella prima posizione della lista
iter = lista.iterator();
Processo proc = (Processo)iter.next();
System.out.println("elimino il processo:\n"+proc.toString());
iter.remove();
}
else
break;
}

// apertura del file per la scrittura
FileWriter f = new FileWriter("newproc.txt");
// creazione dell'oggetto per la scrittura
PrintWriter out = new PrintWriter(f);
// scrittura del testo su file
out.println(proc); // QUI DA ERRORE IL COMPILATORE
// chiusura del file
out.close(); }




}

emsmail
11-10-2006, 21.06.29
public int compareTo(Object o){
Processo p=(Processo)o;
return this.memoria-p.memoria;//ordina in base alla quantità di memoria in ordine crescente
}
Questo è molto brutto..... dovresti passare diretamente Processo senza fare il casting,
perchè cosi non sfrutti la caratteristica di java di essere fortemente tipizzato, altrimenti se vuoi passare un object e fare il casting devi essere pronto a gestire una eccezione di tipo classcastexception oppure fare prima una type of .

Per i file non ne so' molto.... probabilmente devi rendere la classe Processo di tipo Serializzabile (implements serializable)......

aduri
17-10-2006, 13.40.22
Risolto il codice !!!!
Chiedo scusa
ma mi era sfuggita una richiesta che mi mette in difficolta'.
Mi viene chiesto di:
fare i grafici dell'occupazione di memoria e del numero di processi (in ogni istante)
e valutare il costo computazionale per mantenere la lista ordinata e per eliminare il processo che occupa piu' memoria.

Grazie dell'aiuto