Data Structures and Program Design in C++ phần 10 pps

77 372 0
Data Structures and Program Design in C++ phần 10 pps

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Section 13.5 • An Interactive Expression Evaluator 641 data membersin thePlot constructor. We would, for example, give them the values 19 and 79 to obtain a 20 × 80 text screen, or perhaps 780 and 1024 for a graphics screen. A position on the screen is specified by giving its integer row and column coordinates, from the ranges 0 ≤ row ≤ max_row and 0 ≤ col ≤ max_col. The method get_print_row uses the y-coordinate of a point of our graph to calculate a corresponding row of the screen. 517 int Plot ::get_print_row(double y_value) / * Post: Returns the row of the screen at which a point with y-coordinate y_value should be plotted, or returns −1 if the point would fall off the edge of the screen. * / { double interp_y = (( double) max_row) * (y_high − y_value)/(y_high − y_low) + 0.5; int answer = (int) interp_y; if (answer < 0 || answer > max_row) answer = −1; return answer; } The function returns a value of −1 to signify an input coordinate from outside the limits of the graph. 2. Points The Sortable_list in a Plot stores objects of the class Point. Since these objects repre- sent data points to be plotted, each Point must include two integer data members, row and col, that determine a location on the user’s screen. These data members completely determine the ordering of points. We can therefore simply view a Point as its own sorting key. In our program, this decision is implemented with the definition typedef Point Key; To ensure compatibility with ourearlier sorting methods, each Point must have overloaded comparison operators. The Point structure that we now define also includes two constructors. The constructors create either a Point with no useable data, or a Point storing the given row and col parameter values. 518 struct Point { int row; int col; Point( ); Point(int a, int b); bool operator == (const Point &p); bool operator !=(const Point &p); bool operator >= (const Point &p); bool operator <= (const Point &p); bool operator > (const Point &p); bool operator < (const Point &p); }; 642 Chapter 13 • Case Study: The Polish Notation Eventually, when we plot data to the screen, we will first have to plot those data points that belong at the top of the screen and then plot lower points. Similarly, if two data points occupy the same row of the screen, we will plot the leftward one first. Let us therefore design Point comparison operators so that points that must be plotted earlier are considered smaller than points that must be plotted later. In this way, we can simply sort the points, to arrange them in the order that they must be plotted to the user’s screen. For example, the Point :: operator < has the following implementation: 518 bool Point :: operator < (const Point &p) { return (row < p.row) || (col < p.col && row == p.row); } 3. Creating the Point Data The method Plot :: find_points produces the list of points to be plotted. It must repeatedly evaluate its postscript expression parameter and insert the resulting point into the Sortable_list Plot ::points. void Plot ::find_points(Expression &postfix) / * Post: The Expression postfix is evaluated for values of x that range from x_low to x_high in steps of x_increment. For each evaluation we add a Point to the Sortable_list points. Uses: Classes Token, Expression, Point, and List. * / { double x_val = x_low; double y_val; while (x_val <= x_high) { Token :: set_x(x_val); postfix.evaluate_postfix(y_val); postfix.rewind(); Point p(get_print_row(y_val), get_print_col(x_val)); points.insert(0, p); x_val += x_increment; } } 4. Drawing the Graph As soon as we have generated a Sortable_list of points, we are ready to draw a graph. We simply sort the points, in our implementation with a mergesort, and then traverse through the sorted list, placing a symbol at each indicated screen location. Our care in first sorting the list of points to be plotted ensures that they are already arranged from top to bottom and, at any given height, from left to right in the output graph. Section 13.5 • An Interactive Expression Evaluator 643 519 void Plot ::draw() / * Post: All screen locations represented in points have been marked with the char- acter  #  to produce a picture of the stored graph. Uses: Classes Point and Sortable_list and its method merge_sort. * / { points.merge_sort(); int at_row = 0, at_col = 0; // cursor coordinates on screen for (int i = 0; i < points.size(); i++) { Point q; points.retrieve(i, q); if (q.row < 0 || q.col < 0) continue; // off the scale of the graph if (q.row < at_row || (q.row == at_row && q.col < at_col)) continue; if (q.row > at_row) { // Move cursor down the screen. at_col = 0 ; while (q.row > at_row) { cout << endl; at_row++; } } if (q.col > at_col) // Advance cursor horizontally. while (q.col > at_col) { cout << " " ; at_col++; } cout << " #"; at_col++; } while (at_row++ <= max_row) cout << endl; } 13.5.8 A Graphics-Enhanced Plot Class Although there is no graphics support in the standard library of C++, such support is often provided by particular systems. For example, the Borland C++ compiler includes a library of graphics routines in the header file <graphics.h>. This library includes functions to initialize the screen for graphics, to detect the number of pixels on the screen, to mark individual pixels, and to restore the screen. We can incorporate these routines into our class Plot by changing the im- plementations of just four methods that have some interaction with the output screen. These methods are the constructor and the operations draw, find_points, and get_print_col. In a very minor modification to the constructor, we should remove the prede- fined limits on max_row and max_col since these are now to be calculated by library functions. A similarly minor modification is required in the method get_print_col to reflect the numbering of pixel rows upwards from the bottom of the screen rather than downwards from the top of the screen. 644 Chapter 13 • Case Study: The Polish Notation In the method find_points, we begin by using Borland graphics functions to initialize the screen and record its dimensions. The output data points are then listed just as in our earlier implementation. 520 void Plot ::find_points(Expression &postfix) / * Post: The Expression postfix is evaluated for values of x that range from x_low to x_high in steps of x_increment. For each evaluation we add a Point of the corresponding data point to the Sortable_list points. Uses: Classes Token, Expression, Point, and List and the library < graphics.h > . * / { int graphicdriver = DETECT, graphicmode; initgraph( &graphicdriver, &graphicmode, ""); // screen detection and graphresult( ) ; // initialization max_col = getmaxx( ) ; // with graphics.h library max_row = getmaxy( ) ; double x_val = x_low; double y_val; while (x_val <= x_high) { Token :: set_x(x_val); postfix.evaluate_postfix(y_val); postfix.rewind(); Point p(get_print_row(y_val), get_print_col(x_val)); points.insert(0, p); x_val += x_increment; } } Finally, the method draw has no need to sort the points, since pixels can be plotted in any order. The method simply lists points and marks corresponding pixels. 521 void Plot ::draw() / * Post: All pixels represented in points have been marked to produce a picture of the stored graph. Uses: Classes Point and Sortable_list and the library <graphics.h> * / { for (int i = 0; i < points.size(); i++) { Point q; points.retrieve(i, q); if (q.row < 0 || q.col < 0) continue; // off the scale of the graph if (q.row > max_row || q.col > max_col) continue; putpixel(q.col, q.row, 3); // graphics.h library function } cout "Enter a character to clear screen and continue: "<<flush; char wait_for; cin >> wait_for; restorecrtmode( ); // graphics.h library function } Chapter 13 • References for Further Study 645 At this point, we have surveyed the entire project. There remain several functions and methods that do not appear in the text, but these are all sufficiently straight- forward that they can be left as exercises. Exercises 13.5 E1. State precisely what changes in the program are needed to add the base 10 logarithm function log( ) as an additional unary operator. E2. Naïve users of this program might (if graphing a function involving money) write a dollar sign ‘$’ within the expression. What will the present program do if this happens? What changes are needed so that the program will ignore a ‘$’? E3. C++ programmers might accidentally type a semicolon ‘;’ at the end of the expression. What changes are needed so that a semicolon will be ignored at the end of the expression but will be an error elsewhere? E4. Explain what changes are needed to allow the program to accept either square brackets [ ] or curly brackets { } as well as round brackets ( ). The nesting must be done with the same kind of brackets; that is, an expression of the form ( [ ) ] is illegal, but forms like [ ( ) { } ] are permissible. Programming Project 13.5 P1. Provide the missing functions and methods and implement the graphing pro- gram on your computer. REFERENCES FOR FURTHER STUDY The Polish notation is so natural and useful that one might expect its dis- covery to be hundreds of years ago. It may be surprising to note that it is a discovery of this century: JAN ŁUKASIEWICZ, Elementy Logiki Matematyczny, Warsaw, 1929; English translation: Elements of Mathematical Logic, Pergamon Press, 1963. The development of iterative algorithms to form and evaluate Polish expressions (usually postfix form) can be found in several data structures books, as well as more advanced books on compiler theory. The iterative algorithm for translat- ing an expression from infix to postfix form appears to be due independently to E. W. D IJKSTRA and to C. L. HAMBLIN and appears in E. W. DIJKSTRA, “Making a translator for ALGOL 60,” Automatic Programming Infor- mation number 7 (May 1961); reprinted in Annual Revue of Automatic Programming 3 (1963), 347–356. C. L. H AMBLIN, “Translation to and from Polish notation,” Computer Journal 5 (1962), 210–213. The recursive algorithm for evaluationof postfix expressions is derived, albeit from a rather different point of view, and for binary operators only, in EDWARD M. REINGOLD, “A comment on the evaluation of Polish postfix expressions,” Computer Journal 24 (1981), 288. Mathematical Methods A T HE FIRST PART of this appendix supplies several mathematical results used in algorithm analysis. The final two sections of the appendix, Fibonacci numbers and Catalan numbers, are optional topics intended for the mathe- matically inclined reader. A.1 SUMS OF POWERS OF INTEGERS The following two formulas are useful in counting the steps executed by an algo- 523 rithm. Theorem A.1 1 + 2 +···+n = n(n + 1) 2 . 1 2 + 2 2 +···+n 2 = n(n + 1)(2n + 1) 6 . Proof The first identity has a simple and elegant proof. We let S equal the sum on the left side, write it down twice (once in each direction), and add vertically: 1 n n + 1 + + + 2 n − 1 n + 1 + + + 3 n − 2 n + 1 + + + ··· ··· ··· + + + n − 1 2 n + 1 + + + n 1 n + 1 = = = S S 2S There are n columns on the left; hence n(n +1)= 2S and the formula follows. end of proof 647 648 Appendix A • Mathematical Methods 1 2 3 4 5 n – 1 n n – 1 n – 2 n – 3 n – 4 n n +1 n 2 1 Figure A.1. Geometrical proof for sum of integers The first identity also has the proof without words shown in Figure A.1. 523 We shall use the method of mathematical induction to prove the second iden- proof by induction tity. This method requires that we start by establishing an initial case, called the induction base, which for our formula is the case n = 1. In this case the formula becomes 1 2 = 1(1 + 1)(2 + 1) 6 , which is true, so the induction base is established. Next, using the formula for the case n −1, we must establish it for case n. For case n − 1 we thus shall assume 1 2 + 2 2 +···+(n − 1) 2 = (n − 1)n  2(n − 1)+1  6 It follows that 1 2 + 2 2 +···+(n − 1) 2 +n 2 = (n − 1)n  2(n − 1)+1  6 + n 2 = 2n 3 − 3n 2 + n + 6n 2 6 = n(n + 1)(2n + 1) 6 , which is the desired result, and the proof by induction is complete. A convenient shorthand for a sum of the sort appearing in these identities is to use the capital Greek letter sigma  summation notation Section A.1 • Sums of Powers of Integers 649 in front of the typical summand, with the initial value of the index controlling the summation written below the sign, and the final value above. Thus the preceding identities can be written n  k=1 k = n(n + 1) 2 and n  k=1 k 2 = n(n + 1)(2n + 1) 6 . Two other formulas are also useful, particularly in working with trees. Theorem A.2 1 + 2 + 4 +···+2 m−1 = 2 m − 1. 1 × 1 + 2 × 2 + 3 × 4 +···+m × 2 m−1 = (m − 1)×2 m + 1. In summation notation these equations are 524 m−1  k=0 2 k = 2 m − 1. m  k=1 k × 2 k−1 = (m − 1)×2 m + 1. Proof The first formula will be proved in a more general form. Westart with the following identity, which, for any value of x = 1, can be verified simply by multiplying both sides by x − 1: x m − 1 x − 1 = 1 + x + x 2 +···+x m−1 for any x = 1. With x = 2 this expression becomes the first formula. To establish the second formula we take the same expression in the case of m +1 instead of m : x m+1 − 1 x − 1 = 1 + x + x 2 +···+x m for any x = 1, and differentiate with respect to x: (x − 1)(m + 1)x m − (x m+1 − 1) (x − 1) 2 = 1 + 2x + 3x 2 +···+mx m−1 for any x = 1. Setting x = 2 now gives the second formula. end of proofend of proof 650 Appendix A • Mathematical Methods Suppose that |x| < 1 in the preceding formulas. As m becomeslarge, it follows that x m becomes small, that is 524 lim m→∞ x m = 0. Taking the limit as m →∞in the preceding equations gives Theorem A.3 If |x| < 1 then ∞  k=0 x k = 1 1 − x . infinite series ∞  k=1 kx k−1 = 1 (1 − x) 2 . A.2 LOGARITHMS The primary reason for using logarithms is to turn multiplication and division into addition and subtraction, and exponentiation into multiplication. Before the advent of pocket calculators, logarithms were an indispensable tool for hand cal- culation: Witness the large tables of logarithms and the once ubiquitous slide rule. Even though we now have other methods for numerical calculation, thefundamen- tal properties of logarithms give them importance that extends far beyond their use as computational tools. The behavior of many phenomena, first of all, reflects an intrinsically logarith- mic structure; that is, by using logarithms we find important relationships that are not otherwise obvious. Measuring the loudness of sound, for example, is logarith- physical measurements mic: if one sound is 10 dB (decibels) louder than another, then the actual acoustic energy is 10 times as much. If the sound level in one room is 40 dB and it is 60 dB in another, then the human perception may be that the second room is half again as noisy as the first, but there is actually 100 times more sound energy in the second room. This phenomenon is why a single violin soloist can be heard above a full orchestra (when playing a different line), and yet the orchestra requires so many violins to maintain a proper balance of sound. Earthquake intensity is also measured logarithmically: An increase of 1 on the R ICHTER scale represents a ten-fold increase in energy released. large numbers Logarithms, secondly, provide a convenient way to handle very large numbers. The scientific notation, where a number is written as a small real number (often in the range from 1 to 10) times a power of 10, is really based on logarithms, since the power of 10 is essentially the logarithm of the number. Scientists who need to use very large numbers (like astronomers, nuclear physicists, and geologists) frequently speak of orders of magnitude and thereby concentrate on the logarithm of the number. A logarithmic graph, thirdly, is a very useful device for displaying the proper- ties of a function over a much broader range than a linear graph. With a logarithmic [...]... at random which to take now How much more quickly does he get home? generation of searching and sorting data P7 Write a program that creates files of integers in forms suitable for testing and comparing the various searching, sorting, and information retrieval programs A suitable approach to testing and comparing these programs is to use the program to create a small suite of files of varying size and. .. start with a random real number in [0, 1) , multiply it by high − low + 1 since that is the number of integers in the desired range, truncate the result to an integer, and add low to put the result into the desired range of integers Again, we implement this operation as a method of the class Random int Random :: random_integer(int low, int high) /* Post: A random integer between low and high (inclusive)... translation unit of a program We normally guarantee this by compiling the c file itself, and we never include a c file into another program file 676 Appendix C • Packages and Utility Functions information hiding In addition to aiding in the compilation and linking of large projects, the division of our packages into separate h and c files effectively enforces the principles of information hiding The h file... size and various kinds of ordering, and then use the CPU timing unit to compare various programs operating on the same data file The program should generate files of any size up to 15,000 positive integers, arranged in any of several ways These include: (a) Random order, allowing duplicate keys (b) Random order with no duplicates (c) Increasing order, with duplicates allowed (d) Increasing order with no... the function, and for large values a broad view of the function appears on the same graph For searching and sorting algorithms, we wish to compare methods both for small problems and large problems; hence log-log graphs are appropriate (See Figure A.4.) 108 107 Insertion sort 106 105 Merge sort 104 103 Comparisons of keys, average 102 50 10 5 1 1 2 3 5 10 20 50 100 200 500 100 0 2000 5000 10, 000 Figure... comparisons, insertion and merge sorts One observation is worth noting: Any power of x graphs as a straight line with a log-log scale To prove this, we start with an arbitrary power function y = x n and take logarithms on both sides, obtaining log y = n log x A log-log graph in x and y becomes a linear graph in u = log x and v = log y , and the equation becomes v = nu in terms of u and v , which indeed graphs... random numbers is integers We cannot, however, speak meaningfully about random integers since the number of integers is in nite but the number representable on a computer is finite Hence the probability that a truly random integer is one of those representable on a computer is 0 We instead consider only the integers in a range between two integers low and high, inclusive To calculate such an integer we start... as much grain to eat as you wish, you may plant as much as you wish, or you may buy or sell land for grain The price of land (in bushels of grain per acre) is determined randomly (between 6 and 13) Rats will consume a random percentage of your grain, and there are other events that may occur at random during the year These are: ¯ ¯ ¯ ¯ ¯ ¯ ¯ Plague Bumper Crop Population Explosion Flooding Crop Blight... (since paper covers rock), and rock beats scissors (since rock breaks scissors) Write a program to simulate playing this game with a person who types in S, P, or R at each turn 672 Appendix B • Random Numbers Hamurabi P5 In the game of Hamurabi you are the emperor of a small kingdom You begin with 100 people, 100 bushels of grain, and 100 acres of land You must make decisions to allocate these resources... system it is imitating The header files and provide random number generation routines in C++ systems These routines can be used in place of the ones developed here But system random-number generators are sometimes not very good, so it is worthwhile to see how better ones can be constructed In any case, we should regard the random-number generator and all the subprograms in this section . A.4.) 528 10 8 10 7 10 6 10 5 10 4 10 3 10 2 50 10 5 1 2 3 5 10 20 50 100 200 500 100 0 Insertion sort Merge sort Comparisons of keys, average 1 2000 10, 0005000 Figure A.4. Log-log graph, comparisons, insertion. both sides, obtaining log y = n log x. A log-log graph in x and y becomes a linear graph in u = log x and v = log y , and the equation becomes v = nu in terms of u and v , which indeed graphs as. Creating the Point Data The method Plot :: find_points produces the list of points to be plotted. It must repeatedly evaluate its postscript expression parameter and insert the resulting point into

Ngày đăng: 12/08/2014, 16:21

Từ khóa liên quan

Mục lục

  • 13 Case Study: The Polish Notation

    • 13.5 An Interactive Expression Evaluator

      • 13.5.8 A Graphics-Enhanced Plot Class

      • References for Further Study

      • A Mathematical Methods

        • A.1 Sums of Powers of Integers

        • A.2 Logarithms

        • A.2.1 Definition of Logarithms

        • A.2.2 Simple Properties

        • A.2.3 Choice of Base

        • A.2.4 Natural Logarithms

        • A.2.5 Notation

        • A.2.6 Change of Base

        • A.2.7 Logarithmic Graphs

        • A.2.8 Harmonic Numbers

        • A.3 Permutations, Combinations, Factorials

        • A.3.1 Permutations

        • A.3.2 Combinations

        • A.3.3 Factorials

        • A.4 Fibonacci Numbers

        • A.5 Catalan Numbers

        • A.5.1 The Main Result

        • A.5.2 The Proof by One-to-One Correspondences

Tài liệu cùng người dùng

Tài liệu liên quan