1 / 54

Controlling statement execution

Controlling statement execution. CS101 2012.1. Statement block. A block looks like {statement;statement;…statement;} 0 or 1 statement allowed for uniformity Walk down the list executing one statement after another Effect of each statement on memory completes before next executed

kemal
Download Presentation

Controlling statement execution

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Controlling statement execution CS101 2012.1

  2. Statement block • A block looks like{statement;statement;…statement;} • 0 or 1 statement allowed for uniformity • Walk down the list executing one statement after another • Effect of each statement onmemory completesbefore next executed • Note on scope: Outside {…} cannot use variables declared inside float x = 5, y = 11; float temporary = x; x = y; y = temporary; CS101 2012.1

  3. If-then-else int a, b; cin >> a; if (a >= 0) { b = a; } else { b = -a; } • Store in variable b the absolute value of variable a • Store in variable c the smaller of the values of variables a and b • Else part is optional • Cascades/nests allowed • Statement blocks also optional but best used int a, b, c; cin >> a >> b; if (a < b) { c = a; } else { c = b; } CS101 2012.1

  4. Example: withdrawing money from bank cin >> deduct; if (deduct > balance) { cout << “Account overdrawn\n”; } else { cout << “Successfully withdrawing ” << deduct << endl; balance -= deduct; // emit paper money } CS101 2012.1

  5. Curly brackets • You can also write then or else parts without curly brackets, but this could be dangerous • Best to always use curly brackets even if not needed int m = 5; int n = 10; if (m >= n) ++m; ++n; cout << "m=" << m << "n=" << n << endl; Increment of n happens outside the if-then action, which only increments m CS101 2012.1

  6. Conditional expression • Format: cond ? ifExpr : elseExpr • Earlier examples rewritten • b = (a > 0)? a : -a; • c = (a < b)? a : b; • If in doubt, use (parens) to make sure expression tree is correct • Nesting quickly gives unreadable code:(a > 0)? a : ((-a < b)? 100+c : c-100) CS101 2012.1

  7. Switch statement • if (cond1) {…} else if (cond2) {…} else if (cond3) {…} can get tiring • Common use is to choose between different statements depending on the value of a variable Can be char, int, long int switch (dayOfWeek) { case 0: cout << “Sunday”; break; case 6: cout << “Saturday”; break; default: cout << “Weekday”; } If no break here, control will “fall through” to the next case If none of the listed cases match dayOfWeek CS101 2012.1

  8. Switch mystery int val = 5; switch (val) { case 5: cout << "five\n"; // suppose we forget this break; case 4: cout << "four\n"; break; default: cout << "default\n"; } This statement will be executed even though val is not 4 CS101 2012.1

  9. Switch example switch (ch) { case 'a': case 'A': case 'e': case 'E': case 'i': case 'I': case 'o': case 'O': case 'u': case 'U': cout << ch << " is a vowel" << endl; break; default: cout << ch << " is not a vowel" << endl; } Can use fall-through as a feature to combine many cases CS101 2012.1

  10. Another switch example cout << "Enter simple expression: "; int left; int right; char operator; cin >> left >> operator >> right; cout << left << " " << operator << " " << right << " = "; switch (operator) { case '+' : cout << left + right << endl; break; case '-' : cout << left - right << endl; break; case '*' : cout << left * right << endl; break; case '/' : cout << left / right << endl; break; default: cout << "Illegal operation" << endl; } CS101 2012.1

  11. The infinite loop while (true) { cout << “I will lecture clearly and slowly\n”; cout << “I will remain quiet in class\n”; } Insanity: doing the same thing over and over again and expecting different results. Albert Einstein CS101 2012.1

  12. Are inputs in increasing order? • Keep reading input number for ever, and check if it is greater than the previous number read #include <iostream> #include <limits> using namespace std; double prev = numeric_limits<double>::min(); while (true) { double cur; cin >> cur; if (cur <= prev) { cout << “Not in increasing order\n”; } prev = cur; } How do we get out of the infinite loop? CS101 2012.1

  13. Printing an integer in binary • Surprisingly, standard C++ does not offer a library function • But simple enough • For brevity consider printing a byte num • Take bit pattern mask = 10000000 • Bitwise and: num & mask • If result is nonzero, print ‘1’ else ‘0’ • Shift mask right to 01000000, then 00100000, 00010000, etc. CS101 2012.1

  14. Shortcut • Instead of shifting mask right, shift num left • Use fixed mask of 10000000 • Say num = 01101011 = 107 (decimal) • 10000000 & 01101011  print ‘0’ • Shift num left to 11010110 • 10000000 & 11010110  print ‘1’ • Shift num left to 10101100 • 10000000 & 10101100  print ‘1’ • And so on CS101 2012.1

  15. Raising a number to an integer power • Given a double base and a non-negative integer power int pow • Find basepow • A simple and a more efficient version double ans = 1; int todo = pow; while (todo > 0) { ans = ans * base; // or ans *= base; --todo; } CS101 2012.1

  16. Loop invariant • Initially, ans=1 and todo=pow • After each iteration, ans * basetodo = basepow • ans multiplied by base, todo reduced by 1 • Finally, todo=0, therefore ans = basepow • Number of multiplications: pow double ans = 1; int todo = pow; while (todo > 0) { ans = ans * base; // or ans *= base; --todo; } CS101 2012.1

  17. The squaring method • Suppose pow = 32 • Instead of base*base*…*base(31 multiplications), run the following double b2 = base * base; double b4 = b2 * b2; double b8 = b4 * b4; double b16 = b8 * b8; double ans = b16 * b16; // only 5 multiplications CS101 2012.1

  18. General powers • Suppose pow = 29 is a byte • Express as 1 + 4 + 8 + 16 • Answer is base * b4 * b8 * b16 • Let bx take values 0 through 7 • Keep squaring base as before • If the bxth bit of pow is 1, include the power of base in the product, else not • Already know how to get bit by (val & 1) bx CS101 2012.1

  19. Faster code unsigned int todo = pow; double ans = 1, term = base; while (todo > 0) { if (todo & 1 == 1) { ans *= term; } term = (term * term); // squaring todo = (todo >> 1); } What if pow is a real number? Exercise: Work out the loop invariant CS101 2012.1

  20. Factorial long long int double fac = 1, n; cin >> n; while (n > 0.5) { fac *= (n--); } cout << fac << endl; • Can easily overflow even for moderate n • Even if we use double CS101 2012.1

  21. Iteration: Approximating the logarithm • How many times must we divide a number x by 10 until the result goes below 1? • while (condition) statementOrBlock Another shorthand: x /= 10; float x; cin >> x; int numDivs = 0; while (x > 1) { x = x / 10; numDivs = numDivs + 1; } cout << numDivs; Prolog Loopbody More shorthands: numDivs += 1; or ++numDivs; Epilog CS101 2012.1

  22. Quick review • Why do we care about how data types are represented in RAM? • To understand the limits of what can be represented within hardware limitations • Thus write more reliable and robust code • Can give insights for better algorithms • E.g., bit shifts  squaring trick  fast power algorithm CS101 2012.1

  23. Perimeter of regular polygons • Polygons inscribed in circle of radius ½ • First, a polygon with sides x • Next double the number ofsides, each side is y • Let’s start with x = ½ (six sides) CS101 2012.1

  24. Code double sides = 6, x = .5; while (true) { cout << (sides * x) << endl; double a = sqrt(1-x*x) / 2; double b = .5 – a; double y = sqrt(x*x/4 + b*b); x = y; sides *= 2; } CS101 2012.1

  25. Numerical integration • Divide x-axis into intervals of width h • Approximate area under function f(x) between x and x+h as h f(x) • As h becomes smaller, estimate should become more accurate • But remember finite precision limitations CS101 2012.1

  26. One loop nested in another double h = .01; while (true) { double area = 0, x = -1.; while (x + h <= 1.) { area += h * sqrt(1. – x*x); x += h; } cout << 2.*area << endl; h /= 2.; // halve interval width } CS101 2012.1

  27. Moral of the story • On an ideal computer, increasing number of polygon sides, or decreasing interval width h without bound should get you better and better estimates • Finite precision prevents this • (This is why we need to know our hardware representation!) • In general limits are troublesome to evaluate reliably • Luckily there are other methods, e.g., convergent series CS101 2012.1

  28. ex • Well-known series double ans=1, base=x, fac=1, ix=1; bool keepGoing = true; while (keepGoing) { ans += base/fac; base *= x; fac *= (++ix); if (base/fac < epsilon) { keepGoing = false; } } Tedious to have to exit from a loop like this CS101 2012.1

  29. break while (true) { ans += base/fac; base *= x; fac *= (++ix); if (base/fac < epsilon) { break; } cout << (base/fac) << endl; } Terminates immediately enclosing while loop CS101 2012.1

  30. Pep • Why are we developing algorithms to compute powers of numbers or or ex if we already have library functions? • Techniques like limits, numerical integration, series summing are universal • Familiarizes us with loop and break constructs CS101 2012.1

  31. A counting problem • Input is int len • How many sequences of len bits are there? • 2len • Of these, how many do not have two consecutive zeros? • If len = 1, answer is 2 (0, 1) • If len = 2, answer is 3 (01, 10, 11) • Suppose a(len) sequences end with 0 • And b(len) sequences end with 1 • Required answer is a(len) + b(len) CS101 2012.1

  32. Counting problem, continued • If a sequence ends with 0, second last bit must be 1 • Therefore a(len) = b(len-1) • If a sequence ends with 1, second last bit could be either 0 or 1 • b(len) = a(len-1)+b(len-1) • Therefore b(len) = b(len-2)+b(len-1) • First focus only on b(len) • Hemachandra numbers, Fibonacci series CS101 2012.1

  33. Base cases for b() • b(1) = 1 (the bit sequence 1) • b(2) = 2 (sequences 01, 11) int len; cin >> len; if (len == 1 || len == 2) { cout << “b(" << len << ")=" << len; } else { … } CS101 2012.1

  34. After base cases • Note that b(len) depends only on b(len-1) and b(len-2) • Enough to keep around last two values • Rather than all of b(1), b(2), …, b(len) lx lx 1 2 3 5 1 2 3 5 8 bLx bLx bLxM2 bLxM1 bLxM2 bLxM1 CS101 2012.1

  35. Else… len 3 int bLxM2=1, bLxM1=2; int lx = 3; while (lx < len) { int bLx = bLxM2 + bLxM1; // shift forward one step ++lx; bLxM2 = bLxM1; bLxM1 = bLx; } cout << len << " " << (bLxM2+bLxM1) <<endl; Invariant:bLxM2+bLxM1 = b(lx) CS101 2012.1

  36. Running average • The user inputs a sequence of numbers • After the third number is input, and for every subsequent input, print the three-point running average double a1, a2, a3; cin >> a1 >> a2 >> a3; while (true) { cout << (a1 + a2 + a3) / 3.; a1 = a2; a2 = a3; cin >> a3; } CS101 2012.1

  37. Migrations between Mumbai and Pune • Initial populations m and p • Every year, 1/4th of Mumbai migrates to Pune • And ½ of Pune migrates to Mumbai • Simulate for k years • Do the populations stabilize? CS101 2012.1

  38. Migrations code main() { double m, p; int k; cin >> m >> p >> k; for (int t=0; t<k; ++t) { p = p – p/2. + m/4.; m = m – m/4. + p/2.; // print } } X Synchronous vs. asynchronous update CS101 2012.1

  39. Greatest common divisor (gcd) • Given integers m  n  1, find their gcd • gcd(m,n) = gcd(n, m%n) int m, n; cin >> m >> n;// assume m >= n while (n > 0) { const int tmp = n; n = m % n; m = tmp; } cout << m << endl; • Let h = gcd(m,n) •  h divides m, n • Let m = n*q + r • Given h divides n … • … h must divide r • h divides gcd(n,r) (so h  gcd(n,r)) • Also, gcd(n,r) dividesn and r,  n and m •  h  gcd(n,r) CS101 2012.1

  40. “String theory” • Iterative computations are demonstrated well on arrays • We have already introduced strings, which are arrays of characters • Luckily the system manages the array space for us • Can assign and append to strings • Can read a position: cout << message[px] • Can write a position: message[px] = ‘q’ • That’s all we need for now CS101 2012.1

  41. Printing a string in reverse string message; getline(cin, message); int mx = message.size()-1; while (mx >= 0) { cout << message[mx]; --mx; } • mx updated in a completely predictable way • Ideal candidate to write as for loop Character at position mx in string message CS101 2012.1

  42. While and for for (init; cond; stepper) { stmt } while (cond) { stmt } init f cond cond f t t stmt stmt stepper CS101 2012.1

  43. Printing reversed string, for loop • General syntaxfor (prelude; condition; stepper) { body } • Equivalent toprelude; while (condition) { body; stepper; } for (int mx = message.size()-1;mx >= 0; --mx) { cout << message[mx]; } Look, a declaration In ISO standard C++, mx is no longer available here CS101 2012.1

  44. Nested for loops • Calculate  (again!) by… • Generate grid of x, y points in the plane for (double x=-radius; x<=radius; ++x) { for (double y=-radius; y<=radius; ++y) { // detect if they are within a circular disk } } • Just to demonstrate nested for loops • radius2 grid points unacceptably slow • Numerical integration much faster, at least as accurate CS101 2012.1

  45. Finding needles in a haystack • Given two strings, needles and haystack • needles has no repeated characters • haystack may repeat characters • How many characters in needles appear in haystack at least once? • needles = “bat”, haystack = “tabla”  3 • needles = “tab”, haystack = “bottle”  2 CS101 2012.1

  46. One needle in a haystack • Subproblem: given one character ch and a string find if ch appears in string at least once char ch; // suitably initialized string haystack; // suitably initialized int ans = 0; // will change to 1 if found for (int hx = 0; hx < haystack.size(); ++hx) { if (ch == haystack[hx]) { ++ans; break; // quit on first match } } CS101 2012.1

  47. Many needles: nested loop main() { string needles, haystack; getline(cin, needles); getline(cin, haystack); int ans = 0; for (int nx=0; nx < needles.size(); ++nx) { char ch = needles[nx]; for (int hx = 0; hx < haystack.size(); ++hx) { if (ch == haystack[hx]) { ++ans; break; // quit on first match } } // ends haystack loop } // ends needles loop } Generalize to work in case needles can also have repeated characters CS101 2012.1

  48. Duplicate needles • needles = “bat”, haystack = “tabla”  3 • needles = “tab”, haystack = “bottle”  2 • needles = “bata”, haystack = “tabla”  3 • Two approaches • Dedup needles before executing earlier code (reducing to known problem) • Dedup needles “on the fly” (inside the nx loop) Exercise: If the input strings have n and h characters, at most how much time does the needle-in-haystack search code take? CS101 2012.1

  49. Parallel steppers • Print the first character of a string, then the last, then second, then second last … until you meet in the middle for (int lx=0, rx=message.size()-1;lx < rx; ++lx, --rx) { cout << message[lx] << message[rx]; } Parallel steppers Middle character of odd-length string will not get printed CS101 2012.1

  50. lx rx H e l l o lx rx o e l l H lx,rx o l l e H Reversing a string for (int lx=0, rx=msg.size()–1;lx < rx; ++lx, --rx) { const char tmp = msg[lx]; msg[lx] = msg[rx]; msg[rx] = tmp; } Used as lhs, msg[rx] is a cell where a character is to be written Used in a rhs expression, msg[lx] is a character value CS101 2012.1

More Related