310 likes | 400 Vues
Soluzione MidTerm 2005. Giuseppe Attardi. Esercizio 1. Albero binario di string. class Tree { string key; string value; Tree left; Tree right; public Tree(string k, string v) { key = k; value = v; left = null; right = null; }. Albero binario generico.
E N D
Soluzione MidTerm 2005 Giuseppe Attardi
Albero binario di string class Tree { string key; string value; Tree left; Tree right; public Tree(string k, string v) { key = k; value = v; left = null; right = null; }
Albero binario generico class Tree<K:Comparable, V> { K key; V value; Tree<K, V> left; Tree<K, V> right; public Tree(K k, V v) { key = k; value = v; left = null; right = null; } }
class Dictionary class Dictionary : IDictionary { class Tree { ... } Tree root; public Dictionary() { root = null; } public bool insert(string k, string v); public string get(string key); IDictionaryIterator getIterator(); }
insert public bool insert(string k, string v) { if (k == null) return false; if (root == null) { root = new Tree(k, v); return true; } Tree curr = root; while (true) { int r = curr.key.CompareTo(k); if (r == 0) return false; if (r < 0) { if (curr.left == null) { curr.left = new Tree(k, v); return true; } else curr = curr.left; } else { ... } } }
get public string get(string k) { Tree curr = root; while (curr != null) { int r = curr.key.CompareTo(k); if (r == 0) return curr.value; if (r < 0) curr = curr.left; else curr = curr.right; } return null; }
getIterator IDictionaryIterator getIterator() { return new Iterator(root); }
Iterator class Iterator { stack<Tree> rest; Tree curr = null; Iterator(Tree root) { rest = new stack<Tree>; if (root != null) rest.push(root); }
MoveNext public bool MoveNext() { if (rest.empty) return false; curr = rest.pop; if (curr.right != null) rest.push(curr.right); if (curr.left != null) rest.push(curr.left); return true; }
Current public string Current() { return curr.value; }
sp fp Standard call sequence local m local m-1 ... local 1 old fp return addr arg1 arg2 ... argn
transfer routine saved regs transfer routine saved regs old fp old fp return addr return addr sp fp fp Coroutine stacks Coroutine A Coroutine B savedSP savedSP
Transfer Routine transfer(Coroutine c) { save registers on stack (no SP) this.savedSP = SP; SP = c.savedSP; restore registers (except SP) return; } Why?
class CoroutineA : Thread { public void Run() { wait(); // prepare ... corB.notify(); wait(); // transfer ... } }
public int main(string[] args) { CoroutineA corA = new CoroutineA(); coroutineA.start(); CoroutineB corB = new CoroutineB(); coroutineB.start(); corA.notify(); corA.join(); }
coroutine A { Stack<Tree> rest = new Stack<Tree>(); rest.push(tree1); while (true) { if (rest.empty) { end1 = true; transfer Main; return; } Tree curr = rest.pop; if (curr.left == null && curr.right == null) { leaf1 = curr.value; transfer Main; } else { if (curr.right != null) rest.push(curr.right); if (curr.left != null) rest.push(curr.left); } } }
coroutine C { Stack<Tree> rest = new Stack<Tree>(); rest.push(tree2); while (true) { if (rest.empty) { end2 = true; transfer Main; return; } Tree curr = rest.pop; if (curr.right != null) rest.push(curr.right); if (curr.left != null) rest.push(curr.left); leaf2 = curr.value; transfer Main; } }
Main end1 = end2 = false; while (true) { transfer A; transfer B; if (end1) return end2; if (end2) return end1; if (leaf1 != leaf2) return false; }
Passaggio per reference • In Java non esiste il passaggio per reference • Java does not provide call by reference • Java n’avait pas call by reference • Java hat nicht call by reference
Language Specific Variations • Pascal: Call by Value is the default, the keyword var denotes Call by Reference • Fortran: all parameters passed by Reference • Smalltalk, Lisp, Java: actual parameter is already a reference to the object, always passed by Value • C: always passed by Value
Ada Parameter Modes Three parameter passing modes • in • Passes information from the caller to the callee, can read but not write • Call by Value • out • Passes information from the callee to the caller, can write but not read • Call by Result (formal parameter is copied to actual parameter when subroutine exits) • inout - passes information both directions
C++ Parameter Modes • C passes pointers as addresses, must be explicitly dereferenced when used • C++ has notion of references • Parameter passing: void swap (int &a, int &b) • Variable References: int &j = i; • Function Returns: for objects that don’t support copy operations, i.e. file buffers
C# Parameter Modes • in • Passes information from the caller to the callee, can read but not write • Call by Value • out • Passes information from the callee to the caller, can write but not read • Call by Result (formal parameter is copied to actual parameter when subroutine exits) • in out – Call by Value-Result • ref • Call by Reference
Function Returns • Some languages restrict return types • Algol 60, Fortran: scalars only • Pascal, Modula: scalars or pointers only • Most imperative languages are flexible • Return statements specify a value and also cause the immediate termination of the subroutine
Totale esercizi • 105 righe di codice • Una settimana di tempo • 15 righe al giorno
MoveNext public bool MoveNext() { while (true) { if (curr == null) { if (rest.empty) return false; else { curr = rest.pop; return true; } curr = curr.left; if (curr.right != null) rest.push(curr.right); } }