initial commit
This commit is contained in:
10
.classpath
Executable file
10
.classpath
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
17
.project
Executable file
17
.project
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>AlgoritmiStruttureDati</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
12
.settings/org.eclipse.jdt.core.prefs
Executable file
12
.settings/org.eclipse.jdt.core.prefs
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.8
|
||||||
11
src/it/algoritmi/adt/CircularQueue.java
Normal file
11
src/it/algoritmi/adt/CircularQueue.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
public interface CircularQueue<E> extends Queue<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sposta alla fine della coda il suo elemento iniziale.
|
||||||
|
* Se la coda <20> vuota non fa niente.
|
||||||
|
*/
|
||||||
|
void rotate();
|
||||||
|
|
||||||
|
}
|
||||||
33
src/it/algoritmi/adt/Deque.java
Normal file
33
src/it/algoritmi/adt/Deque.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interfaccia che definisce una coda doppia: un contenitore di elementi con
|
||||||
|
* inserimenti e rimozioni ai due estremi. Semplificata rispetto a java.util.Dequeue.
|
||||||
|
*/
|
||||||
|
public interface Deque<E> {
|
||||||
|
|
||||||
|
/** Restituisce il numero di elementi presenti nella coda doppia. */
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/** Verifica se la coda doppia <20> vuota. */
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/** Restituisce il primo elemento, senza toglierlo (null se la coda <20> vuota). */
|
||||||
|
E first();
|
||||||
|
|
||||||
|
/** Restituisce l'ultimo elemento, senza toglierlo (null se la coda <20> vuota). */
|
||||||
|
E last();
|
||||||
|
|
||||||
|
/** Inserisce un elemento all'inizio della coda doppia. */
|
||||||
|
void addFirst(E e);
|
||||||
|
|
||||||
|
/** Inserisce un elemento alla fine della coda doppia. */
|
||||||
|
void addLast(E e);
|
||||||
|
|
||||||
|
/** Elimina e restituisce il primo elemento della coda (null se <20> vuota). */
|
||||||
|
E removeFirst();
|
||||||
|
|
||||||
|
/** Elimina e restituisce l'ultimo elemento della coda (null se <20> vuota). */
|
||||||
|
E removeLast();
|
||||||
|
|
||||||
|
}
|
||||||
24
src/it/algoritmi/adt/List.java
Normal file
24
src/it/algoritmi/adt/List.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
/** Una versione semplificata dell'interfaccia java.util.List. */
|
||||||
|
public interface List<E> extends Iterable<E> {
|
||||||
|
|
||||||
|
/** Restituisce il numero di elementi presenti nella lista. */
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/** Restituisce true se e sole se la lista è vuota. */
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/** Restituisce l'elemento corristondente all'indice i, senza eliminarlo. */
|
||||||
|
E get(int i) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/** Sostituisce con e l'elemento di indice i; restituisce l'elemento sostituito. */
|
||||||
|
E set(int i, E e) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/** Inserisce e come elemento di indice i, spostando gli elementi successivi. */
|
||||||
|
void add(int i, E e) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
/** Rimuove e restituisce l'elemento di indice i, spostando i successivi. */
|
||||||
|
E remove(int i) throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
}
|
||||||
13
src/it/algoritmi/adt/Position.java
Normal file
13
src/it/algoritmi/adt/Position.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
public interface Position<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce l'elemento memorizzato in questa posizione.
|
||||||
|
*
|
||||||
|
* @return l'elemento memorizzato
|
||||||
|
* @throws IllegalStateException se la posizione non è più valida
|
||||||
|
*/
|
||||||
|
E getElement() throws IllegalStateException;
|
||||||
|
|
||||||
|
}
|
||||||
45
src/it/algoritmi/adt/PositionalList.java
Normal file
45
src/it/algoritmi/adt/PositionalList.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
/** L'interfaccia che definisce liste posizionali. */
|
||||||
|
public interface PositionalList<E> extends Iterable<E> {
|
||||||
|
|
||||||
|
/** Restituisce il numero di elementi presenti nella lista. */
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/** Restituisce true se e solo se la lista è vuota. */
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/** Restituisce la prima Position della lista (o null se la lista è vuota). */
|
||||||
|
Position<E> first();
|
||||||
|
|
||||||
|
/** Restituisce l'ultima Position della lista (o null se la lista è vuota). */
|
||||||
|
Position<E> last();
|
||||||
|
|
||||||
|
/** Restituisce la Position che precede p (o null, se p è la prima). */
|
||||||
|
Position<E> before(Position<E> position) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Restituisce la Position che segue p (o null, se p è l'ultima). */
|
||||||
|
Position<E> after(Position<E> position) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Inserisce l'elemento e all'inizio della lista; ne restituisce la posizione. */
|
||||||
|
Position<E> addFirst(E element);
|
||||||
|
|
||||||
|
/** Inserisce l'elemento e alla fine della lista; ne restituisce la posizione. */
|
||||||
|
Position<E> addLast(E element);
|
||||||
|
|
||||||
|
/** Inserisce l'elemento e prima della Position p; ne restituisce la posizione. */
|
||||||
|
Position<E> addBefore(Position<E> position, E element) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Inserisce l'elemento e dopo la Position p; ne restituisce la posizione. */
|
||||||
|
Position<E> addAfter(Position<E> position, E element) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Sostituisce l'elemento nella Position p; restituisce l'elemento sostituito. */
|
||||||
|
E set(Position<E> position, E element) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Elimina e restituisce l'elemento nella Position p; (poi p non è più valida). */
|
||||||
|
E remove(Position<E> position) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/** Restituisce una rappresentazione iterabile delle posizioni dela lista. */
|
||||||
|
public Iterable<Position<E>> positions();
|
||||||
|
|
||||||
|
}
|
||||||
20
src/it/algoritmi/adt/Queue.java
Normal file
20
src/it/algoritmi/adt/Queue.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
public interface Queue<E> {
|
||||||
|
|
||||||
|
/** Restituisce il numero di elementi presenti nella coda. */
|
||||||
|
public int size();
|
||||||
|
|
||||||
|
/** Verifica se la coda <20> vuota. */
|
||||||
|
public boolean isEmpty();
|
||||||
|
|
||||||
|
/** Inserisce un elemento in fondo alla coda. */
|
||||||
|
public void enqueue(E e);
|
||||||
|
|
||||||
|
/** Elimina e restituisce il primo elemento della coda (null se <20> vuota). */
|
||||||
|
public E dequeue();
|
||||||
|
|
||||||
|
/** Restituisce il primo elemento della coda, senza toglierlo (null se <20> vuota). */
|
||||||
|
public E first();
|
||||||
|
|
||||||
|
}
|
||||||
44
src/it/algoritmi/adt/Stack.java
Normal file
44
src/it/algoritmi/adt/Stack.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package it.algoritmi.adt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Una raccolta di oggetti che vengono inseriti e eliminati secondo il principio
|
||||||
|
* last-in first-out. Anche se ha uno scopo simile, questa interfaccia <20> diversa da
|
||||||
|
* java.util.Stack
|
||||||
|
*
|
||||||
|
* @author fscotto
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Stack<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il numero di elementi presenti nella pila.
|
||||||
|
* @return il numero di elementi presenti nella pila.
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifica se la pila <20> vuota.
|
||||||
|
* @return true se e solo se la pila <20> vuota
|
||||||
|
*/
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce un elemento in cima alla pila.
|
||||||
|
* @param e l'elemento da inserire
|
||||||
|
*/
|
||||||
|
void push(E e);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce l'elemento in cima alla pila, senza eliminarlo.
|
||||||
|
* @return l'elemento in cima alla pila (o null se la pila <20> vuota)
|
||||||
|
*/
|
||||||
|
E top();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina e restituisce l'elemento che si trova in cima alla pila.
|
||||||
|
* @return l'elemento eliminato (o null se la pila <20> vuota)
|
||||||
|
*/
|
||||||
|
E pop();
|
||||||
|
|
||||||
|
}
|
||||||
82
src/it/algoritmi/adt/dequeue/ArrayDeque.java
Normal file
82
src/it/algoritmi/adt/dequeue/ArrayDeque.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package it.algoritmi.adt.dequeue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Deque;
|
||||||
|
|
||||||
|
public class ArrayDeque<E> implements Deque<E> {
|
||||||
|
private E[] data;
|
||||||
|
private int size;
|
||||||
|
private int f;
|
||||||
|
|
||||||
|
public static final int CAPACITY = 1000;
|
||||||
|
|
||||||
|
public ArrayDeque() {
|
||||||
|
this(CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"all"})
|
||||||
|
public ArrayDeque(int capacity) {
|
||||||
|
data = (E[]) new Object[capacity];
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E first() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data[f];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E last() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data[size-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFirst(E element) throws IllegalStateException {
|
||||||
|
final int len = data.length;
|
||||||
|
if (size() == len) {
|
||||||
|
throw new IllegalStateException("Queue is full");
|
||||||
|
}
|
||||||
|
final int avail = (f - 1 + len) % len;
|
||||||
|
data[avail] = element;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLast(E element) throws IllegalStateException {
|
||||||
|
final int len = data.length;
|
||||||
|
if (size() == len) {
|
||||||
|
throw new IllegalStateException("Queue is full");
|
||||||
|
}
|
||||||
|
final int avail = (f + size) % len;
|
||||||
|
data[avail] = element;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeFirst() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeLast() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
49
src/it/algoritmi/adt/dequeue/LinkedDeque.java
Normal file
49
src/it/algoritmi/adt/dequeue/LinkedDeque.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package it.algoritmi.adt.dequeue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Deque;
|
||||||
|
import it.algoritmi.adt.list.DoublyLinkedList;
|
||||||
|
|
||||||
|
public class LinkedDeque<E> implements Deque<E> {
|
||||||
|
private DoublyLinkedList<E> l = new DoublyLinkedList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return l.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return l.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E first() {
|
||||||
|
return l.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E last() {
|
||||||
|
return l.last();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFirst(E element) {
|
||||||
|
l.addFirst(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLast(E element) {
|
||||||
|
l.addLast(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeFirst() {
|
||||||
|
return l.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E removeLast() {
|
||||||
|
return l.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
161
src/it/algoritmi/adt/list/ArrayList.java
Normal file
161
src/it/algoritmi/adt/list/ArrayList.java
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.List;
|
||||||
|
|
||||||
|
public class ArrayList<E> implements List<E> {
|
||||||
|
// variabili di esemplare
|
||||||
|
public static final int CAPACITY = 16; // capacità predefinita dell'array
|
||||||
|
|
||||||
|
private E[] data; // array generico per memorizzare gli elementi
|
||||||
|
private int size; // numero di elementi nella lista
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruttore di una lista standard
|
||||||
|
*/
|
||||||
|
public ArrayList() {
|
||||||
|
this(CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costruisce una lista con capacità data
|
||||||
|
* @param capacity
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public ArrayList(int capacity) {
|
||||||
|
data = (E[]) new Object[capacity];
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il numero di elementi presenti nella lista.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce true se e solo se la lista è vuota.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce l'elemento corrispondente all'indice i,
|
||||||
|
* senza eliminarlo.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E get(int i) throws IndexOutOfBoundsException {
|
||||||
|
checkIndex(i, size);
|
||||||
|
return data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sostituisce con e l'elemento di indice i;
|
||||||
|
* restituisce l'elemento sostituito.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E set(int i, E e) throws IndexOutOfBoundsException {
|
||||||
|
checkIndex(i, size);
|
||||||
|
E tmp = data[i];
|
||||||
|
data[i] = e;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce e come elemento di indice i,
|
||||||
|
* spostando gli elementi successivi.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void add(int i, E e) throws IndexOutOfBoundsException {
|
||||||
|
checkIndex(i, size + 1);
|
||||||
|
if(size == data.length) resize(2 * data.length);
|
||||||
|
for(int k = size - 1; k >= i; --k) data[k + 1] = data[k];
|
||||||
|
data[i] = e;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina e restituisce l'elemento con l'indice i,
|
||||||
|
* spostando i successivi.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E remove(int i) throws IndexOutOfBoundsException {
|
||||||
|
checkIndex(i, size);
|
||||||
|
E tmp = data[i];
|
||||||
|
for(int k = i; k <= size-1; ++k) data[k] = data[k + 1];
|
||||||
|
data[size - 1] = null;
|
||||||
|
--size;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controlla se l'indice data appartiene all'intervallo [0, n - 1]
|
||||||
|
* @param i
|
||||||
|
* @param n
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
*/
|
||||||
|
protected void checkIndex(int i, int n) throws IndexOutOfBoundsException {
|
||||||
|
if(i < 0 || i >= n) throw new IndexOutOfBoundsException("Illegal index: " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ridimensiona l'array interno in modo che abbia capacità >= size.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected void resize(int capacity) {
|
||||||
|
E[] tmp = (E[]) new Object[capacity];
|
||||||
|
for(int k = 0; k < size; ++k) tmp[k] = data[k];
|
||||||
|
data = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ArrayIterator implements Iterator<E> {
|
||||||
|
private int j = 0; // indice del prossimo elemento da restituire
|
||||||
|
private boolean removable = false; // si può invocare remove ora?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifica se l'iteratore ha ancora oggetti da restituire
|
||||||
|
* @return true se e solo se ci sono ancora oggetti da restituire
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return j < size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce l'oggetto successivo presente nell'iteratore.
|
||||||
|
*
|
||||||
|
* @return l'oggetto successivo
|
||||||
|
* @throws NoSuchElementException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E next() throws NoSuchElementException {
|
||||||
|
if(j == size()) throw new NoSuchElementException("No next element");
|
||||||
|
removable = true; // questo elemento potrà poi essere rimosso
|
||||||
|
return data[j++]; // post-incremente di j, così è pronto per il futuro
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina l'elemento restituito dalla più recente invocazione di next.
|
||||||
|
* @throws IllegalStateException se next non è mai stato invocato
|
||||||
|
* @throws IllegalStateException se remove è già stato invocato dopo next
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void remove() throws IllegalStateException {
|
||||||
|
if(!removable) throw new IllegalStateException("nothing to remove");
|
||||||
|
ArrayList.this.remove(j-1);
|
||||||
|
--j;
|
||||||
|
removable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new ArrayIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
86
src/it/algoritmi/adt/list/CircularyLinkedList.java
Normal file
86
src/it/algoritmi/adt/list/CircularyLinkedList.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
public class CircularyLinkedList<E> {
|
||||||
|
private Node<E> tail = null;
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
private static class Node<E> {
|
||||||
|
private E element;
|
||||||
|
private Node<E> next;
|
||||||
|
|
||||||
|
public Node(E e, Node<E> n) {
|
||||||
|
element = e;
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(Node<E> n) {
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E first() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tail.getNext().getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E last() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tail.getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate() {
|
||||||
|
if (tail != null) {
|
||||||
|
tail = tail.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFirst(E e) {
|
||||||
|
if(size == 0) {
|
||||||
|
tail = new Node<>(e, null);
|
||||||
|
tail.setNext(tail);
|
||||||
|
} else {
|
||||||
|
Node<E> newest = new Node<>(e, tail.getNext());
|
||||||
|
tail.setNext(newest);
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLast(E e) {
|
||||||
|
addFirst(e);
|
||||||
|
tail = tail.getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E removeFirst() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node<E> head = tail.getNext();
|
||||||
|
if(head == tail) {
|
||||||
|
tail = null;
|
||||||
|
} else {
|
||||||
|
tail.setNext(head.getNext());
|
||||||
|
}
|
||||||
|
size--;
|
||||||
|
return head.getElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
120
src/it/algoritmi/adt/list/DoublyLinkedList.java
Normal file
120
src/it/algoritmi/adt/list/DoublyLinkedList.java
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
public class DoublyLinkedList<E> {
|
||||||
|
private Node<E> header;
|
||||||
|
private Node<E> trailer;
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
private static class Node<E> {
|
||||||
|
private E element;
|
||||||
|
private Node<E> prev;
|
||||||
|
private Node<E> next;
|
||||||
|
|
||||||
|
private Node(E e, Node<E> prev, Node<E> next) {
|
||||||
|
element = e;
|
||||||
|
this.prev = prev;
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getPrev() {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrev(Node<E> prev) {
|
||||||
|
this.prev = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(Node<E> next) {
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public DoublyLinkedList() {
|
||||||
|
header = new Node<>(null, null, null);
|
||||||
|
trailer = new Node<>(null, header, null);
|
||||||
|
header.setNext(trailer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il numero di elementi presenti nella lista
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce true se e solo se la lista <20> vuota */
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce il primo elemento della lista, senza eliminarlo. */
|
||||||
|
public E first() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return header.getNext().getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce l'ultimo elemento della lista, senza eliminarlo. */
|
||||||
|
public E last() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return trailer.getPrev().getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Aggiunge un elemento all'inizio della lista. */
|
||||||
|
public void addFirst(E e) {
|
||||||
|
addBetween(e, header, header.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Aggiunge un elemento alla fine della lista. */
|
||||||
|
public void addLast(E e) {
|
||||||
|
addBetween(e, trailer.getPrev(), trailer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Elimina e restituisce il primo elemento della lista. */
|
||||||
|
public E removeFirst() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return remove(header.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Elimina e restituisce l'ultimo elemento della lista. */
|
||||||
|
public E removeLast() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return remove(trailer.getPrev());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Elimina dall lista il nodo indicato e restituisce il suo elemento. */
|
||||||
|
private E remove(Node<E> node) {
|
||||||
|
Node<E> predecessor = node.getPrev();
|
||||||
|
Node<E> successor = node.getNext();
|
||||||
|
predecessor.setNext(successor);
|
||||||
|
successor.setPrev(predecessor);
|
||||||
|
--size;
|
||||||
|
return node.getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Aggiunge l'elemento e alla lista, tra i due nodi dati. */
|
||||||
|
private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
|
||||||
|
// crea un nuovo nodo e lo collega alla lista
|
||||||
|
Node<E> newest = new Node<>(e, predecessor, successor);
|
||||||
|
predecessor.setNext(newest);
|
||||||
|
successor.setPrev(newest);
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
111
src/it/algoritmi/adt/list/FavoritesList.java
Normal file
111
src/it/algoritmi/adt/list/FavoritesList.java
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Position;
|
||||||
|
import it.algoritmi.adt.PositionalList;
|
||||||
|
|
||||||
|
/** Gestisce una lista di elementi ordinati in base alla frequenza di accesso. */
|
||||||
|
public class FavoritesList<E> {
|
||||||
|
|
||||||
|
protected static class Item<E> {
|
||||||
|
private E value;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
public Item(E value) {
|
||||||
|
this.value = value;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment() {
|
||||||
|
++this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PositionalList<Item<E>> list = new LinkedPositionalList<>(); // lista di oggetti
|
||||||
|
|
||||||
|
/** Abbreviazione per accedere al preferito memorizzato in posizione position. */
|
||||||
|
protected E value(Position<Item<E>> position) {
|
||||||
|
return position.getElement().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Abbreviazione per accedere al conteggio associato alla posizione position. */
|
||||||
|
protected int count(Position<Item<E>> position) {
|
||||||
|
return position.getElement().getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce la Position che ha value uguale a element (o null se non trovato). */
|
||||||
|
protected Position<Item<E>> findPosition(E element) {
|
||||||
|
Position<Item<E>> walk = list.first();
|
||||||
|
while(walk != null && !element.equals(value(walk)))
|
||||||
|
walk = list.after(walk);
|
||||||
|
return walk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sposta verso sinistra l'oggetto in posizione position sulla base del conteggio. */
|
||||||
|
private void moveUp(Position<Item<E>> position) {
|
||||||
|
int cnt = count(position); // conteggio aggiornato dell'elemento a cui si è acceduto
|
||||||
|
Position<Item<E>> walk = position;
|
||||||
|
while (walk != list.first() && count(list.before(walk)) < cnt)
|
||||||
|
walk = list.before(walk); // trovato un conteggio minore a sinistra
|
||||||
|
if(walk != position) list.addBefore(walk, list.remove(position)); // elimina e reinserisce l'oggetto
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il numero di elementi presenti
|
||||||
|
* nella lista dei preferiti.
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce true se e solo se la lista
|
||||||
|
* dei preferiti è vuota.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return list.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accede all'elemento element (eventualmente nuovo),
|
||||||
|
* incrementando il suo conteggio.
|
||||||
|
*/
|
||||||
|
public void access(E element) {
|
||||||
|
Position<Item<E>> position = findPosition(element); // cerca un elemento esistente
|
||||||
|
if(position == null) position = list.addLast(new Item<E>(element)); // se nuovo, aggiunge alla fine
|
||||||
|
position.getElement().increment(); // in ogni caso, incrementa il conteggio
|
||||||
|
moveUp(position); // sposta a sinistra, se serve
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina dalla lista dei preferiti l'elemento
|
||||||
|
* uguale a element (se c'è).
|
||||||
|
*/
|
||||||
|
public void remove(E element) {
|
||||||
|
Position<Item<E>> position = findPosition(element); // cerca un elemento esitente
|
||||||
|
if (position != null) list.remove(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce un contenitore iterabile con i k elementi
|
||||||
|
* aventi più accessi.
|
||||||
|
*/
|
||||||
|
public Iterable<E> getFavorites(int k) throws IllegalArgumentException {
|
||||||
|
if(k < 0 || k > size()) throw new IllegalArgumentException("Invalid k");
|
||||||
|
PositionalList<E> result = new LinkedPositionalList<>();
|
||||||
|
Iterator<Item<E>> iter = list.iterator();
|
||||||
|
for(int j = 0; j < k; ++j) result.addLast(iter.next().getValue());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
46
src/it/algoritmi/adt/list/FavoritesListMTF.java
Normal file
46
src/it/algoritmi/adt/list/FavoritesListMTF.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Position;
|
||||||
|
import it.algoritmi.adt.PositionalList;
|
||||||
|
|
||||||
|
/** Gestisce una lista di preferiti usando l'euristica move-to-front */
|
||||||
|
public class FavoritesListMTF<E> extends FavoritesList<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sposta all'inizio della lista l'oggetto in posizione position
|
||||||
|
* a cui si è acceduto.
|
||||||
|
*/
|
||||||
|
protected void moveUp(Position<Item<E>> position) {
|
||||||
|
if(position != list.first()) list.addFirst(list.remove(position)); // elimina e reinserisce all'inizio
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce un contenitore iterabile con i k elementi
|
||||||
|
* aventi più accessi.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterable<E> getFavorites(int k) throws IllegalArgumentException {
|
||||||
|
if(k < 0 || k > size()) throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
// iniziamo facendo una copia della lista originale
|
||||||
|
PositionalList<Item<E>> tmp = new LinkedPositionalList<>();
|
||||||
|
for(Item<E> item : list) tmp.addLast(item);
|
||||||
|
|
||||||
|
// cerchiamo ed eliminiamo ripetutamente l'elemento con il conteggio massimo
|
||||||
|
PositionalList<E> result = new LinkedPositionalList<>();
|
||||||
|
for(int j = 0; j < k; ++j) {
|
||||||
|
Position<Item<E>> highPos = tmp.first();
|
||||||
|
Position<Item<E>> walk = tmp.after(highPos);
|
||||||
|
while(walk != null) {
|
||||||
|
if(count(walk) > count(highPos))
|
||||||
|
highPos = walk;
|
||||||
|
walk = tmp.after(walk);
|
||||||
|
}
|
||||||
|
// abbiamo trovato l'elemento con il conteggio massimo
|
||||||
|
result.addLast(value(highPos));
|
||||||
|
tmp.remove(highPos);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
303
src/it/algoritmi/adt/list/LinkedPositionalList.java
Normal file
303
src/it/algoritmi/adt/list/LinkedPositionalList.java
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Position;
|
||||||
|
import it.algoritmi.adt.PositionalList;
|
||||||
|
|
||||||
|
/** Implementazione di lista posizionale mediante lista doppiamente concatenata. */
|
||||||
|
public class LinkedPositionalList<E> implements PositionalList<E> {
|
||||||
|
|
||||||
|
private static class Node<E> implements Position<E> {
|
||||||
|
private E element; // riferimento all'elemento memorizzato in questo nodo
|
||||||
|
private Node<E> prev; // riferimento al nodo precedente nella lista
|
||||||
|
private Node<E> next; // riferimento al nodo seguente nella lista
|
||||||
|
|
||||||
|
public Node(E element, Node<E> prev, Node<E> next) {
|
||||||
|
this.element = element;
|
||||||
|
this.prev = prev;
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getPrev() {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrev(Node<E> prev) {
|
||||||
|
this.prev = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(Node<E> next) {
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElement(E element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getElement() throws IllegalStateException {
|
||||||
|
if(next == null) throw new IllegalStateException("Position no longer valid");
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node<E> header; // sentinella iniziale
|
||||||
|
private Node<E> trailer; // sentinella finale
|
||||||
|
private int size; // numero di elementi presenti nella lista
|
||||||
|
|
||||||
|
public LinkedPositionalList() {
|
||||||
|
header = new Node<>(null, null, null); // crea la sentinella iniziale
|
||||||
|
trailer = new Node<>(null, header, null); // trailer è preceduto da header
|
||||||
|
header.setNext(trailer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifica se la posizione è valida e la restituisce
|
||||||
|
* sotto forma di nodo.
|
||||||
|
*
|
||||||
|
* @param position
|
||||||
|
* @return
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
private Node<E> validate(Position<E> position) throws IllegalArgumentException {
|
||||||
|
if(!(position instanceof Node)) throw new IllegalArgumentException("Invalid p");
|
||||||
|
Node<E> node = (Node<E>) position; // cast sicuro
|
||||||
|
if(node.getNext() == null) throw new IllegalArgumentException("p is no longer in the list");
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il nodo sotto forma di Position (o null, se è una sentinella).
|
||||||
|
* @param node
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Position<E> position(Node<E> node) {
|
||||||
|
return (node != header && node != trailer) ? node : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce il numero di elementi presenti
|
||||||
|
* nella lista concatenata.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce true se e solo se la lista concatenata è vuota.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la prima Position della lista (o null, se la lista è vuota).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> first() {
|
||||||
|
return position(header.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce l'ultima Position della lista(o null, se la lista è vuota).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> last() {
|
||||||
|
return position(trailer.getPrev());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la Position che precede p (o null, se p è la prima).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> before(Position<E> position) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
return position(node.getPrev());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la Posizione che segue p (o null, se p è l'ultima).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> after(Position<E> position) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
return position(node.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggiunge l'elemento e alla lista concatenata
|
||||||
|
* tra i due nodi dati.
|
||||||
|
*
|
||||||
|
* @param element
|
||||||
|
* @param pred
|
||||||
|
* @param succ
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Position<E> addBeetween(E element, Node<E> pred, Node<E> succ) {
|
||||||
|
Node<E> newest = new Node<>(element, pred, succ);
|
||||||
|
pred.setNext(newest);
|
||||||
|
succ.setPrev(newest);
|
||||||
|
++size;
|
||||||
|
return newest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce l'elemento e all'inizio della lista;
|
||||||
|
* ne restituisce la posizione.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> addFirst(E element) {
|
||||||
|
return addBeetween(element, header, header.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce l'elemento e alla fine della lista;
|
||||||
|
* ne restituisce la posizione.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> addLast(E element) {
|
||||||
|
return addBeetween(element, trailer.getPrev(), trailer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce l'elemento e prima della Position p;
|
||||||
|
* ne restituisce la posizione.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> addBefore(Position<E> position, E element) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
return addBeetween(element, node.getPrev(), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserisce l'elemento e dopo la Position p;
|
||||||
|
* ne restituisce la posizione.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> addAfter(Position<E> position, E element) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
return addBeetween(element, node, node.getNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sostituisce l'elemento nella Position p;
|
||||||
|
* restituisce l'elemento sostituito.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E set(Position<E> position, E element) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
E answer = node.getElement();
|
||||||
|
node.setElement(element);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina e restituisce l'elemento nella Position p (poi p non è più valida).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public E remove(Position<E> position) throws IllegalArgumentException {
|
||||||
|
Node<E> node = validate(position);
|
||||||
|
Node<E> predecessor = node.getPrev();
|
||||||
|
Node<E> successor = node.getNext();
|
||||||
|
predecessor.setNext(successor);
|
||||||
|
successor.setPrev(predecessor);
|
||||||
|
--size;
|
||||||
|
E answer = node.getElement();
|
||||||
|
node.setElement(null);
|
||||||
|
node.setNext(null);
|
||||||
|
node.setPrev(null);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PositionIterator implements Iterator<Position<E>> {
|
||||||
|
private Position<E> cursor = first(); // prossima posizione da restituire
|
||||||
|
private Position<E> recent = null; // posizione restituita più recente
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifica se l'iteratore ha altro da restituire.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return cursor != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce la prossima posizione dell'iteratore.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Position<E> next() throws NoSuchElementException {
|
||||||
|
if(cursor == null) throw new NoSuchElementException("nothing left");
|
||||||
|
recent = cursor;
|
||||||
|
cursor = after(cursor);
|
||||||
|
return recent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina l'elemento restituito dalla più recente invocazione di next.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void remove() throws IllegalStateException {
|
||||||
|
if(recent == null) throw new IllegalArgumentException("nothing to remove");
|
||||||
|
LinkedPositionalList.this.remove(recent); // rimuova l'elemento della lista
|
||||||
|
recent = null; // non si può invocare di nuovo remove prima di next
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PositionIterable implements Iterable<Position<E>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Position<E>> iterator() {
|
||||||
|
return new PositionIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce una rappresentazione iterabile delle posizioni dela lista.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterable<Position<E>> positions() {
|
||||||
|
return new PositionIterable(); // crea un nuovo esemplare della classe interna
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adatta l'iteratore restituito da positions() perchè restituisca elementi.
|
||||||
|
*/
|
||||||
|
private class ElementIterator implements Iterator<E> {
|
||||||
|
Iterator<Position<E>> it = new PositionIterator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return it.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
return it.next().getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restituisce un iteratore degli elementi memorizzati nella lista.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new ElementIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
123
src/it/algoritmi/adt/list/SinglyLinkedList.java
Normal file
123
src/it/algoritmi/adt/list/SinglyLinkedList.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package it.algoritmi.adt.list;
|
||||||
|
|
||||||
|
public class SinglyLinkedList<E> implements Cloneable {
|
||||||
|
private Node<E> head = null;
|
||||||
|
private Node<E> tail = null;
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
private static class Node<E> {
|
||||||
|
private E element;
|
||||||
|
private Node<E> next;
|
||||||
|
|
||||||
|
public Node(E e, Node<E> n) {
|
||||||
|
element = e;
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<E> getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(Node<E> n) {
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E first() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return head.getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public E last() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return tail.getElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFirst(E e) {
|
||||||
|
head = new Node<>(e, head);
|
||||||
|
if(size == 0) {
|
||||||
|
tail = head;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLast(E e) {
|
||||||
|
Node<E> newest = new Node<>(e, null);
|
||||||
|
if(isEmpty()) {
|
||||||
|
head = newest;
|
||||||
|
} else {
|
||||||
|
tail.setNext(newest);
|
||||||
|
}
|
||||||
|
tail = newest;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public E removeFirst() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
E answer = head.getElement();
|
||||||
|
head = head.getNext();
|
||||||
|
size--;
|
||||||
|
if (size == 0) {
|
||||||
|
tail = null;
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
SinglyLinkedList other = (SinglyLinkedList) obj;
|
||||||
|
if (size != other.size)
|
||||||
|
return false;
|
||||||
|
Node walkA = head;
|
||||||
|
Node walkB = other.head;
|
||||||
|
while(walkA != null) {
|
||||||
|
if (!walkA.getElement().equals(walkB.getElement()))
|
||||||
|
return false;
|
||||||
|
walkA = walkA.getNext();
|
||||||
|
walkB = walkB.getNext();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
|
||||||
|
SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone();
|
||||||
|
if (size > 0) {
|
||||||
|
other.head = new Node<>(head.getElement(), null);
|
||||||
|
Node<E> walk = head.getNext();
|
||||||
|
Node<E> otherTail = other.head;
|
||||||
|
while(walk != null) {
|
||||||
|
Node<E> newest = new Node<>(walk.getElement(), null);
|
||||||
|
otherTail.setNext(newest);
|
||||||
|
otherTail = newest;
|
||||||
|
walk = walk.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
62
src/it/algoritmi/adt/queue/ArrayQueue.java
Normal file
62
src/it/algoritmi/adt/queue/ArrayQueue.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package it.algoritmi.adt.queue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Queue;
|
||||||
|
|
||||||
|
public class ArrayQueue<E> implements Queue<E> {
|
||||||
|
public static final int CAPACITY = 1000;
|
||||||
|
|
||||||
|
private E[] data;
|
||||||
|
private int size;
|
||||||
|
private int f;
|
||||||
|
|
||||||
|
public ArrayQueue() {
|
||||||
|
this(CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public ArrayQueue(int capacity) {
|
||||||
|
data = (E[]) new Object[capacity];
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enqueue(E element) throws IllegalStateException {
|
||||||
|
if (size() == data.length) {
|
||||||
|
throw new IllegalStateException("Queue is full");
|
||||||
|
}
|
||||||
|
int avail = (f + size) % data.length;
|
||||||
|
data[avail] = element;
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E dequeue() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
E answer = data[f];
|
||||||
|
data[f] = null;
|
||||||
|
f = (f + 1) % data.length;
|
||||||
|
--size;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E first() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data[f];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
src/it/algoritmi/adt/queue/DoubleLinkedQueue.java
Normal file
35
src/it/algoritmi/adt/queue/DoubleLinkedQueue.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package it.algoritmi.adt.queue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Deque;
|
||||||
|
import it.algoritmi.adt.Queue;
|
||||||
|
import it.algoritmi.adt.dequeue.LinkedDeque;
|
||||||
|
|
||||||
|
public class DoubleLinkedQueue<E> implements Queue<E> {
|
||||||
|
private Deque<E> d = new LinkedDeque<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return d.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return d.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enqueue(E element) {
|
||||||
|
d.addFirst(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E dequeue() {
|
||||||
|
return d.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E first() {
|
||||||
|
return d.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
14
src/it/algoritmi/adt/queue/LinkedCircularQueue.java
Normal file
14
src/it/algoritmi/adt/queue/LinkedCircularQueue.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package it.algoritmi.adt.queue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.CircularQueue;
|
||||||
|
import it.algoritmi.adt.list.CircularyLinkedList;
|
||||||
|
|
||||||
|
public class LinkedCircularQueue<E> extends LinkedQueue<E> implements CircularQueue<E> {
|
||||||
|
private CircularyLinkedList<E> list = new CircularyLinkedList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rotate() {
|
||||||
|
list.rotate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/it/algoritmi/adt/queue/LinkedQueue.java
Normal file
34
src/it/algoritmi/adt/queue/LinkedQueue.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package it.algoritmi.adt.queue;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Queue;
|
||||||
|
import it.algoritmi.adt.list.SinglyLinkedList;
|
||||||
|
|
||||||
|
public class LinkedQueue<E> implements Queue<E> {
|
||||||
|
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return list.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enqueue(E element) {
|
||||||
|
list.addLast(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E dequeue() {
|
||||||
|
return list.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E first() {
|
||||||
|
return list.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
56
src/it/algoritmi/adt/stack/ArrayStack.java
Normal file
56
src/it/algoritmi/adt/stack/ArrayStack.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package it.algoritmi.adt.stack;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
|
||||||
|
public class ArrayStack<E> implements Stack<E> {
|
||||||
|
public static final int CAPACITY = 1000;
|
||||||
|
private E[] data;
|
||||||
|
private int t = -1;
|
||||||
|
|
||||||
|
public ArrayStack() {
|
||||||
|
this(CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public ArrayStack(int capacity) {
|
||||||
|
data = (E[]) new Object[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return t + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return t == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void push(E element) throws IllegalStateException {
|
||||||
|
if (size() == data.length) {
|
||||||
|
throw new IllegalStateException("Stack is full");
|
||||||
|
}
|
||||||
|
data[++t] = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E top() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pop() {
|
||||||
|
if(isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
E answer = data[t];
|
||||||
|
data[t] = null;
|
||||||
|
t--;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
src/it/algoritmi/adt/stack/DoubledLinkedStack.java
Normal file
35
src/it/algoritmi/adt/stack/DoubledLinkedStack.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package it.algoritmi.adt.stack;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Deque;
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
import it.algoritmi.adt.dequeue.LinkedDeque;
|
||||||
|
|
||||||
|
public class DoubledLinkedStack<E> implements Stack<E> {
|
||||||
|
private Deque<E> d = new LinkedDeque<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return d.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return d.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void push(E element) {
|
||||||
|
d.addFirst(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E top() {
|
||||||
|
return d.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pop() {
|
||||||
|
return d.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/it/algoritmi/adt/stack/LinkedStack.java
Normal file
34
src/it/algoritmi/adt/stack/LinkedStack.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package it.algoritmi.adt.stack;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
import it.algoritmi.adt.list.SinglyLinkedList;
|
||||||
|
|
||||||
|
public class LinkedStack<E> implements Stack<E> {
|
||||||
|
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return list.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void push(E element) {
|
||||||
|
list.addFirst(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E top() {
|
||||||
|
return list.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E pop() {
|
||||||
|
return list.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
56
src/it/algoritmi/test/ADTs.java
Normal file
56
src/it/algoritmi/test/ADTs.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Deque;
|
||||||
|
import it.algoritmi.adt.Queue;
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
import it.algoritmi.adt.dequeue.ArrayDeque;
|
||||||
|
import it.algoritmi.adt.queue.LinkedQueue;
|
||||||
|
import it.algoritmi.adt.stack.ArrayStack;
|
||||||
|
|
||||||
|
public class ADTs {
|
||||||
|
|
||||||
|
public static <E> void transfer(Stack<E> s, Stack<E> t) {
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
for(int i = 0, len = s.size(); i < len; ++i)
|
||||||
|
t.push(s.pop());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E> void removeAll(Stack<E> s) {
|
||||||
|
if(s.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s.pop();
|
||||||
|
removeAll(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E> void shuffle(Deque<E> d) {
|
||||||
|
Queue<E> q = new LinkedQueue<>();
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private static <E> Stack<E> buildStack(E... elements) {
|
||||||
|
Stack<E> result = new ArrayStack<>();
|
||||||
|
for(E elem : elements)
|
||||||
|
result.push(elem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
private static <E> Deque<E> buildDequeue(E... elements) {
|
||||||
|
Deque<E> result = new ArrayDeque<>();
|
||||||
|
for(E elem : elements)
|
||||||
|
result.addLast(elem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Stack<Integer> s1 = buildStack(1, 2, 3, 4, 5);
|
||||||
|
Stack<Integer> s2 = buildStack(6, 7, 8, 9, 0);
|
||||||
|
transfer(s1, s2);
|
||||||
|
removeAll(s2);
|
||||||
|
Deque<Integer> dk = buildDequeue(1, 2, 3, 4, 5, 6, 7, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
31
src/it/algoritmi/test/ArithmeticMatcher.java
Normal file
31
src/it/algoritmi/test/ArithmeticMatcher.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
import it.algoritmi.adt.stack.LinkedStack;
|
||||||
|
|
||||||
|
public class ArithmeticMatcher {
|
||||||
|
|
||||||
|
public static boolean isMatched(String expression) {
|
||||||
|
final String opening = "({[";
|
||||||
|
final String closing = ")}]";
|
||||||
|
Stack<Character> buffer = new LinkedStack<>();
|
||||||
|
for(char c : expression.toCharArray()) {
|
||||||
|
if(opening.indexOf(c) != -1) {
|
||||||
|
buffer.push(c);
|
||||||
|
} else if(closing.indexOf(c) != -1) {
|
||||||
|
if(buffer.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(closing.indexOf(c) != opening.indexOf(buffer.pop())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String exp = "(10 + 4) * 89";
|
||||||
|
System.out.println(isMatched(exp));
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/it/algoritmi/test/CaesarCipher.java
Normal file
47
src/it/algoritmi/test/CaesarCipher.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
public class CaesarCipher {
|
||||||
|
protected char[] encoder = new char[26];
|
||||||
|
protected char[] decoder = new char[26];
|
||||||
|
|
||||||
|
public CaesarCipher(int rotation) {
|
||||||
|
for (int k = 0; k < 26; ++k) {
|
||||||
|
encoder[k] = (char) ('A' + (k + rotation) % 26);
|
||||||
|
decoder[k] = (char) ('A' + (k - rotation + 26) % 26);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce il messaggio cifrato. */
|
||||||
|
public String encrypt(String message) {
|
||||||
|
return trasform(message, encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce il messaggio decifrato. */
|
||||||
|
public String decrypt(String secret) {
|
||||||
|
return trasform(secret, decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Restituisce la trasformazione della stringa ricevuta secondo il codice dato. */
|
||||||
|
private String trasform(String original, char[] code) {
|
||||||
|
char[] msg = original.toCharArray();
|
||||||
|
for (int k = 0; k < msg.length; ++k) {
|
||||||
|
if(Character.isUpperCase(msg[k])) {
|
||||||
|
int j = msg[k] - 'A';
|
||||||
|
msg[k] = code[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new String(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
CaesarCipher cipher = new CaesarCipher(3);
|
||||||
|
System.out.println("Encryption code = " + new String(cipher.encoder));
|
||||||
|
System.out.println("Decryption code = " + new String(cipher.decoder));
|
||||||
|
String message = "THE EAGLE IS IN PLAY; MEET AT JOE'S.";
|
||||||
|
String coded = cipher.encrypt(message);
|
||||||
|
System.out.println("Secret: " + coded);
|
||||||
|
String answer = cipher.decrypt(coded);
|
||||||
|
System.out.println("Message: " + answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
83
src/it/algoritmi/test/CreditCard.java
Normal file
83
src/it/algoritmi/test/CreditCard.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
public class CreditCard {
|
||||||
|
private String customer;
|
||||||
|
private String bank;
|
||||||
|
private String account;
|
||||||
|
private int limit;
|
||||||
|
protected double balance;
|
||||||
|
|
||||||
|
public CreditCard(String customer, String bank, String account, int limit) {
|
||||||
|
this(customer, bank, account, limit, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreditCard(String customer, String bank, String account, int limit, double balance) {
|
||||||
|
this.customer = customer;
|
||||||
|
this.bank = bank;
|
||||||
|
this.account = account;
|
||||||
|
this.limit = limit;
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomer() {
|
||||||
|
return customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomer(String customer) {
|
||||||
|
this.customer = customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBank() {
|
||||||
|
return bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBank(String bank) {
|
||||||
|
this.bank = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccount(String account) {
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLimit() {
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimit(int limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBalance() {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(double balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean charge(double price) {
|
||||||
|
if(price + balance > limit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
balance += price;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void makePayment(double amount) {
|
||||||
|
balance -= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printSummary(CreditCard card) {
|
||||||
|
System.out.println("Customer = " + card.customer);
|
||||||
|
System.out.println("Bank = " + card.bank);
|
||||||
|
System.out.println("Account = " + card.account);
|
||||||
|
System.out.println("Balance = " + card.balance);
|
||||||
|
System.out.println("Limit = " + card.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
36
src/it/algoritmi/test/HTMLMatcher.java
Normal file
36
src/it/algoritmi/test/HTMLMatcher.java
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.Stack;
|
||||||
|
import it.algoritmi.adt.stack.LinkedStack;
|
||||||
|
|
||||||
|
public class HTMLMatcher {
|
||||||
|
|
||||||
|
public static boolean isHTMLMatched(String html) {
|
||||||
|
Stack<String> buffer = new LinkedStack<>();
|
||||||
|
int j = html.indexOf('<');
|
||||||
|
while(j != -1) {
|
||||||
|
int k = html.indexOf('>', j+1);
|
||||||
|
if(k == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String tag = html.substring(j+1, k);
|
||||||
|
if(!tag.startsWith("/")) {
|
||||||
|
buffer.push(tag);
|
||||||
|
} else {
|
||||||
|
if(buffer.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!tag.substring(1).equals(buffer.pop())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j = html.indexOf('<', k+1);
|
||||||
|
}
|
||||||
|
return buffer.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
40
src/it/algoritmi/test/Josephus.java
Normal file
40
src/it/algoritmi/test/Josephus.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
import it.algoritmi.adt.CircularQueue;
|
||||||
|
import it.algoritmi.adt.queue.LinkedCircularQueue;
|
||||||
|
|
||||||
|
public class Josephus {
|
||||||
|
/** Determina il vincitore del problema di Josephus usando una coda circolare. */
|
||||||
|
public static <E> E josephus(CircularQueue<E> queue, int k) {
|
||||||
|
if(queue.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
while(queue.size() > 1) {
|
||||||
|
for (int i = 0; i < k-1; ++i) {
|
||||||
|
queue.rotate();
|
||||||
|
}
|
||||||
|
E e = queue.dequeue();
|
||||||
|
System.out.println(" " + e + " is out");
|
||||||
|
}
|
||||||
|
return queue.dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Costruisce una coda circolare a partire da un array di oggetti. */
|
||||||
|
public static <E> CircularQueue<E> buildQueue(E a[]) {
|
||||||
|
CircularQueue<E> queue = new LinkedCircularQueue<>();
|
||||||
|
for(int i = 0; i < a.length; ++i) {
|
||||||
|
queue.enqueue(a[i]);
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String[] a1 = {"Alice", "Bob", "Cindy", "Doug", "Ed", "Fred"};
|
||||||
|
String[] a2 = {"Gene", "Hope", "Irene", "Jack", "Kim", "Lance"};
|
||||||
|
String[] a3 = {"Mike", "Roberto"};
|
||||||
|
System.out.println("First winner is " + josephus(buildQueue(a1), 3));
|
||||||
|
System.out.println("Second winner is " + josephus(buildQueue(a2), 10));
|
||||||
|
System.out.println("Third winner is " + josephus(buildQueue(a3), 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/it/algoritmi/test/PredatoryCreditCard.java
Normal file
28
src/it/algoritmi/test/PredatoryCreditCard.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package it.algoritmi.test;
|
||||||
|
|
||||||
|
public class PredatoryCreditCard extends CreditCard {
|
||||||
|
private double rate;
|
||||||
|
|
||||||
|
public PredatoryCreditCard(String customer, String bank, String account,
|
||||||
|
int limit, double initialBalance, double rate) {
|
||||||
|
super(customer, bank, account, limit, initialBalance);
|
||||||
|
this.rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processMoth() {
|
||||||
|
if(balance > 0) {
|
||||||
|
double monthlyFactor = Math.pow(1 + rate, 1. / 12);
|
||||||
|
balance *= monthlyFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean charge(double price) {
|
||||||
|
boolean isSuccess = super.charge(price);
|
||||||
|
if(!isSuccess) {
|
||||||
|
balance += 5;
|
||||||
|
}
|
||||||
|
return isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user