Lecture P5: Abstract Data Types Data Type
Total Page:16
File Type:pdf, Size:1020Kb
Review Lecture P5: Abstract Data Types Data type: Set of values and collection of operations on those values. Example: int Set of values: between -32,767 and 32,767 (minimum limits). Operations: +, -, *, /, %, printf("%d"), sqrt How is an int represented? multiply 16 bits? negative integers? shouldn't care! add int print ... 2 Overview "Non ADT’s" Is Rational data type an ABSTRACT data type? Separate implementation from specification. No: Representation in interface. INTERFACE: specify the allowed operations. Client can directly manipulate the data type: a.num = 5; IMPLEMENTATION: provide code for operations. CLIENT: code that uses operations. RAT.h client.c Abstract data type (ADT): typedef struct { #include "RAT.h" int num; Data type whose representation is HIDDEN. int den; int main(void) { Don’t want client to directly manipulate data type. } Rational; Rational a; Operations ONLY permitted through interface. legal C, but very bad a.num = 5; Rational RATadd(Rationalsoftware a, Rational design b); a.den = 8; Rational RATmul(Rational a, Rational b); RATshow(a); Principle of least privilege. Rational RATshow(Rational a); return 0; Rational RATinit(int x, int y); } 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 structure 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 data structure int STACKisempty(void); get: remove the info LEAST recently added void STACKpush(int item); initialize, test if empty int STACKpop(void); Could use EITHER array or "linked list" 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" #include <stdio.h> Demo: #define MAX_SIZE 1000 #include "STACK.h" static int s[MAX_SIZE]; static int N; int main(void) { int c, balanced = 1; void STACKinit(void) { STACKinit(); 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; N++; s[N++] = item; return 0; } } int STACKpop(void) { N--; Good: ((()())) return s[N]; return s[--N]; Bad: (()))(() } 10 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 character 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 handle 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. 12345*+6**789++*+ 28888****7888***588**38*1++++ Example 2b: convert 27531 from octal to decimal. 28*7+8*5+8*3+8*1+ Stack never has more than two numbers on it! Horner’s method (see lecture P2). 15 17 Stack Client: Postfix Evaluation Stack Client: Postfix Evaluation postfix.c Program has some flaws. Unix #include <stdio.h> #include <ctype.h> 2+5 % gcc postfix.c stackarray.c #include "STACK.h" 16 12 + % a.out 24+ int main(void) { top of stack = 6 int c; STACKinit(); % a.out while ((c = getchar()) != EOF) { 12345*+6**789++* if ('+' == c) top of stack = 6624 pop 2 elements STACKpush(STACKpop() + STACKpop()); and push sum else if ('*' == c) % a.out STACKpush(STACKpop() * STACKpop()); 598+46**7+* else if (isdigit(c)) convert char to top of stack = 2075 STACKpush(c - '0'); integer and push } % a.out 28*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 <stdio.h> Example: STACK. % a.out #include <ctype.h> (2 + ((3 + 4) * (5 * 6))) #include "STACK.h" Representation is HIDDEN in the implementation. 234+56**+ int main(void) { Provides security. int c; Infix to postfix algorithm: STACKinit(); Convenient way to organize large problems. while ((c = getchar()) != EOF) { Left paren: ignore. Decompose into smaller problems. if (c == ')') Right paren: pop and print. Substitute alternate solutions (time / space tradeoffs). printf("%c ", STACKpop()); Separation compilation. Operator: push. else if (c == '+' || c == '*') Build libraries. Digit: print. STACKpush(c); else if (isdigit(c)) Different clients can share the same ADT. printf("%c ", c); } Powerful mechanism for building layers of abstraction. printf("\n"); Client works at a higher level of abstraction. return 0; } 20 21 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, ... 28mul7add8mul5add8mul3add8mul1add 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 22 23 Summary Data type. Set of values and collection of operations on those values. Lecture P5: Supplemental Notes 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) 24 First Class ADT First Class ADT Client: Infix infix.c So far, only 1 stack per program. STACKinit(); #include <stdio.h> ... #include <ctype.h> 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 of infix.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; } 26 27 "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 – works only if they’re stored as "two’s complement integers" QUEUE.h CONSEQUENCE: strive to write programs that function properly independent of representation. void QUEUEinit(void); – (x % 2 == 0) is more portable way to test if even int QUEUEisempty(void); – also, use <limits.h> for machine-specific ranges of int, long void QUEUEput(int item); 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" void QUEUEput(int item) { #define MAX_SIZE 1000 q[back++] = item; Preferring suicide to capture, rebels formed a circled and killed back %= MAX_SIZE; every 3rd remaining person until no one was left. static int q[MAX_SIZE]; } Where should you stand to be among last two survivors? static int front, back; 31 and and 16 int QUEUEget(void) { void QUEUEinit(void) { int r = q[front++]; front = back = 0; front %= MAX_SIZE; } return r; } int QUEUEisempty(void) { return front == back; } 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 <stdio.h> #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 } .