<<

Review

Lecture P5: Abstract Data Types :

of values and collection of operations on those values.

Example: int

■ Set of values: between -32,767 and 32,767 (minimum limits).

■ Operations: +, -, *, /, %, printf("%"), sqrt

■ How is an int represented? multiply ! 16 ? ! negative ? ! shouldn't care! add int print

. . .

2

Overview "Non ADT’s"

Is an ? Separate from specification. ! No: Representation in . ■ INTERFACE: specify the allowed operations. ! Client can directly manipulate the data type: a.re = 5.0; ■ IMPLEMENTATION: provide code for operations.

■ CLIENT: code that uses operations. client.

Abstract data type (ADT): #include "COMPLEX.h"

■ Data type whose representation is HIDDEN. int main(void) { ■ Don’t want client to directly manipulate data type. Complex a = COMPLEXinit(1.0, 2.0); ■ Operations ONLY permitted through interface. a.re = 5.0; legal C, but very bad design Principle of least privilege. COMPLEXshow(a); return 0; }

Violates "principle of least privilege."

3 6 ADT's for Stacks and Queues Stack Interface

Fundamental data type. Stack operations.

■ Set of operations (insert, delete) on generic data. ■ STACKinit(): initialize empty stack

■ STACKisempty(): return 1 if stack is empty; 0 otherwise

Stack ("last in first out" or LIFO). ■ STACKpush(int): insert new item

■ push: add info to the data ■ STACKpop(): delete and return item most recently added

■ pop: remove the info MOST recently added

■ initialize, test if empty STACK.h

Queue ("first in first out" or FIFO). void STACKinit(void); ■ put: add info to the int STACKisempty(void);

■ get: remove the info LEAST recently added void STACKpush(int);

■ initialize, test if empty int STACKpop(void);

Could use EITHER array or "" to implement EITHER stack or queue.

7 9

Stack Implementation with Arrays Stack Client: Balanced Parentheses

stackarray.c Push and pop at the end of array. par.c #include "STACK.h" big #include Demo: #define MAX_SIZE 1000 enough? #include "STACK.h" static int s[MAX_SIZE]; Drawback: static int N; int main(void) { int c, balanced = 1; ! Have to reserve void STACKinit(void) { STACKinit(); space for max size. N = 0; } . . . /* MAIN CODE HERE */

int STACKisempty(void) { if (balanced) return N == 0; printf("Balanced.\n"); } else printf("NOT Balanced.\n"); void STACKpush(int item) { s[N++] = item; return 0; } } int STACKpop(void) { Good: ( ( ( ) ( ) ) ) return s[--N]; Bad: ( ( ) ) ) ( ( )

} 11 12 Stack Client: Balanced Parentheses Stack Client: Balanced Parentheses

par.c (cont) Check if your C program has unbalanced parentheses.

stop loop if unbalanced Read from stdin Unix % gcc par.c stackarray.c while (balanced && (c = getchar()) != EOF) { % a.out < myprog.c if ( c == '(' ) balanced STACKpush(c); push left parentheses else if ( c == ')' ) { % a.out < someprogram.c if (STACKisempty()) check for matching unbalanced balanced = 0; left parenthesis else How could valid C program have STACKpop(); unbalanced parentheses? } } if (!STACKisempty()) balanced if empty stack balanced = 0; when no more input Exercise: extend to square and curly braces.

■ Good: { ( [ ( [ ] ) ( ) ] ) }

Good: ( ( ( ) ( ) ) ) ■ Bad: ( ( [ ) ] ) Bad: ( ( ) ) ) ( ( )

13 14

Stack Client: Postfix Evaluation Stack Client: Postfix Evaluation

Practical example of use of stack abstraction. Practical example of use of stack abstraction.

Put operator after operands in expression. Put operator after operands in expression.

■ Use stack to evaluate. ■ Use stack to evaluate. – operand: push it onto stack. – operand: push it onto stack. – operator: pop operands, push result. – operator: pop operands, push result.

■ Systematic way to save intermediate results. ■ Systematic way to save intermediate results.

Example 1. Example 2a: convert 27531 from octal to decimal.

■ 1 2 3 4 5 * + 6 * * 7 8 9 + + * + ■ 2 8 8 8 8 * * * * 7 8 8 8 * * * 5 8 8 * * 3 8 * 1 + + + +

Example 2b: convert 27531 from octal to decimal.

■ 2 8 * 7 + 8 * 5 + 8 * 3 + 8 * 1 +

■ Stack never has more than two numbers on it!

■ Horner’s method (see lecture A3).

15 17 Stack Client: Postfix Evaluation Stack Client: Postfix Evaluation

posfix.c Program has some flaws. Unix #include ! #include 2 + 5 % gcc postfix.c stackarray.c #include "STACK.h" ! 16 12 + % a.out 2 4 + int main(void) { top of stack = 6 int c; STACKinit(); % a.out while ((c = getchar()) != EOF) { 1 2 3 4 5 * + 6 * * 7 8 9 + + * if ('+' == c) top of stack = 6624 pop 2 elements STACKpush(STACKpop() + STACKpop()); and push sum else if ('*' == c) % a.out STACKpush(STACKpop() * STACKpop()); 5 9 8 + 4 6 * * 7 + * else if (isdigit(c)) convert char to top of stack = 2075 STACKpush(c - '0'); and push } % a.out 2 8 * 7 + 8 * 5 + 8 * 3 + 8 * 1 + printf("top of stack = %d\n", STACKpop()); top of stack = 12121 return 0; }

18 19

Stack Client: Infix to Postfix ADT Review

Unix infix2postfix.c Client can access data type ONLY through interface. % gcc infix2postfix.c ... #include ■ Example: STACK. % a.out #include (2 + ((3 + 4) * (5 * 6))) #include "STACK.h" Representation is HIDDEN in the implementation. 2 3 4 + 5 6 * * + int main(void) { ■ Provides security. int c; Infix to postfix : STACKinit(); Convenient way to organize large problems. while ((c = getchar()) != EOF) { ■ Left paren: ignore. if (c == ')') ■ Decompose into smaller problems. ■ Right paren: pop and print. printf("%c ", STACKpop()); ■ Substitute alternate solutions (time / space tradeoffs). ■ Operator: push. else if (c == '+' || c == '*') ■ Separation compilation.

■ STACKpush(c); Digit: print. ■ Build libraries. else if (isdigit(c)) ■ Different clients can share the same ADT. printf("%c ", c); } printf("\n"); Powerful mechanism for building layers of abstraction.

return 0; ■ Client works at a higher level of abstraction. }

20 21 First Class ADT First Class ADT Client: Infix infix.c So far, only 1 stack per program. STACKinit(); #include . . . #include First Class ADT: STACKpush(a); #include "STACK.h" . . . int main(void) { ■ ADT that is just like a built-in C type. Stack s1 = STACKinit(); s1 = stack of operatorsUnix b = STACKpop(); Stack s2 = STACKinit(); ■ Can declare multiple instances of s2 =% stack gcc ofinfix.c integers ... int c, op; them. % a.out while ((c = getchar()) != EOF) { (2 + ((3 + 4) * (5 * 6))) ■ Pass specific instances of them to if (c == ')') { interface as inputs. Stack s1, s2; op = STACKpop(s1); 212 if (op == '+') ■ Details omitted in COS 126. STACKpush(s2, STACKpop(s2) + STACKpop(s2)); (See Sedgewick 4.8 or COS 226.) s1 = STACKinit(); else if (op == '*') s2 = STACKinit(); STACKpush(s2, STACKpop(s2) * STACKpop(s2)); . . . } else if (c == '+' || c == '*') STACKpush(s1, a); STACKpush(s1, c); STACKpush(s2, b); else if (isdigit(c)) . . . STACKpush(s2, c - '0'); c = STACKpop(s2); } printf("Result = %d\n", STACKpop(s2)); return 0; } 22 23

PostScript: Abstract Stack Machine PostScript: Abstract Stack Machine

Language of most printers nowadays. Some commands:

■ Postfix language. ■ Coordinate system: rotate, translate, scale, ...

■ Abstract stack machine. ■ Turtle commands: moveto, lineto, rmoveto, rlineto, ...

■ Graphics commands: stroke, fill, ...

Ex: convert 27531 from octal to decimal. ■ Arithmetic: add, sub, mul, div, ...

■ 2 8 mul 7 add 8 mul 5 add 8 mul 3 add 8 mul 1 add ■ Stack commands: copy, exch, dup, currentpoint, ...

■ Control constructs: if, ifelse, while, for, ...

Stack uses: ■ Define functions: /XX { ... } def

■ Operands for operators.

■ Arguments for functions. Everyone’s first PostScript program (draw a box).

■ Return value(s) for functions. %! 50 50 translate 0 0 moveto 0 512 rlineto 512 0 rlineto 0 -512 rlineto -512 0 rlineto stroke showpage

24 25 Overview

Data type. Lecture P5: Supplemental Notes ■ Set of values and collection of operations on those values.

ABSTRACT data type (ADT).

■ Data type whose representation is completely HIDDEN from client.

Stacks and queues.

■ Fundamental ADT's. – calculators – printers and PostScript language – compiler uses to implement functions (see next lecture)

26

"Non ADT’s" Queue Interface

Is Complex data type an ABSTRACT data type? Queue operations.

■ NO: Representation in interface. ■ QUEUEinit(): initialize empty queue.

■ QUEUEisempty(): return 1 if queue is empty; 0 otherwise Are C built-in types like int ADT’s? QUEUEput(int): insert new item at end of list.

■ ALMOST: we generally ignore representation. ■ QUEUEget(): return and remove item at beginning of list.

■ NO: set of values depends on representation. – might use (x & 0) to test if even QUEUE.h – works only if they’re stored as "two’s complement integers"

■ CONSEQUENCE: strive to write programs that properly void QUEUEinit(void); independent of representation. int QUEUEisempty(void); – (x % 2 == 0) is more portable way to test if even void QUEUEput(int); – also, use for machine-specific ranges of int, long int QUEUEget(void);

28 29 Queue Implementation Queue Client: Josephus Problem

queuearray.c queuearray.c Flavius Josephus. (first century)

■ Band of 41 Jewish rebels trapped in cave by Romans. #include "QUEUE.h" int QUEUEisempty(void) { #define MAX_SIZE 1000 return front % N == back; ■ Preferring suicide to capture, rebels formed a circled and killed } every 3rd remaining person until no one was left.

static int q[MAX_SIZE]; void QUEUEput(int item) { ■ Where should you stand to be among last two survivors? static front, back; q[back++] = item; ! 31 and and 16 back = back % N; void QUEUEinit(void) { } front = N; int QUEUEget(void) { back = 0; front = front % N; } return q[front++]; } front

Variable q[0] q[1] q[2] q[3] q[4] q[5] MAX_SIZE = 6 Value M D T E X A

back 30 31

Queue Client: Josephus Problem

josephus.c

N = 8, M = 3 #include #include "QUEUE.h" #define N 41 1 2 3 4 5 6 7 8 #define M 3 2 3 4 5 6 7 8 1 int main(void) { 3 4 5 6 7 8 1 2 int i; QUEUEinit(); for (i = 1; i <= N; i++) 4 5 6 7 8 1 2 QUEUEput(i); 5 6 7 8 1 2 4 while (!QUEUEisempty()) { for (i = 0; i < M - 1; i++) 6 7 8 1 2 4 5 QUEUEput(QUEUEget()); printf("%d\n", QUEUEget()); 7 8 1 2 4 5 } . . . return 0; }

32