commit 988025618b24ef1cf9d2a0cbfc64afef430ca360 Author: Fabio Scotto di Santolo Date: Tue Feb 20 11:37:37 2018 +0100 initial commit diff --git a/.classpath b/.classpath new file mode 100755 index 0000000..2197894 --- /dev/null +++ b/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.project b/.project new file mode 100755 index 0000000..689b264 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + AlgoritmiStruttureDati + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 0000000..ace45ce --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/src/it/algoritmi/adt/CircularQueue.java b/src/it/algoritmi/adt/CircularQueue.java new file mode 100644 index 0000000..9b487b6 --- /dev/null +++ b/src/it/algoritmi/adt/CircularQueue.java @@ -0,0 +1,11 @@ +package it.algoritmi.adt; + +public interface CircularQueue extends Queue { + + /** + * Sposta alla fine della coda il suo elemento iniziale. + * Se la coda è vuota non fa niente. + */ + void rotate(); + +} diff --git a/src/it/algoritmi/adt/Deque.java b/src/it/algoritmi/adt/Deque.java new file mode 100644 index 0000000..f28c28b --- /dev/null +++ b/src/it/algoritmi/adt/Deque.java @@ -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 { + + /** Restituisce il numero di elementi presenti nella coda doppia. */ + int size(); + + /** Verifica se la coda doppia è vuota. */ + boolean isEmpty(); + + /** Restituisce il primo elemento, senza toglierlo (null se la coda è vuota). */ + E first(); + + /** Restituisce l'ultimo elemento, senza toglierlo (null se la coda è 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 è vuota). */ + E removeFirst(); + + /** Elimina e restituisce l'ultimo elemento della coda (null se è vuota). */ + E removeLast(); + +} diff --git a/src/it/algoritmi/adt/List.java b/src/it/algoritmi/adt/List.java new file mode 100644 index 0000000..2b00a00 --- /dev/null +++ b/src/it/algoritmi/adt/List.java @@ -0,0 +1,24 @@ +package it.algoritmi.adt; + +/** Una versione semplificata dell'interfaccia java.util.List. */ +public interface List extends Iterable { + + /** 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; + +} diff --git a/src/it/algoritmi/adt/Position.java b/src/it/algoritmi/adt/Position.java new file mode 100644 index 0000000..0ab058f --- /dev/null +++ b/src/it/algoritmi/adt/Position.java @@ -0,0 +1,13 @@ +package it.algoritmi.adt; + +public interface Position { + + /** + * Restituisce l'elemento memorizzato in questa posizione. + * + * @return l'elemento memorizzato + * @throws IllegalStateException se la posizione non è più valida + */ + E getElement() throws IllegalStateException; + +} diff --git a/src/it/algoritmi/adt/PositionalList.java b/src/it/algoritmi/adt/PositionalList.java new file mode 100644 index 0000000..f58c5bf --- /dev/null +++ b/src/it/algoritmi/adt/PositionalList.java @@ -0,0 +1,45 @@ +package it.algoritmi.adt; + +/** L'interfaccia che definisce liste posizionali. */ +public interface PositionalList extends Iterable { + + /** 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 first(); + + /** Restituisce l'ultima Position della lista (o null se la lista è vuota). */ + Position last(); + + /** Restituisce la Position che precede p (o null, se p è la prima). */ + Position before(Position position) throws IllegalArgumentException; + + /** Restituisce la Position che segue p (o null, se p è l'ultima). */ + Position after(Position position) throws IllegalArgumentException; + + /** Inserisce l'elemento e all'inizio della lista; ne restituisce la posizione. */ + Position addFirst(E element); + + /** Inserisce l'elemento e alla fine della lista; ne restituisce la posizione. */ + Position addLast(E element); + + /** Inserisce l'elemento e prima della Position p; ne restituisce la posizione. */ + Position addBefore(Position position, E element) throws IllegalArgumentException; + + /** Inserisce l'elemento e dopo la Position p; ne restituisce la posizione. */ + Position addAfter(Position position, E element) throws IllegalArgumentException; + + /** Sostituisce l'elemento nella Position p; restituisce l'elemento sostituito. */ + E set(Position position, E element) throws IllegalArgumentException; + + /** Elimina e restituisce l'elemento nella Position p; (poi p non è più valida). */ + E remove(Position position) throws IllegalArgumentException; + + /** Restituisce una rappresentazione iterabile delle posizioni dela lista. */ + public Iterable> positions(); + +} diff --git a/src/it/algoritmi/adt/Queue.java b/src/it/algoritmi/adt/Queue.java new file mode 100644 index 0000000..3d43795 --- /dev/null +++ b/src/it/algoritmi/adt/Queue.java @@ -0,0 +1,20 @@ +package it.algoritmi.adt; + +public interface Queue { + + /** Restituisce il numero di elementi presenti nella coda. */ + public int size(); + + /** Verifica se la coda è 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 è vuota). */ + public E dequeue(); + + /** Restituisce il primo elemento della coda, senza toglierlo (null se è vuota). */ + public E first(); + +} diff --git a/src/it/algoritmi/adt/Stack.java b/src/it/algoritmi/adt/Stack.java new file mode 100644 index 0000000..4be8d20 --- /dev/null +++ b/src/it/algoritmi/adt/Stack.java @@ -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 è diversa da + * java.util.Stack + * + * @author fscotto + * + */ +public interface Stack { + + /** + * Restituisce il numero di elementi presenti nella pila. + * @return il numero di elementi presenti nella pila. + */ + int size(); + + /** + * Verifica se la pila è vuota. + * @return true se e solo se la pila è 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 è vuota) + */ + E top(); + + /** + * Elimina e restituisce l'elemento che si trova in cima alla pila. + * @return l'elemento eliminato (o null se la pila è vuota) + */ + E pop(); + +} diff --git a/src/it/algoritmi/adt/dequeue/ArrayDeque.java b/src/it/algoritmi/adt/dequeue/ArrayDeque.java new file mode 100644 index 0000000..d64fed1 --- /dev/null +++ b/src/it/algoritmi/adt/dequeue/ArrayDeque.java @@ -0,0 +1,82 @@ +package it.algoritmi.adt.dequeue; + +import it.algoritmi.adt.Deque; + +public class ArrayDeque implements Deque { + 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; + } + +} diff --git a/src/it/algoritmi/adt/dequeue/LinkedDeque.java b/src/it/algoritmi/adt/dequeue/LinkedDeque.java new file mode 100644 index 0000000..6dd45e1 --- /dev/null +++ b/src/it/algoritmi/adt/dequeue/LinkedDeque.java @@ -0,0 +1,49 @@ +package it.algoritmi.adt.dequeue; + +import it.algoritmi.adt.Deque; +import it.algoritmi.adt.list.DoublyLinkedList; + +public class LinkedDeque implements Deque { + private DoublyLinkedList 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(); + } + +} diff --git a/src/it/algoritmi/adt/list/ArrayList.java b/src/it/algoritmi/adt/list/ArrayList.java new file mode 100644 index 0000000..b6bf000 --- /dev/null +++ b/src/it/algoritmi/adt/list/ArrayList.java @@ -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 implements List { + // 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 { + 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 iterator() { + return new ArrayIterator(); + } + +} diff --git a/src/it/algoritmi/adt/list/CircularyLinkedList.java b/src/it/algoritmi/adt/list/CircularyLinkedList.java new file mode 100644 index 0000000..983bee8 --- /dev/null +++ b/src/it/algoritmi/adt/list/CircularyLinkedList.java @@ -0,0 +1,86 @@ +package it.algoritmi.adt.list; + +public class CircularyLinkedList { + private Node tail = null; + private int size = 0; + + private static class Node { + private E element; + private Node next; + + public Node(E e, Node n) { + element = e; + next = n; + } + + public E getElement() { + return element; + } + + public Node getNext() { + return next; + } + + public void setNext(Node 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 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 head = tail.getNext(); + if(head == tail) { + tail = null; + } else { + tail.setNext(head.getNext()); + } + size--; + return head.getElement(); + } +} diff --git a/src/it/algoritmi/adt/list/DoublyLinkedList.java b/src/it/algoritmi/adt/list/DoublyLinkedList.java new file mode 100644 index 0000000..1daa16b --- /dev/null +++ b/src/it/algoritmi/adt/list/DoublyLinkedList.java @@ -0,0 +1,120 @@ +package it.algoritmi.adt.list; + +public class DoublyLinkedList { + private Node header; + private Node trailer; + private int size = 0; + + private static class Node { + private E element; + private Node prev; + private Node next; + + private Node(E e, Node prev, Node next) { + element = e; + this.prev = prev; + this.next = next; + } + + public Node getPrev() { + return prev; + } + + public void setPrev(Node prev) { + this.prev = prev; + } + + public Node getNext() { + return next; + } + + public void setNext(Node 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 è 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 node) { + Node predecessor = node.getPrev(); + Node 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 predecessor, Node successor) { + // crea un nuovo nodo e lo collega alla lista + Node newest = new Node<>(e, predecessor, successor); + predecessor.setNext(newest); + successor.setPrev(newest); + ++size; + } + +} diff --git a/src/it/algoritmi/adt/list/FavoritesList.java b/src/it/algoritmi/adt/list/FavoritesList.java new file mode 100644 index 0000000..f24a797 --- /dev/null +++ b/src/it/algoritmi/adt/list/FavoritesList.java @@ -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 { + + protected static class Item { + 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> list = new LinkedPositionalList<>(); // lista di oggetti + + /** Abbreviazione per accedere al preferito memorizzato in posizione position. */ + protected E value(Position> position) { + return position.getElement().getValue(); + } + + /** Abbreviazione per accedere al conteggio associato alla posizione position. */ + protected int count(Position> position) { + return position.getElement().getCount(); + } + + /** Restituisce la Position che ha value uguale a element (o null se non trovato). */ + protected Position> findPosition(E element) { + Position> 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> position) { + int cnt = count(position); // conteggio aggiornato dell'elemento a cui si è acceduto + Position> 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> position = findPosition(element); // cerca un elemento esistente + if(position == null) position = list.addLast(new Item(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> 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 getFavorites(int k) throws IllegalArgumentException { + if(k < 0 || k > size()) throw new IllegalArgumentException("Invalid k"); + PositionalList result = new LinkedPositionalList<>(); + Iterator> iter = list.iterator(); + for(int j = 0; j < k; ++j) result.addLast(iter.next().getValue()); + return result; + } + +} diff --git a/src/it/algoritmi/adt/list/FavoritesListMTF.java b/src/it/algoritmi/adt/list/FavoritesListMTF.java new file mode 100644 index 0000000..658ce27 --- /dev/null +++ b/src/it/algoritmi/adt/list/FavoritesListMTF.java @@ -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 extends FavoritesList { + + /** + * Sposta all'inizio della lista l'oggetto in posizione position + * a cui si è acceduto. + */ + protected void moveUp(Position> 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 getFavorites(int k) throws IllegalArgumentException { + if(k < 0 || k > size()) throw new IllegalArgumentException(); + + // iniziamo facendo una copia della lista originale + PositionalList> tmp = new LinkedPositionalList<>(); + for(Item item : list) tmp.addLast(item); + + // cerchiamo ed eliminiamo ripetutamente l'elemento con il conteggio massimo + PositionalList result = new LinkedPositionalList<>(); + for(int j = 0; j < k; ++j) { + Position> highPos = tmp.first(); + Position> 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; + } + +} diff --git a/src/it/algoritmi/adt/list/LinkedPositionalList.java b/src/it/algoritmi/adt/list/LinkedPositionalList.java new file mode 100644 index 0000000..1954eba --- /dev/null +++ b/src/it/algoritmi/adt/list/LinkedPositionalList.java @@ -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 implements PositionalList { + + private static class Node implements Position { + private E element; // riferimento all'elemento memorizzato in questo nodo + private Node prev; // riferimento al nodo precedente nella lista + private Node next; // riferimento al nodo seguente nella lista + + public Node(E element, Node prev, Node next) { + this.element = element; + this.prev = prev; + this.next = next; + } + + public Node getPrev() { + return prev; + } + + public void setPrev(Node prev) { + this.prev = prev; + } + + public Node getNext() { + return next; + } + + public void setNext(Node 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 header; // sentinella iniziale + private Node 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 validate(Position position) throws IllegalArgumentException { + if(!(position instanceof Node)) throw new IllegalArgumentException("Invalid p"); + Node node = (Node) 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 position(Node 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 first() { + return position(header.getNext()); + } + + /** + * Restituisce l'ultima Position della lista(o null, se la lista è vuota). + */ + @Override + public Position last() { + return position(trailer.getPrev()); + } + + /** + * Restituisce la Position che precede p (o null, se p è la prima). + */ + @Override + public Position before(Position position) throws IllegalArgumentException { + Node node = validate(position); + return position(node.getPrev()); + } + + /** + * Restituisce la Posizione che segue p (o null, se p è l'ultima). + */ + @Override + public Position after(Position position) throws IllegalArgumentException { + Node 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 addBeetween(E element, Node pred, Node succ) { + Node 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 addFirst(E element) { + return addBeetween(element, header, header.getNext()); + } + + /** + * Inserisce l'elemento e alla fine della lista; + * ne restituisce la posizione. + */ + @Override + public Position addLast(E element) { + return addBeetween(element, trailer.getPrev(), trailer); + } + + /** + * Inserisce l'elemento e prima della Position p; + * ne restituisce la posizione. + */ + @Override + public Position addBefore(Position position, E element) throws IllegalArgumentException { + Node node = validate(position); + return addBeetween(element, node.getPrev(), node); + } + + /** + * Inserisce l'elemento e dopo la Position p; + * ne restituisce la posizione. + */ + @Override + public Position addAfter(Position position, E element) throws IllegalArgumentException { + Node node = validate(position); + return addBeetween(element, node, node.getNext()); + } + + /** + * Sostituisce l'elemento nella Position p; + * restituisce l'elemento sostituito. + */ + @Override + public E set(Position position, E element) throws IllegalArgumentException { + Node 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 position) throws IllegalArgumentException { + Node node = validate(position); + Node predecessor = node.getPrev(); + Node 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> { + private Position cursor = first(); // prossima posizione da restituire + private Position 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 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> { + + @Override + public Iterator> iterator() { + return new PositionIterator(); + } + + } + + /** + * Restituisce una rappresentazione iterabile delle posizioni dela lista. + */ + @Override + public Iterable> 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 { + Iterator> 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 iterator() { + return new ElementIterator(); + } + +} diff --git a/src/it/algoritmi/adt/list/SinglyLinkedList.java b/src/it/algoritmi/adt/list/SinglyLinkedList.java new file mode 100644 index 0000000..bebaf90 --- /dev/null +++ b/src/it/algoritmi/adt/list/SinglyLinkedList.java @@ -0,0 +1,123 @@ +package it.algoritmi.adt.list; + +public class SinglyLinkedList implements Cloneable { + private Node head = null; + private Node tail = null; + private int size = 0; + + private static class Node { + private E element; + private Node next; + + public Node(E e, Node n) { + element = e; + next = n; + } + + public E getElement() { + return element; + } + + public Node getNext() { + return next; + } + + public void setNext(Node 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 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 clone() throws CloneNotSupportedException { + SinglyLinkedList other = (SinglyLinkedList) super.clone(); + if (size > 0) { + other.head = new Node<>(head.getElement(), null); + Node walk = head.getNext(); + Node otherTail = other.head; + while(walk != null) { + Node newest = new Node<>(walk.getElement(), null); + otherTail.setNext(newest); + otherTail = newest; + walk = walk.getNext(); + } + } + return other; + } + +} diff --git a/src/it/algoritmi/adt/queue/ArrayQueue.java b/src/it/algoritmi/adt/queue/ArrayQueue.java new file mode 100644 index 0000000..cdb8fe7 --- /dev/null +++ b/src/it/algoritmi/adt/queue/ArrayQueue.java @@ -0,0 +1,62 @@ +package it.algoritmi.adt.queue; + +import it.algoritmi.adt.Queue; + +public class ArrayQueue implements Queue { + 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]; + } + +} diff --git a/src/it/algoritmi/adt/queue/DoubleLinkedQueue.java b/src/it/algoritmi/adt/queue/DoubleLinkedQueue.java new file mode 100644 index 0000000..e0f2783 --- /dev/null +++ b/src/it/algoritmi/adt/queue/DoubleLinkedQueue.java @@ -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 implements Queue { + private Deque 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(); + } + +} diff --git a/src/it/algoritmi/adt/queue/LinkedCircularQueue.java b/src/it/algoritmi/adt/queue/LinkedCircularQueue.java new file mode 100644 index 0000000..8c8e681 --- /dev/null +++ b/src/it/algoritmi/adt/queue/LinkedCircularQueue.java @@ -0,0 +1,14 @@ +package it.algoritmi.adt.queue; + +import it.algoritmi.adt.CircularQueue; +import it.algoritmi.adt.list.CircularyLinkedList; + +public class LinkedCircularQueue extends LinkedQueue implements CircularQueue { + private CircularyLinkedList list = new CircularyLinkedList<>(); + + @Override + public void rotate() { + list.rotate(); + } + +} diff --git a/src/it/algoritmi/adt/queue/LinkedQueue.java b/src/it/algoritmi/adt/queue/LinkedQueue.java new file mode 100644 index 0000000..8744be6 --- /dev/null +++ b/src/it/algoritmi/adt/queue/LinkedQueue.java @@ -0,0 +1,34 @@ +package it.algoritmi.adt.queue; + +import it.algoritmi.adt.Queue; +import it.algoritmi.adt.list.SinglyLinkedList; + +public class LinkedQueue implements Queue { + private SinglyLinkedList 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(); + } + +} diff --git a/src/it/algoritmi/adt/stack/ArrayStack.java b/src/it/algoritmi/adt/stack/ArrayStack.java new file mode 100644 index 0000000..3730737 --- /dev/null +++ b/src/it/algoritmi/adt/stack/ArrayStack.java @@ -0,0 +1,56 @@ +package it.algoritmi.adt.stack; + +import it.algoritmi.adt.Stack; + +public class ArrayStack implements Stack { + 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; + } + +} diff --git a/src/it/algoritmi/adt/stack/DoubledLinkedStack.java b/src/it/algoritmi/adt/stack/DoubledLinkedStack.java new file mode 100644 index 0000000..b187dab --- /dev/null +++ b/src/it/algoritmi/adt/stack/DoubledLinkedStack.java @@ -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 implements Stack { + private Deque 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(); + } + +} diff --git a/src/it/algoritmi/adt/stack/LinkedStack.java b/src/it/algoritmi/adt/stack/LinkedStack.java new file mode 100644 index 0000000..1c15001 --- /dev/null +++ b/src/it/algoritmi/adt/stack/LinkedStack.java @@ -0,0 +1,34 @@ +package it.algoritmi.adt.stack; + +import it.algoritmi.adt.Stack; +import it.algoritmi.adt.list.SinglyLinkedList; + +public class LinkedStack implements Stack { + private SinglyLinkedList 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(); + } + +} diff --git a/src/it/algoritmi/test/ADTs.java b/src/it/algoritmi/test/ADTs.java new file mode 100644 index 0000000..8b22e0f --- /dev/null +++ b/src/it/algoritmi/test/ADTs.java @@ -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 void transfer(Stack s, Stack t) { + if(!s.isEmpty()) { + for(int i = 0, len = s.size(); i < len; ++i) + t.push(s.pop()); + } + } + + public static void removeAll(Stack s) { + if(s.isEmpty()) { + return; + } + s.pop(); + removeAll(s); + } + + public static void shuffle(Deque d) { + Queue q = new LinkedQueue<>(); + // TODO + } + + @SafeVarargs + private static Stack buildStack(E... elements) { + Stack result = new ArrayStack<>(); + for(E elem : elements) + result.push(elem); + return result; + } + + @SafeVarargs + private static Deque buildDequeue(E... elements) { + Deque result = new ArrayDeque<>(); + for(E elem : elements) + result.addLast(elem); + return result; + } + + public static void main(String[] args) { + Stack s1 = buildStack(1, 2, 3, 4, 5); + Stack s2 = buildStack(6, 7, 8, 9, 0); + transfer(s1, s2); + removeAll(s2); + Deque dk = buildDequeue(1, 2, 3, 4, 5, 6, 7, 8); + } + +} diff --git a/src/it/algoritmi/test/ArithmeticMatcher.java b/src/it/algoritmi/test/ArithmeticMatcher.java new file mode 100644 index 0000000..9d6cd38 --- /dev/null +++ b/src/it/algoritmi/test/ArithmeticMatcher.java @@ -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 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)); + } +} diff --git a/src/it/algoritmi/test/CaesarCipher.java b/src/it/algoritmi/test/CaesarCipher.java new file mode 100644 index 0000000..6f16468 --- /dev/null +++ b/src/it/algoritmi/test/CaesarCipher.java @@ -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); + } + +} diff --git a/src/it/algoritmi/test/CreditCard.java b/src/it/algoritmi/test/CreditCard.java new file mode 100644 index 0000000..d96ed05 --- /dev/null +++ b/src/it/algoritmi/test/CreditCard.java @@ -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); + } + +} diff --git a/src/it/algoritmi/test/HTMLMatcher.java b/src/it/algoritmi/test/HTMLMatcher.java new file mode 100644 index 0000000..1480765 --- /dev/null +++ b/src/it/algoritmi/test/HTMLMatcher.java @@ -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 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) { + + } + +} diff --git a/src/it/algoritmi/test/Josephus.java b/src/it/algoritmi/test/Josephus.java new file mode 100644 index 0000000..afe3ac5 --- /dev/null +++ b/src/it/algoritmi/test/Josephus.java @@ -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 josephus(CircularQueue 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 CircularQueue buildQueue(E a[]) { + CircularQueue 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)); + } + +} diff --git a/src/it/algoritmi/test/PredatoryCreditCard.java b/src/it/algoritmi/test/PredatoryCreditCard.java new file mode 100644 index 0000000..0b3cc69 --- /dev/null +++ b/src/it/algoritmi/test/PredatoryCreditCard.java @@ -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; + } + +}