1. Trang chủ
  2. » Luận Văn - Báo Cáo

Problem Set 6 – Solutions Part 1: Pointers to pointers. Multidimensional arrays. Stacks and queues.

8 437 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Problem Set 6 – Solutions Part 1: Pointers to pointers. Multidimensional arrays. Stacks and queues.
Trường học Massachusetts Institute of Technology
Chuyên ngành Electrical Engineering and Computer Science
Thể loại bài tập
Năm xuất bản 2010
Thành phố Cambridge
Định dạng
Số trang 8
Dung lượng 264,15 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

In this problem, we will implement a simple “four-function” calculator using stacks and queues. This calculator takes as input a space-delimited infix expression

Trang 1

6.087: Practical Programming in C

IAP 2010 Problem Set 6 – Solutions Part 1: Pointers to pointers Multidimensional arrays Stacks and queues

Out: Wednesday, January 20, 2010 Due: Friday, January 22, 2010 This is Part 1 of a two-part assignment Part 2 will be released Thursday

Problem 6.1

In this problem, we will implement a simple “four-function” calculator using stacks and queues This calculator takes as input a space-delimited infix expression (e.g 3 + 4 * 7), which you will convert to postfix notation and evaluate There are four (binary) operators your calculator must handle: addition (+), subtraction (-), multiplication (*), and division (/) In addition, your calculator must handle the unary negation operator (also -) The usual order of operations is in effect:

• the unary negation operator - has higher precedence than the binary operators, and is eval­ uated right-to-left (right-associative)

• * and / have higher precedence than + and ­

• all binary operators are evaluated left-to-right (left-associative)

To start, we will not consider parentheses in our expressions The code is started for you in prob1.c, which is available for download from Stellar Read over the file, paying special attention to the data structures used for tokens, the stack, and queue, as well as the functions you will complete (a) We have provided code to translate the string to a queue of tokens, arranged in infix (natural) order You must:

– fill in the infix to postfix() function to construct a queue of tokens arranged in postfix order (the infix queue should be empty when you’re done)

– complete the evaluate postfix() function to evaluate the expression stored in the postfix queue and return the answer

You may assume the input is a valid infix expression, but it is good practice to make your code robust by handling possible errors (e.g not enough tokens) Turn in a printout of your code, along with a printout showing the output from your program for a few test cases (infix expressions of your choosing) to demonstrate it works properly

Trang 2

Answer: Here’s one possible implementation: (only functions infix to postfix() and

evaluate postfix() shown)

/∗ c r e a t e s a queue o f t o k e n s i n p o s t f i x o r d e r from a queue o f t o k e n s i n i n f i x o r d e r ∗/ /∗ p o s t c o n d i t i o n : r e t u r n e d queue c o n t a i n s a l l t h e t o k e n s , and p q u e u e i n f i x s h o u l d be empty ∗/

s t r u c t t o k e n q u e u e i n f i x t o p o s t f i x ( s t r u c t t o k e n q u e u e ∗ p q u e u e i n f i x ) {

s t r u c t

q u e u e p o s t f i x f r o n t = q u e u e p o s t f i x back = NULL ;

f o r

switch

case

/∗ o p e r a n d s added d i r e c t l y t o p o s t f i x queue ∗/

break

case

while

o p p r e c e d e n c e s [ ptoken−>v a l u e o p c o d e ] &&

o p a s s o c i a t i v i t y [ o p p r e c e d e n c e s [ ptoken−>v a l u e o p c o d e ] ] == LEFT ) ) )

break

d e f a u l t :

break

}

}

while ( s t a c k t o p )

return

}

/

double e v a l u a t e p o s t f i x ( s t r u c t

double

double o p e r a n d s [ 2 ] ; /

union

i n t

while

switch

case

/∗ o p e r a n d s a l w a y s pushed t o s t a c k ∗/

break

case

2

Trang 3

/∗ pop o p e r a n d s from s t a c k ∗/

f o r ( i = 0 ; i < o p o p e r a n d s [ ptoken−>v a l u e o p c o d e ] ; i ++) {

i f

f r e e ( p v a l u e ) ; / }

goto }

/

switch ( ptoken−>v a l u e o p c o d e ) {

case

break

case

break

case

break

case

break

case

}

d e f a u l t

f r e e ( p t o k e n ) ; /

break

}

}

/∗ r e t u r n v a l u e i s on t op o f s t a c k ( s h o u l d be l a s t v a l u e on s t a c k ) ∗/

i f ( s t a c k v a l u e s )

a n s = s t a c k v a l u e s −>v a l u e operand ;

c l e a n u p :

/∗ f r e e any r e m a i n i n g t o k e n s ∗/

while

while

return

f p u t s ( " Error e val uat ing the e xpr ess ion \ n "

goto

}

(b) Now, an infix calculator really is not complete if parentheses are not allowed So, in this part, update the function infix to postfix() to handle parentheses as we discussed in class Note: your postfix queue should contain no parentheses tokens Turn in a printout of your code, along with a printout showing the output from your program for a few test cases utilizing parentheses

3

Trang 4

Answer: Here’s an implementation: (only function infix to postfix() shown)

/∗ c r e a t e s a queue o f t o k e n s i n p o s t f i x o r d e r from a queue o f t o k e n s i n i n f i x o r d e r ∗/ /∗ p o s t c o n d i t i o n : r e t u r n e d queue c o n t a i n s a l l t h e t o k e n s , and p q u e u e i n f i x s h o u l d be empty ∗/

s t r u c t t o k e n q u e u e i n f i x t o p o s t f i x ( s t r u c t t o k e n q u e u e ∗ p q u e u e i n f i x ) {

/∗ TODO: c o n s t r u c t p o s t f i x −o r d e r e d queue from i n f i x −o r d e r e d queue ;

a l l t o k e n s from i n f i x queue s h o u l d be added t o p o s t f i x queue o r f r e e d ∗/

s t r u c t

q u e u e p o s t f i x f r o n t = q u e u e p o s t f i x back = NULL ;

f o r ( p t o k e n = dequeue ( p q u e u e i n f i x ) ; p t o k e n ; p t o k e n = dequeue ( p q u e u e i n f i x ) ) {

switch ( ptoken−>t y p e ) {

case OPERAND:

/∗ o p e r a n d s added d i r e c t l y t o p o s t f i x queue ∗/

break

case

while

o p p r e c e d e n c e s [ ptoken−>v a l u e o p c o d e ] &&

o p a s s o c i a t i v i t y [ o p p r e c e d e n c e s [ ptoken−>v a l u e o p c o d e ] ] == LEFT ) ) )

break

case LPARENS :

/∗ pushed t o o p e r a t o r s t a c k ∗/

break

case

/∗ pop o p e r a t o r s o f f s t a c k u n t i l l e f t p a r e n t h e s e s r e a c h e d ∗/

f r e e ( p t o k e n ) ; /∗ p a r e n t h e s e s not i n c l u d e d i n p o s t f i x queue ∗/

while ( ( p t o k e n = pop(& s t a c k t o p ) ) ) {

i f break }

enqueue (& q u e u e p o s t f i x , p t o k e n ) ;

}

while ( s t a c k t o p )

return

}

Problem 6.2

A useful data structure for storing lots of strings is the “trie.” This tree structure has the special

property that a node’s key is a prefix of the keys of its children For instance, if we associate a node

with the string “a,” that node may have a child node with the key “an,” which in turn may have a

child node “any.” When many strings share a common prefix, this structure is a very inexpensive

Trang 5

way to store them Another consequence of this storage method is that the trie supports very fast searching – the complexity of finding a string with m characters is O(m)

(root)

pointer array of childre �

"a" "c"

"an" "ca"

"and" "ant" "cat"

Figure 6.2-1: Trie structure (translations not shown) For each node, its key (e.g “and”) is not explicitly stored in the node; instead, the key is defined by the node’s position in the tree: the key

of its parent node + its index in that parent’s pointer array of children

In this problem, you will utilize a trie structure and to implement a simple one-way English-to-French dictionary The trie structure, shown in Figure 6.2-1, consists of nodes, each of which contains a string for storing translations for the word specified at that node and an array of pointers

to child nodes Each node, by virtue of its position in the trie, is associated with a string; in the dictionary context, this string is the word (or part of a word) in the dictionary The dictionary may contain multiple translations for the same word; in this case, words should be separated by commas For example: the word like, which has two meanings, could translate as comme, a preposition, or

as aimer, a verb Thus, the translation string should be “comme,aimer.” To get you started, we’ve provided code in prob2.c, which can be downloaded from Stellar You will need to:

• fill in the helper functions new node(), delete node()

• complete the function add word(), which adds a word to the trie

• complete the function lookup word(), which searches the trie for a word and returns its translation(s)

Once your code is working, run a few test cases Hand in a copy of your code, and a printout of your program running in gdb, with a few example translations to demonstrate functionality

Trang 6

Answer: one possible implementation of the four functions is shown below:

/∗ a l l o c a t e new node on t h e heap

o u t p u t : p o i n t e r t o new node ( must be f r e e d ) ∗/

s t r u c t s t r i e n o d e ∗ new node ( void ) {

s t r u c t s t r i e n o d e ∗ pnode =

( s t r u c t

s i z e o f ( s t r u c t

i n t

f o r

pnode

return

}

/∗ d e l e t e node and a l l i t s c h i l d r e n

i n p u t : p o i n t e r t o node t o d e l e t e

p o s t c o n d i t i o n : node and c h i l d r e n a r e f r e e d ∗/

void d e l e t e n o d e ( s t r u c t s t r i e n o d e ∗ pnode ) {

∗/

i n t i ;

i f

f o r

i f

}

/∗ add word t o t r i e , w i t h t r a n s l a t i o n

i n p u t : word and t r a n s l a t i o n

o u t p u t : non−z e r o i f new node added , z e r o o t h e r w i s e

p o s t c o n d i t i o n : word e x i s t s i n t r i e ∗/

i n t add word ( const char ∗ word , char ∗ t r a n s l a t i o n ) {

∗/

s t r u c t s t r i e n o d e ∗ pnode = p r o o t ;

i n t

unsigned char

f o r

i f

}

i f ( pnode−>t r a n s l a t i o n ) {

/∗ c o n c a t e n a t e s t r i n g s ∗/

6

Trang 7

char ∗ o l d t r a n s l a t i o n = pnode−>t r a n s l a t i o n ;

i n t o l d l e n = s t r l e n ( o l d t r a n s l a t i o n ) ,

newlen = s t r l e n ( t r a n s l a t i o n ) ;

pnode−>t r a n s l a t i o n = m a l l o c ( o l d l e n + newlen + 2 ) ;

s t r c p y ( pnode−>t r a n s l a t i o n , o l d t r a n s l a t i o n ) ;

s t r c p y ( pnode−>t r a n s l a t i o n+o l d l e n , " ," ) ;

s t r c p y ( pnode−>t r a n s l a t i o n+o l d l e n +1 , t r a n s l a t i o n ) ;

f r e e ( o l d t r a n s l a t i o n ) ;

}

pnode

return

}

/∗ s e a r c h t r i e s t r u c t u r e f o r word and r e t u r n t r a n s l a t i o n s

i n p u t : word t o s e a r c h

o u t p u t : t r a n s l a t i o n , o r NULL i f n o t found ∗/

char ∗ l o o k u p w o r d ( const char ∗ word ) {

s t r u c t s t r i e n o d e ∗ pnode = p r o o t ;

i n t

unsigned char

f o r

i f

return

}

return pnode−>t r a n s l a t i o n ;

}

Trang 8

MIT OpenCourseWare

http://ocw.mit.edu

6.087 Practical Programming in C

January (IAP) 2010

For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms

Ngày đăng: 25/04/2013, 08:07

TỪ KHÓA LIÊN QUAN

w