Answers to all exercises of

   Ammeraal, L. (2000) C++ for Programmers, 3rd Edition,
      Chichester: John Wiley, ISBN 0-471-60697-9.

See also http://home.wxs.nl/~ammeraal/


Exercise 1.1

// p01_01.cpp: Name and address.
#include <iostream>
using namespace std;
int main()
{  cout << "John Brown\n"
        << "1234 Church Street\n"
        << "London\n";
   return 0;
}


Exercise 1.2

// p01_02.cpp: Computing your age.
#include <iostream>
using namespace std;
int main()
{  int curYear, yearOfBirth;
   cout << "Current year:  ";
   cin >> curYear;
   cout << "Year of birth: ";
   cin >> yearOfBirth;
   cout << "Your computed age at the end of this\n"
        << "year is " << curYear - yearOfBirth << endl;
   return 0;
}


Exercise 1.3

a. 15 
b. -16
c. 2k - 1
d. -2k


Exercise 1.4

a. 00000000 00000000 00000000 000010011
b. 11111111 11111111 11111111 111111000


Exercise 1.5

// p01_05.cpp: Output of double quotes and slashes.
#include <iostream>
using namespace std;
int main()
{  cout << "One double quote: \"\n"
           "Two double quotes: \"\"\n"
           "Backslash: \\\n";
   return 0;
}


Exercise 1.6

include <iostream>  // should be: #include <iostream>
int main();         // should be: int main()
{  int i, j         // should be: {  int i, j;
   i = 'A';         // is correct
   j = "B";         // should be: j = 'B';
   i = 'C' + 1;     // is correct
   cout >> "End of  // should be: std::cout << "End of "
      program/n";   // should be: "program\n";
   return 0         // should be: return 0;
}  


Exercise 1.7

// p01_07.cpp: Hexadecimal constant
#include <iostream>
using namespace std;

int main()
{  cout << 0x55555555 << endl;
   return 0;
}


Exercise 1.8

Single quote: '
Double quote: "
Backslash: \
The End.


Exercise 2.1

// p02_01.cpp: The largest of some positive integers.
#include <iostream>
using namespace std;

int main()
{  int x, maximum = 0;
   cout << "Enter some positive integers, followed\n"
           "by a negative integer:\n";
   for (;;)
   {  cin >> x;
      if (x < 0) 
         break;
      if (x > maximum) 
         maximum = x;
   }
   cout << "Largest: " << maximum << endl;
   return 0;
}


Exercise 2.2

// p02_02.cpp: The average of some positive numbers.
#include <iostream>
using namespace std;

int main()
{  double x, sum = 0;
   int n = 0;
   cout << "Enter some positive numbers, followed by a\n"
           "negative number:\n";
   for (;;)
   {  cin >> x;
      if (x < 0) break;
      sum += x;
      ++n;
   }
   if (n == 0) 
      cout << "No numbers read.\n"; 
   else
      cout << "Average: " << sum/n << endl;
   return 0;
}


Exercise 2.3

// p02_03: Sum of final two decimal digits.
#include <iostream>
using namespace std;
int main()
{  int x;
   cout << "Enter an integer: ";
   cin >> x;
   if (x < 0) x = -x;
   cout << "The sum of the final two digits is "
        << x % 10 + x % 100 / 10 << endl;
   return 0;
}


Exercise 2.4

// p02_04.cpp: Given an sequence of 20 integers, how
//             often is an element of this sequence
//             immediately followed by a smaller one?
#include <iostream>
using namespace std;
int main()
{  int xOld, xNew, i, nLargePrecedesSmall = 0;
   cout << "Enter 20 integers: \n";
   cin >> xOld;
   for (i=2; i<=20; ++i)
   {  cin >> xNew;
      if (xOld > xNew) 
         nLargePrecedesSmall++;
      xOld = xNew;
   }
   cout << "A larger integer is immediately followed by "
        << "a smaller one " << nLargePrecedesSmall 
        << " times.\n";
   return 0;
}


Exercise 2.5

// p02_05.cpp: The second smallest of an input sequence
//             of 10 integers.
//             Note that the second smallest of 
//             1 1 1 1 1 2 3 4 5 6 
//             is 2, not 1.
#include <iostream>
using namespace std;
int main()
{  int x, minimum, secondSmallest;
   cout << "Enter 10 integers:\n";
   cin >> x; 
   minimum = secondSmallest = x;
   for (int i=1; i<10; ++i)
   {  cin >> x;
      if (minimum == secondSmallest)
      {  if (x < minimum) minimum = x;
         else secondSmallest = x;
      }
      else             
      if (x < minimum)
      {  secondSmallest = minimum;
         minimum = x;
      }  
      else
      if (x > minimum && x < secondSmallest) 
         secondSmallest = x;
   }
   if (minimum == secondSmallest)
      cout << "Ten equal integers read.\n";
   else
      cout << "The second smallest is "
           << secondSmallest << endl;
   return 0;
}


Exercise 2.6

// p02_06.cpp: Three sides of a triangle?
#include <iostream>
using namespace std;
int main()
{  double a, b, c, h;
   const double eps = 1e-8;
   cout << "Enter three numbers a, b and c: ";
   cin >> a >> b >> c;
   if (a > c){h = a; a = c; c = h;} // Now c >= a
   if (b > c){h = b; b = c; c = h;} // Now c >= b
   if (a + b < c + eps)
      cout << "No triangle possible with these data.\n";
   else
   {  double v = a * a + b * b - c * c;
      if (v < -eps) 
         cout << "The triangle has an obtuse angle.\n"; 
      else
      if (v > +eps) 
         cout << "The triangle has three acute angles\n"; 
      else cout << "This is a right angled triangle.\n";
   }
   return 0;
}


Exercise 2.7

// p02_07.cpp: Compute all sequences of two or more successive
//             integers whose sum is equal to a given number.
//             The solution below is not the simplest one, but 
//             it is very efficient in that it does not contain 
//             any nested loops.
#include <iostream>
using namespace std;

int main()
{  int s, n, k, ndiv2, t1, tn;
   cout << "Enter the desired sum: ";
   cin >> s;
   for (n=2; n<s; ++n) // n will be the number of terms
   {  k = s/n;      
      ndiv2 = n/2;    
      tn = k + ndiv2; 
      t1 = tn - n + 1;  
      if (t1 < 1) break; 
      if (n % 2 == 1 && s % n == 0                  
      || n % 2 == 0 && s % 2 == 1 && 2 * s % n == 0)
         cout << s << "  = " << t1 << " + ... + "
              << tn << " (" << n << " terms)\n";
         
   }
   return 0;
}


Exercise 2.8

// p02_08.cpp: A generalized chessboard.
#include <iostream>
using namespace std;

int main()
{  int n, k;
   const char white = ' ', black = '*';
   cout << "Chessboard of n x n squares; each black square\n"
        << "consists of k x k asterisks.\n"
        << "Enter n and k: ";
   cin >> n >> k;
   int nk = n * k;
   for (int I=0; I<nk; ++I)    // Line number I (0,...,nk-1)
   {  int i = I/k;             // Row number i (0,..., n-1)
      for (int J=0; J<nk; ++J) // Position J (0,...,nk-1)
      {  int j = J/k;          // Column number (0,...,n-1)
         // If n is even, the upper-left square (i = j = 0) is 
         // white, while it is black if n is odd:
         if ((i + j) % 2 == n % 2) cout << white;
         else cout << black;
         // The above can be programmed more elegantly by
         // using ?:, as we will see in Section 3.1.
      }
      cout << endl;
   }
   return 0;
}


Exercise 2.9

// p02_09.cpp: Smallest and largest integer and their
//             positions in a given sequence of length 20.
#include <iostream>
using namespace std;

int main()
{  int minim, maxim, iMin, iMax, x, i;
   cout << "Enter 20 integers:\n";
   cin >> minim;
   maxim = minim; iMin = iMax = 1;
   for (i=2; i<=20; ++i)
   {  cin >> x;
      if (x < minim){minim = x; iMin = i;} 
      if (x >= maxim){maxim = x; iMax = i;} 
   }
   cout << "Smallest: " << minim 
        << " (first occurrence at position: " << iMin 
        << ").\n";     
   cout << "Largest:  " << maxim
        << " (last occurrence at position:  " << iMax 
        << ").\n";
   return 0;
}


Exercise 2.10

// p02_10.cpp: With a given n x n matrix, compute the
//             maximum distance of a nonzero element to the
//             main diagonal. (This distance is zero if only
//             this diagonal contains nonzero elements.) 
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{  int n, max = 0, i, j, d;
   float x;
   cout << "Enter n: ";
   cin >> n;
   cout << "Enter all n x n matrix elements:\n";
   for (i=1; i<=n; ++i)
   for (j=1; j<=n; ++j)
   {  cin >> x;
      if (x != 0)
      {  d = abs(i - j);
         if (d > max) max = d;
      }
   }
   cout << "The desired distance is equal to " << max 
        << endl;
   cout << "(This is the maximum value of |i - j|\n"
       "for which aij is nonzero.)\n";
   return 0;
}


Exercise 3.1

// p03_01.cpp: Largest integer and its frequency in a sequence
#include <iostream>
using namespace std;

int main()
{  cout << "Enter integers, followed by a nonnumeric character:\n";
   int maxim, n = 1, x;
   cin >> maxim;
   if (!cin) cout << "Error: no integer read at all.\n";
   else
   while (cin >> x)
   {  if (x > maxim)
      {  maxim = x;
         ++n;
      }
   }
   cout << "Largest: " << maxim << ". This occurs " 
        << n << " times.\n";
   return 0;
}


Exercise 3.2

// p03_02.cpp: How many numbers, read from the keyboard,
//             are multiples of 2, 3, and 5?
#include <iostream>
using namespace std;

int main()
{  int x, n2 = 0, n3 = 0, n5 = 0;
   cout << "Enter some integers, followed by a "
           "nonnumeric character:\n";
   while (cin >> x)
   {  if (x % 2 == 0) n2++;
      if (x % 3 == 0) n3++;
      if (x % 5 == 0) n5++;
   }
   cout << n2 << " multiples of 2\n";
   cout << n3 << " multiples of 3\n";
   cout << n5 << " multiples of 5\n";
   return 0;
}


Exercise 3.3

// p03_03.cpp: Sum of 1st, 3rd, 6th, 10th, 15th,... elements 
//             of a number sequence entered by the user.
#include <iostream>
using namespace std;

int main()
{  float x, s = 0;
   int i = 0, iAdd = 1, diff = 1;
   cout << 
      "Add numbers followed by a nonnumeric character: \n";
   while (cin >> x)
   {  if (++i == iAdd)
      {  s += x;
         iAdd += ++diff;
      }
   }
   cout << 
      "Sum (of 1st, 3rd, 6th, 10th, 15th,... number) is "
        << s << endl;
   return 0;
}


Exercise 3.4

// p03_04.cpp: How many distinct integers are read? 
//   (Duplicates are not counted.)
#include <iostream>
using namespace std;

int main()
{  const int maxN = 20;
   // At most 20 distinct integers, with unlimited numbers of
   // duplicates.
   cout << "Enter integers, followed by a nonnumeric 
           "character:\n";
   int n=0, i, a[maxN], x;
   while (cin >> x)
   {  for (i=0; i<n; ++i) 
         if (x == a[i]) break;
      if (i == n)    
      {  if (n == maxN) 
         {  cout << "More than " << maxN 
                 << " distinct integers in input.\n";
            return 0;
         }
         a[n++] = x;
      }
   }
   cout << "Number of distinct integers: " << n 
        << endl;
   return 0;
}


Exercise 3.5

// p03_05.cpp: Frequency table of numbers formed by the least
//    significant six bits of integers read from the keyboard.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  int f[64] = {0}, x;
   cout << "Enter integers, followed by a "
           "nonnegative character:\n";    
   while (cin >> x)
      ++f[x & 0x3F];
   cout << " i   freq[i]\n\n";
   for (int i=0; i<64; ++i)
      if (f[i] > 0) 
      cout << setw(2) << i << setw(8) << f[i] << endl;
   return 0;
}


Exercise 3.6

// p03_06.cpp: Read month, day, year (for example, 12 31 1999)
//    and compute the day number (within one year) of this date.
#include <iostream>
using namespace std;

int main()
{  int day, month, year, i, dayNumber=0, cal[13] =
     {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
   cout << "Enter month, day and year, such as 12 31 1999:\n";
   cin >> month >> day >> year;
   if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) 
      ++cal[2];
   for (i=1; i<=12; i++)
      if (i < month) dayNumber += cal[i]; else break;
   dayNumber += day;
   cout << "Day number, counted from January 1st, is "
        << dayNumber << endl;
   return 0;
}


Exercise 3.7

// p03_07.cpp: Storing four nonnegative integers of four bits
//             in a short int.
#include <iostream>
using namespace std;

int main()
{  int a0, a1, a2, a3, i;
   short int x;
   cout << "Enter four nonnegative integers "
      "a0, a1, a2 en a3,\n"
      "each less than 16:\n";
   cin >> a0 >> a1 >> a2 >> a3;
   x = a3 << 12 | a2 << 8 | a1 << 4 | a0;
   cout << "Enter 0, 1, 2, or 3 to retrieve the first,\n"
        << "second, third, or fourth of these integers:\n"; 
   cin >> i;
   int nShift = 4 * i;
   int ai = (static_cast<unsigned int>(x) >> nShift) & 0xF;
   cout << "Retrieved: " << ai << endl;
   return 0;
}


Exercise 3.8

// p03_08.cpp: Using the operators << and + to multiply by 100.
#include <iostream>
using namespace std;

int main()
{  int x, y;
   cout << "x    = ";
   cin >> x;

   y = (x << 6) + (x << 5) + (x << 2);
   if (x > 0 && y < x || x < 0 && y > x)
      cout << "Take a smaller number for x.\n"; 
   else
      cout << "100x = " << y << endl;
   return 0;
}


Exercise 3.9

// p03_09.cpp: Swapping bits 0 and 7, 1 and 6, 2 and 5, and 3 and 4.
#include <iostream>
using namespace std;

int main()
{  unsigned int x, leftPart, y=0, i;
   cout << "Enter a hexadecimal number; for example, a5f0: ";
   cin >> hex >> x;
   leftPart = x & ~0xFF;
   for (i=0; i<8; i++)
   {  y <<= 1;     // Shift y one position to the left
      y |= x & 1;  // Transport the rightmost bit from x to y
      x >>= 1;     // Shift x one position to the right
   }
   y |= leftPart;
   cout << 
      "After swapping, we obtain " << hex << y << " (hex).\n";
   return 0;
}


Exercise 3.10

// p03_10.cpp: As Exercise 3.9, but bits 0-7 are rotated
//             one position to the left.
#include <iostream>
using namespace std;

int main()
{  unsigned int x, leftPart, rightPart, newBit0, y=0;
   cout << "Enter a hexadecimal integer; for example, a5f0: ";
   cin >> hex >> x;
   leftPart = x & ~0xFF;
   rightPart = x & 0xFF;
   newBit0 = (x & 0x80) >> 7; 
   y = (rightPart << 1) & 0xFF | leftPart | newBit0;
   cout << "After rotating the rightmost eight bits one\n"
      "position to the left, we obtain: " << hex << y << endl;
   return 0;
}


Exercise 3.12

// p03_11.cpp: Application of Horner's rule.
#include <iostream>
using namespace std;

int main()
{  int n, i;
   float x, y, a;
   cout << "Enter n, x, a(n), a(n-1), ..., a(0): ";
   cin >> n >> x;
   y = 0;
   for (i=n; i>=0; i--)
   {  cin >> a;
      y = x * y + a;
   }
   cout << "Result = " << y << endl;
   return 0;
}


Exercise 3.12

// p03_12.cpp: Read ten integers and compute the position 
//    of the one that is equal to the final one. If there 
//    are several, take the first that you encounter.
#include <iostream>
using namespace std;

int main()
{  int a[10], i;
   cout << "Enter 10 integers (a[0], ..., a[9]):\n";
   for (i=0; i<10; ++i) 
      cin >> a[i];
   i = 0; 
   while (a[i] != a[9]) ++i;
   cout << "a[" << i << "] = a[9]\n";
   return 0;
}


Exercise 3.13

// p03_13.cpp: Straight selection sort. 
//   (This should in practice not be done in this way,
//   but rather by means of the sort algorithm, as discussed
//   in Section 9.13.)
#include <iostream>
using namespace std;

void SelSort(float *a, int n) // Sort a[0], a[1], ..., a[n-1]
{  int i, j, imin;
   float min;
   for (i=0; i<n-1; i++)
   {  min = a[i]; imin = i;
      for (j=i+1; j<n; j++)
        if (a[j] < min){min = a[j]; imin = j;}
      // Now min (= a[imin]) is the minimum of
      // the subsequence a[i], ..., a[n-1].
      // We swap it with a[i]:
      a[imin] = a[i]; a[i] = min;
   }
}       

int main()
{  const int N=25;
   float a[N], x;
   int i, n;
   cout << "Enter a sequence of at most " << N << "numbers,\n"
           "followed by a nonnumeric character:\n"; 
   for (n=0; n<N; n++)
   {  cin >> x;
      if (cin.fail()) break;
      a[n] = x;
   }
   // We will now deal with a[0], ..., a[n-1], where n <= N.
   SelSort(a, n);
   cout << "The same numbers in ascending order:\n";
   for (i=0; i<n; i++) 
      cout << a[i] << " ";
   cout << endl;
   return 0;
}


Exercise 3.14

// p03_14.cpp: Frequency diagram.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  int a[25], i, j, max = 0;
   cout << 
      "Enter 25 positive integers, not greater than 40:\n";
   for (j=0; j<25; ++j)
   {  if (!(cin >> a[j]) || a[j] <= 0 || a[j] > 40)
      {  cout << "Incorrect input.\n";
         return 1;
      }
      if (a[j] > max) max = a[j]; 
   }
   cout << endl;
   for (i=max; i>0; --i)
   {  for (j=0; j<25; ++j)
         cout << (a[j] >= i ? "  I" : "   ");
      cout << endl;
   }
   for (j=0; j<25; ++j) 
      cout << setw(3) << j;
   cout << endl;
   return 0;
}


Exercise 3.15

// p03_15.cpp: Count how often each of the integers
//             0, 1, ..., 15 occurs in an input sequence.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  int i, a[16] = {0};
   cout << "Enter integers, followed by a nonnumeric "
           "character:\n";
   while (cin >> i) if (i >= 0 && i < 16) a[i]++;
   cout << "\nThe integers 0, 1, ..., 15 have been entered "
	   "with the following frequencies:\n\n";
   cout << "Number   Frequency\n";
   for (i=0; i<16; ++i) 
      if (a[i] > 0)
         cout << setw(4) << i << setw(9) << a[i] << endl;
   return 0;
}


Exercise 3.16

// p03_16.cpp: A symmetric table.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{  int i, j, n;
   cout << "Enter a (reasonably small) positive integer n: ";
   cin >> n;
   cout << endl;
   for (i=1; i<=n; ++i)
   {  for (j=1; j<=n; ++j)
         cout << setw(3) << (i < j ? i : j);
      cout << endl;
   }
   return 0;
}


Exercise 3.17

// p03_17.cpp: Average, variance, and range of a sequence of
//             real numbers.
#include <iostream>
using namespace std;

int main()
{  double x, s = 0, s2 = 0, minim, maxim;
   int n = 0;
   cout << "Enter two or more numbers, followed by a "
           "nonnumeric character:\n";
   while (cin >> x)
   {  ++n; 
      if (n == 1) minim = maxim = x; else
      {  if (x < minim) minim = x;
         if (x > maxim) maxim = x;
      }
      s += x;
      s2 += x * x;
   }
   if (n < 2) cout << "At least two numbers, please.\n"; else
   {  cout << "Average:  " << s/n << endl;
      cout << "Variance: " << (s2 - s * s / n)/(n - 1) 
           << endl;
      cout << "Range:    " << maxim - minim << endl;
   }
   return 0;
}


Exercise 4.1

// p04_01.cpp: Rectangle of asterisks.
#include <iostream>
using namespace std;

void rectangle(int w, int h, bool outline) 
{  for (int i=1; i<=h; ++i)
   {  for (int j=1; j<=w; ++j)
         cout << (!outline || i == 1 || i == h || j == 1 
                  || j == w ? '*' : ' ');
      cout << endl;
   }
}

int main()
{  cout << "Enter the rectangle's width and height: ";
   int width, height;
   cin >> width >> height;
   cout << "Do you want to print only the outline? (Y/N): ";
   char ch;
   cin >> ch;
   bool outlineOnly = (ch == 'Y' || ch == 'y');
   rectangle(width, height, outlineOnly);
   return 0;
}


Exercise 4.2

// p04_02.cpp: Sum of the decimal digits of an integer.
#include <iostream>
#include <cstdlib>
using namespace std;

int digitsum(int n)
{  int sum=0;
   n = abs(n);
   while (n > 0)
   {  sum += n % 10;
      n /= 10;
   }
   return sum;
}

int main()
{  int k;
   cout << "Enter an integer: ";
   cin >> k;
   cout << "The sum of its decimal digits is  " 
        << digitsum(k) << ".\n";
   return 0;
}


Exercise 4.3

// p04_03.cpp: Display all positive integers x less than 100, 
//             such that a given digit d occurs both in x and 
//             in x * x.
#include <iostream>
#include <iomanip>
using namespace std;
bool occursIn(int d, int x)  // Does digit d occur in integer x?
{  while (x != 0)
   {  if (d == x % 10)
         return true;
      x /= 10;
   }
   return false;
}
int main()
{  int d, x;
   cout << "Enter a decimal digit (0 - 9): ";
   cin >> d;
   for (x=1; x<100; ++x)
   {  if (occursIn(d, x) && occursIn(d, x * x))
         cout << setw(2) << x << setw(6) << x * x << endl;
   }
   return 0;
}


Exercise 4.4

// p04_04.cpp: The functions sort4 and sort4p to sort
//             four integers.
#include <iostream>
#include <cstdlib>
using namespace std;

// C++ reference parameters:

void sort2(int &x, int &y)
{  if (x > y){int t = x; x = y; y = t;}
}

void sort4(int &w, int &x, int &y, int &z)
{  sort2(w, x);  
   sort2(y, z);  // w or y is now the minimum; 
                 // x or z the maximum.
   sort2(w, y);  // w is now the minimum.
   sort2(x, z);  // z is now the maximum.
   sort2(x, y);  // Now w <= x <= y <= z.
}

// C style pointer parameters:

void sort2p(int *p, int *q)
{  if (*p > *q)
   {  int h=*p; *p = *q; *q = h;
   }
}

void sort4p(int *pa, int *pb, int *pc, int *pd)
{  sort2p(pa, pb); 
   sort2p(pc, pd); 
   sort2p(pa, pc); 
   sort2p(pb, pd); 
   sort2p(pb, pc); 
}

int main()
{  int a, b, c, d, a0, b0, c0, d0;
   cout << "Enter four integers: ";
   cin >> a0 >> b0 >> c0 >> d0;
   
   a = a0; b = b0; c = c0; d = d0;
   sort4(a, b, c, d);
   cout << "Sorted by sort4 (reference parameters): " << endl
        << a << " " << b << " " << c << " " << d << endl;
   
   a = a0; b = b0; c = c0; d = d0;
   sort4p(&a, &b, &c, &d);
   cout << "Sorted by sort4p (pointer parameters): " << endl
        << a << " " << b << " " << c << " " << d << endl;
   
   return 0;
}


Exercise 4.5

// p04_05.cpp: Writing a number as a product of prime factors.
#include <iostream>
using namespace std;
void tryFactor(unsigned long *p, unsigned i)
{  static int factorPrinted = 0;
   while (*p % i == 0)
   {  if (factorPrinted) cout << " x "; else
      {  cout << " = ";
         factorPrinted = 1;
      }
      cout << i;
      *p /= i;
   }
}
int main()
{  unsigned long a, a0, i;
   do
   {  cout << "Enter a positive integer: ";
      cin >> a;
   }  while (a < 1);
   a0 = a;
   cout << endl << a;
   tryFactor(&a, 2);
   for (i=3; i*i <= a0; i+=2) 
      tryFactor(&a, i);
   if (a > 1) tryFactor(&a, a); 
   cout << endl;
   return 0;
}


Exercise 4.6

Let us denote the output for k = n as u(n).
Then u(k) is empty (no output) for negative or zero k.
Each other u(k) consists of u(k - 2) and u(k - 1), separated
by the value k:
  u(1) = u(-1) 1 u(0) = 1
  u(2) = u(0) 2 u(1)  = 2 1
  u(3) = u(1) 3 u(2)  = 1 3 2 1
  u(4) = u(2) 4 u(3)  = 2 1 4 1 3 2 1
  u(5) = u(3) 5 u(4)  = 1 3 2 1 5 2 1 4 1 3 2 1


Exercise 4.7

// p04_07.cpp: Recursive and nonrecursive computation
//             of the greatest common divisor (gcd).
#include <iostream>
using namespace std;

int gcd(int x, int y)     // Recursive
{  return y == 0 ? x : gcd(y, x % y);
}

int gcd1(int x, int y)    // Nonrecursive
{  int t;
   while (y > 0)
   {  t = x;
      x = y;
      y = t % y;
   }
   return x;
}           

int main()
{  int a, b;
   cout << "Enter two integers a and b (not both zero):\n";
   cin >> a >> b;
   a = abs(a);
   b = abs(b);
   if (a + b == 0) 
      cout << "a = b = 0 is not allowed.\n"; 
   else
   {  cout << "gcd (a, b) = " << gcd(a, b) << endl;
      cout << "gcd1(a, b) = " << gcd1(a, b) << endl;
   }
   return 0;
}


Exercise 4.8

// p04_08.cpp: Solution to the Towers of Hanoi problem.
#include <iostream>
using namespace std;

/* A tower of n disks is moved from peg src to
   peg dest; peg aux may be used temporarily.
*/
void Hanoi(char src, char aux, char dest, int n)
{  if (n > 0)
   {  Hanoi(src, dest, aux, n-1);
      cout << "Disk " << n << " from peg " <<
              src << " to peg " << dest << '.' << endl;
      Hanoi(aux, src, dest, n-1);
   }
}
int main()
{  int n;
   cout << endl;
   cout << "Enter n, the number of disks: ";
   cin >> n;
   Hanoi('A', 'B', 'C', n);
   cout << endl;
   return 0;
}


Exercise 4.09

// p04_09.cpp: Macros max2 and max3.
#include <iostream>
using namespace std;

#define max2(x, y) ((x) > (y) ? (x) : (y))
#define max3(x, y, z) max2(x, max2(y, z))
int main()
{  int a, b, c;
   cout << "2 times the maximum of "
        << "a = 3 + 4, b = 2 + 3 en c = 5 - 3 is "
        << 2 * max3(a = 3 + 4, b = 2 + 3, c = 5 - 3) << endl;
   return 0;
}


Exercise 4.10

// p04_10.cpp: Binary coded decimal. (Only the least
//             significant two digits are taken).
#include <iostream>
using namespace std;

unsigned char bcd(int n) 
{  return (n/10 % 10 << 4) | n % 10;
}

int main()
{  int result = bcd(12345); 
   cout << 
   "The BCD representation of the final two digits of 12345\n"
   "is the byte " << hex << result << " (hex).\n"; // 45 
   return 0;
}


Exercise 4.11

// p04_11.cpp: Real quadratic equation ax2 + bx + c = 0.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{  double a, b, c, D, sq;
   const double eps = 1e-8;
   cout << "Enter a, b, and c: ";
   cin >> a >> b >> c;
   if (a == 0)
   {  if (b == 0)
      {  if (c == 0) 
            cout << "Any x is a root of this equation.\n"; 
         else cout << "No solution.\n";
      }  
      else // a == 0, b != 0:
         cout << "x = " << -c/b << endl;
   }  
   else   // a != 0
   {  D = b * b - 4 * a * c;
      if (D < -eps) cout << "No solution.\n"; else
      if (D > +eps)
      {  sq = sqrt(D);
         cout << "Two roots: " << (-b+sq)/(2*a)
              << " and " << (-b-sq)/(2*a) << endl;
      }  
      else cout << "Two equal roots: " << -b/(2*a) << endl;
   }
   return 0;
}


Exercise 4.12

// p04_12.cpp: Compute the maximum of 
//             |a2-a1|, |a3-a2|, ..., |a20-a19|, 
//             where the sequence a1, a2, ..., a20
//             is read from the keyboard.
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{  int maxdif = 0, x, xOld, dif;
   cout << "Enter 20 integers:\n";
   cin >> x;
   for (int i=2; i<=20; ++i)
   {  xOld = x;
      cin >> x;
      dif = abs(x - xOld);
      if (dif > maxdif) maxdif = dif;
   }
   cout << "The maximum absolute difference between any\n"
        << "two elements in the sequence is equal to " 
        << maxdif << endl;
   return 0;
}


Exercise 4.13

// p04_13.cpp: The equation sin x - 0.5x = 0 solved
//             numerically by using Newton-Raphson.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

double f(double x){return sin(x) - 0.5 * x;}
double f1(double x){return cos(x) - 0.5;}

int main()
{  double x = 3, x0 = 0, y;
   int i;
   cout << "Intermediate results:\n"
        << setiosflags(ios::showpoint | ios::showpos);
   for (i=1; i<100; ++i)
   {  y = f(x);
      cout << "x = "
           << fixed << setprecision(16) << x
           << "       y = " 
           << scientific << setprecision(4) << y
           << endl;
   if (fabs(y) < 1e-12 && fabs(x - x0) < 1e-12) break;
      x0 = x;
      x = x - y/f1(x);
   }
   cout << "\nThe solution to sin x - 0.5x = 0\n"
           "(to twelve decimals) is "
        << fixed << setprecision(12) << x << ".\n";
   cout << "Number of iteration steps: "
        << showpos << i << endl;
   if (i == 100) 
      cout << 
         "Result unreliable (no convergence in 100 steps).\n";
   return 0;
}


Exercise 4.14

/* p04_04.cpp: Ladder against wall.
   The ladder is the hypotenuse BC of triangle ABC.
   AB is on the floor and AC on the wall. 
   BC is equal to the given ladder length L and
   touches the square ADEF (with sides equal to 1)
   at E, where D is on AB and F on AC. 
   We make use of the variables a = BE and b = EC,
   and we will solve this problem both analytically 
   and iteratively. (Obviously, only one solution
   is actually required.)
   The functions 'analytical' and 'iterative' below
   take the ladder length L as an argument and 
   return the desired distance x = DB.
*/
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;

void error()
{  cout << "Enter a reasonable value of L "
           "(between 2.83 and 1000000)\n";
   exit(1);
}

double analytical(double L)
{  /* With alpha = angle DBE = angle FEC we have
      cos alpha = 1/b and sin alpha = 1/a. It follows that
      1/(b*b) + 1/(a*a) = 1. Furthemore, a + b = L.
      Therefore a*a + b*b = a*a*b*b and 
      a*a + 2ab + b*b = L*L.
      Combining these equations, we find a*a*b*b + 2ab = L*L.
      We set p = ab, obtaining p*p + 2p - L*L = 0.
      Solving this for p, we find p = sqrt(L*L + 1) - 1.
      From ab = p and a + b = L it follows that 
      b*b - Lb + p = 0, so b = (L + sqrt(L*L - 4p))/2.
      Since x : a = 1 : b we have
      x = a/b = ab/(b*b) = p/(b*b).
   */
   double p, b, L2 = L * L, Discr;
   p = sqrt(L2 + 1) - 1;
   Discr = L2 - 4 * p;
   if (Discr < 0) error();
   b = (L + sqrt(L2 - 4 * p))/2;
   return p/(b * b); // = x
}

double iterative(double L, int &i)
{  const double eps = 1e-12;
   double xLow = eps, xHigh = 1, x, a, b, delta, h;
   // x will be between xLow and xHigh.
   for (i=0; i<1000; ++i)
   {  x = (xLow + xHigh)/2;
      a = sqrt(x * x + 1); // Pythagoras (triangle DBE)
      b = a/x;             // Because x : a = 1 : b
      h = a + b;           // Hypotenuse
      delta = h - L;       // Should be zero
      if (delta > eps) xLow = x;        // x was too small
      else if (delta < -eps) xHigh = x; // x was too large
      else break;          // fabs(delta) <= eps
   }
   if (i == 1000) error();
   return x;
}

int main()
{  double L;
   int n;
   cout << "Ladder length L: ";
   cin >> L;
   cout << "Computed analytically: x = " << analytical(L) 
        << endl;
   cout << "Computed iteratively:  x = " << iterative(L, n) 
        << endl;
   cout << "(computed in " << n << " iteration steps)\n";
   return 0;
}


Exercise 4.15

// p04_15.cpp: Compute e, using a series.
#include <iostream>
#include <cmath>
using namespace std;
#define NR_OF_TERMS_REQUIRED 1

#if NR_OF_TERMS_REQUIRED
int iGlobal;  // Only for debug version
#endif

double exp1(double x)
{  const double eps = 1e-10;
   double s, t;
   bool neg = (x < 0);
   if (neg) x = -x;
   s = 1 + x; 
   t = x;
   int i = 2;
   // Already 2 terms computed; t = most recently used term
   // In the following loop we start with the third 
   // term, t = x * x / (2!)
   do s += (t *= x/i++); while (t > eps);
   // i = number of used terms of the series
#if NR_OF_TERMS_REQUIRED
   iGlobal = i;  // Only for debug version
#endif
   return neg ? 1/s : s;  // exp(-x) = 1/exp(x)
}

int main()
{  double x;
   cout << "Enter x: ";
   cin >> x;
   cout << "Standard library function: exp(x) = "
        << exp(x) << endl;
   cout << "Our own function exp1(x) =          " 
        << exp1(x) << endl;
#if NR_OF_TERMS_REQUIRED
   cout << iGlobal << " terms of series computed" << endl;
#endif
   return 0;
}


Exercise 4.16

// p04_16.cpp: Continued fraction.
#include <iostream>
#include <cstdlib>
using namespace std;

long gcd(long a, long b)  // Greatest Common Divisor
{  return b ? gcd(b, a % b) : a;  // See Exercise 4.7
}

int main()
{  long a0, b0, a, b, d, q, r;
   cout << "Enter the positive integers a and b (a < b)\n"
           "of fraction a/b:\n";
   cin >> a0 >> b0;
   if (a0 <= 0 || b0 <= 0)
   {  cout << "a and b must be positive.\n"; 
      exit(1);
   }
   if (a0 >= b0)
   {  cout << "a must be less than b.\n"; 
      exit(1);
   }
   if ((d = gcd(a0, b0)) == 1) 
   {  a = a0;
      b = b0;
   }  
   else
   {  a = a0/d; b = b0/d;
      cout << "Instead of " << a0 << "/" << b0 << ", we take " 
           << a << "/" << b << endl;
   }
   cout << "The following sequence represents the "
           "desired continuous fraction:\n";
   while (a)
   {  q = b / a; 
      r = b % a;
      cout << q << " ";
      b = a;
      a = r;
   }
   cout << endl;
   return 0;
}


Exercise 4.17

// p04_17.cpp: For the given sequence a1, a2, ..., an, 
//             we look for pairs (i, j) (i < j) so that 
//             gcd(ai, aj) = 1.
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

int gcd(int a, int b)    // see also Exercise 4.7
{  return b ? gcd(b, a % b) : a;
}

int main()
{  int n, i, j;
   int *a;
   cout << "Enter n, followed by a sequence of n integers: ";
   cin >> n;
   a = new int[n+1];
   for (i=1; i<=n; ++i) cin >> a[i];
   cout << "Pairs (i, j) (where i and j range from 1 to n),\n"
         "followed by ai and aj so that gcd(ai, aj) = 1, :\n";
   for (i=1; i<=n; ++i)
   for (j=i+1; j<=n; ++j)
      if (gcd(a[i], a[j]) == 1)
         cout << setw(3) << i << " " << setw(3) << j
         << "      " << "==>" << setw(5) << a[i] << "  " 
         << setw(5) << a[j] << endl;
   delete[]a;
   return 0;
}


Exercise 4.18

// p04_18.cpp: Fibonacci sequence. 
#include <iostream>
#include <cmath>
using namespace std;

int main()
{  long previousF = 0, F = 1, h;
   const long double pi = 3.14159265358979323846;
   unsigned n, i;
   cout << "Enter the (nonnegative) integer n: ";
   cin >> n;
   if (n == 0) {cout << "F(0) = 0\n"; return 0;}
   if (n == 1) {cout << "F(1) = 1\n"; return 0;}
   for (i=1; i<n; ++i)
   {  h = previousF;
      previousF = F;
      F = F + h;
      if (F < 0)
      {  cout << 
         "n too large: F(n) does not fit into 'long int'!\n";
         return 1;
      }
   }
   cout << "F(" << n << ") = " << F << endl;
   cout << "F(" << n << ")/F(" << n - 1 << ") = " 
        << static_cast<double>(F)/previousF << endl; 
   cout << "For large n, this value is an approximation of\n"
        << "the mathematical constant tau, which we can\n"
        << "also compute in the following two ways:\n";
   cout << "tau = 2 * cos(pi/5) = " << 2 * cos(pi/5) << endl;
   cout << "tau = 0.5 * (1 + sqrt(5)) = " 
        << 0.5 * (1 + sqrt(5)) << endl;
   return 0;
}


Exercise 5.1

// p05_01.cpp: Output line is reverse of input line.
#include <iostream>
#include <string>
using namespace std;

int main()
{  string s;
   cout << "Enter a line of text:\n";
   getline(cin, s);
   cout << "Reversed:\n";
   for (int i=s.length() - 1; i>=0; --i)
      cout << s[i];
   cout << endl;
   return 0;
}


Exercise 5.2

// p05_02.cpp: The same as Exercise 5.1 but without 
//             type 'string'.
#include <iostream>
#include <string.h>
using namespace std;

int main()
{  const int N = 200;
   char s[N];
   cout << "Enter a line of text:\n";
   int i = N - 1;
   s[i] = '\0';
   char ch;
   while (cin.get(ch), ch != '\n' && i > 0)
      s[--i] = ch;
   if (ch != '\n') // Happens only if length >= N
      cout << "Input string truncated.\n";
   cout << "Reverse:\n";
   cout << s + i << endl;  // or: &s[i]
   return 0;
}


Exercise 5.3

// p05_03.cpp: Determine if two strings are each other's
//             reverse.
#include <iostream>
#include <string>
using namespace std;

bool reverse(const string &s, const string &t)
{  int ns = s.length(), i=0, j;
   if (ns != t.length()) return false;
   for (j=ns-1; j>=0; --j) 
      if (s[i++] != t[j]) return false;
   return true;
}

int main()
{  string a = "ABC", b = "CBA", c = "ABCD", d = "abc";
   cout << "reverse(" << a << ", " << b << ") = " 
        << reverse(a, b) << endl;
   cout << "reverse(" << b << ", " << c << ") = " 
        << reverse(b, c) << endl;
   cout << "reverse(" << b << ", " << d << ") = " 
        << reverse(b, d) << endl;
   return 0;
}


Exercise 5.4

// p05_04.cpp: For each element in a sequence of length 20,
//             count how many smaller elements follow.
#include <iostream>
using namespace std;

int main()
{  const int N = 20;
   int a[N], n, x, i, j;
   cout << "Enter " << N << " integers:\n";
   for (i=0; i<N; ++i) 
      cin >> a[i];
   for (i=0; i<N; ++i)
   {  n = 0; x = a[i];
      for (j=i+1; j<N; ++j) 
         if (a[j] < x) n++;
      cout << "After " << x << " in position " << i + 1 
           << ", " << n << " smaller elements follow.\n";
   }
   return 0;
}


Exercise 5.5

// p05_05.cpp: Merging two sorted sequences of
//             length 10.
#include <iostream>
using namespace std;

int main()
{  const int n = 10;
   float a[n], b[n];
   int i, j;
   cout << "Enter two nondecreasing sequences of " 
        << n << " integers:\n";
   for (i=0; i<n; ++i) cin >> a[i];
   for (j=0; j<n; ++j) cin >> b[j];
   i = j = 0;
   while (i < n && j < n)
      cout << (a[i] < b[j] ? a[i++] : b[j++]) << " ";
   while (i < n) cout << a[i++] << " ";
   while (j < n) cout << b[j++] << " ";
   cout << endl;
   return 0;
}


Exercise 5.6

// p05_06.cpp: Sorting three program arguments.
#include <iostream>
#include <string>
using namespace std;

void sort2(char* &p, char* &q)
{  if (strcmp(p, q)  > 0)
   {  char* t = p; p = q; q = t;
   }
}

int main(int argc, char *argv[])
{  if (argc == 4)
   {  sort2(argv[1], argv[2]);
      sort2(argv[2], argv[3]);
      sort2(argv[1], argv[3]);
      for (int i=1; i<4; ++i) cout << argv[i] << endl;
   }  
   else 
      cout << "Supply three program arguments!\n";
   return 0;
}


Exercise 5.7

// p05_07.cpp: Longest of several input lines.
#include <iostream>
#include <string>
using namespace std;

int main()
{  string s, max;
   cout << "Enter some text lines, the last one followed by\n"
        << "a line consisting only of a period (.):\n";
   getline(cin, max);
   for (;;)
   {  getline(cin, s);
      if (s == ".") break;
      if (s.length() > max.length()) max = s;
   }
   cout << "The longest line read is:\n"
        << max
        << endl;
   return 0;
}


Exercise 5.8

// p05_08.cpp: Pascal's triangle.
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  const int MAX = 12;
   int a[MAX+1], i, j, n;
   cout << "Enter n (at most " << MAX << "): ";
   cin >> n;
   if (n > MAX) 
   {  cout << "Too large.\n"; 
      return 1;
   }
   for (i=0; i<=n; ++i)
   {  a[i] = 1;
      for (j=i-1; j>=1; --j) 
         a[j] = a[j-1] + a[j];
      for (j=(n-i)*3; j>0; --j) 
         cout << ' ';
      for (j=0; j<=i; ++j) 
         cout << setw(6) << a[j];
      cout << endl;
   }
   return 0;
}


Exercise 5.9

a.  D
b.  DEFG
c.  CDEFG
d.  C
e.  0
f.  CDEFG
g.  A


Exercise 6.1

// p06_01.cpp: Names and ages of ten people.
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

struct Person {string name; int age;};

int main()
{  const int n = 10;
   Person a[n]; 
   int i, sum = 0;
   cout << "For each of " << n << 
           " persons, enter name (without\n"
           "any internal space characters) and age:\n";
   for (i=0; i<n; ++i)
   {  cin >> a[i].name >> a[i].age;
      sum += a[i].age;
   }
   double average = sum / static_cast<double>(n);
   cout << "\nAverage age: " << fixed 
        << setw(5) << setprecision(1) << average 
        << endl << endl;
   cout << "Name                     Age    Age deviation\n";
   for (i=0; i<n; ++i)
   {  cout << left << setw(25) << a[i].name
           << right << setw(3) << a[i].age
           << fixed << setw(12) << setprecision(1)
           << a[i].age - average << endl;
   }
   return 0;
}


Exercise 6.2

// p06_02.cpp: A very simple class String.
#include <iostream>
using namespace std;

class String { 
public:
   String(char *s = NULL)               // Default constructor
   {  if (s == NULL)
      {  len = 0;
         ptr = NULL;
      }
      else
      {  len = 0;
         while (s[len] != '\0') ++len;
         ptr = new char[len];
         for (int i=0; i<len; ++i) ptr[i] = s[i];
      }
   }
   String(const String &r)            // Copy constructor
   {  len = r.len; 
      if (len == 0) ptr = NULL;
      else
      if (len != 0)
      {  ptr = new char[len];
         for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
      }
   }
   ~String() {delete[] ptr;}           // Destructor
   String &operator=(const String &r)  // Copy ass. operator
   {  len = r.len;
      if (len == 0) ptr = NULL;
      else
      if (&r != this)
      {  delete[] ptr;
         ptr = new char[len];
         for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
      }
      return *this;
   }
   void printString(ostream &os)const
   {  for (int i=0; i<len; ++i) os << ptr[i];
   }  // Since there is no terminating null character,
      // os << ptr is not possible. 
private:
   char *ptr;
   int len;
};

ostream &operator<<(ostream &os, const String &v)
{  v.printString(os);
   return os;
}

int main()
{  String r, r1, r2(r), s("ABC"), t(s);
   r1 = r;
   r = s;
   r = r;      
   cout << "r: " << r << endl     // ABC
        << "s: " << s << endl     // ABC
        << "t: " << t << endl     // ABC
        << "r1: " << r1 << endl   // (empty string)
        << "r2: " << r2 << endl;  // (empty string)
   return 0;
}


Exercise 6.3

// p06_03.cpp: Difference between two dates of
//             the same (non-leap) year.
#include <iostream>
#include <cstdlib>
using namespace std;

class Dates {
public:
   Dates()
   {  int c[13]; // Calendar
      c[1] = 31; c[2] = 28; c[3] = 31; c[4] = 30;
      c[5] = 31; c[6] = 30; c[7] = 31; c[8] = 31;
      c[9] = 30; c[10]= 31; c[11]= 30; c[12]= 31;
      preceding[0] = 0;
      for (int i=1; i<12; ++i) 
         preceding[i+1] = preceding[i] + c[i];   
   }
   void read2()
   {  cout << "Enter two dates, each coded as a 4-digit "
              "integer (mmdd):\n";
      absDayNr1 = dayNr();
      absDayNr2 = dayNr();
   }
   int difference(){return absDayNr2 - absDayNr1;}
private:
   int absDayNr1, absDayNr2, preceding[13];
      
   int dayNr()
   {  int mmdd, mm, dd;
      cin >> dec >> mmdd; 
         // 'dec' required; otherwise 0101 would be octal
      dd = mmdd % 100;
      mm = mmdd / 100;
      if (dd < 1 || dd > 31 || mm < 1 || mm > 12)
      {  cout << "Invalid input.\n";
         exit(1);
      }
      return preceding[mm] + dd;
   }
};

int main()
{  Dates dd;
   dd.read2();    
   cout << "The second date falls " << dd.difference()
        << " after the first.\n";
   return 0;
}


Exercise 6.4

// p06_04.cpp: All sequences of length n, with each element
//             ranging from a given lower bound to a given 
//             upper bound.
#include <iostream>
#include <iomanip>
using namespace std;

class VarNestedLoops { 
public:
   VarNestedLoops(int n)
   {  r = new int[n]; l = new int[n]; u = new int[n];
      this->n = n;
   }
   ~VarNestedLoops(){delete[]r; delete[]l; delete[]u;}
   void readBounds()
   {  cout << 
      "Enter n input lines, each with two integers, the\n"
      "lower and upper bounds li and ui, where li <= ui:\n";
      for (int i=0; i<n; ++i)
         cin >> l[i] >> u[i];
   }
   void generate(int k = 0)
   {  if (k == n) 
         display_r(); 
      else
         for (r[k] = l[k]; r[k] <= u[k]; ++r[k]) 
            generate(k+1);
   }
private:
   int n, *r, *l, *u;
 
   void display_r()
   {  for (int i=0; i<n; ++i)
         cout << setw(6) << r[i];
      cout << endl;
   }
};

int main()
{  cout << "Enter a (small) positive integer n: ";
   int n;
   cin >> n;
   VarNestedLoops v(n);
   v.readBounds();
   cout << "Result:\n";
   v.generate();
   return 0;
}


Exercise 6.5

// p06_05.cpp: A class 'verylongint'.
//             Preliminary version, based on pointers
//             (see also Exercise 9.9).
#include <string>
#include <iostream>
using namespace std;

class verylongint {
public:
   verylongint(const string &s = "0")
   {  int n = s.length();

      nph = len = 0; ptr = NULL;
      reserve(n);
      for (int i=0; i<n; ++i)
         ptr[i] = s[n - 1 - i] - '0';
      len = n;
      check();
   }
   verylongint(long x)
   {  nph = len = 0; ptr = NULL;
      reserve(1);
      len = 1;
      ptr[0] = x % 10;
      for (;;)
      {  x /= 10;
         if (x == 0) break;
         int r = x % 10;
         reserve(len + 1);
         ptr[len++] = r;
      }
      check();
   }
   verylongint(const verylongint &x)
   {  nph = len = 0; ptr = NULL;
      reserve(x.len);
      len = x.len;
      for (int i=0; i<len; ++i) ptr[i] = x.ptr[i];
   }
   verylongint &operator=(const verylongint &x)
   {  if (&x != this)
      {  delete[] ptr;
         nph = len = 0; ptr = NULL;
         reserve(x.len);
         len = x.len;
         for (int i=0; i<len; ++i) ptr[i] = x.ptr[i];
      }
      return *this;
   }

   friend verylongint operator+(const verylongint &x, 
      const verylongint &y)
   {  verylongint s;
      int d = 0;
      for (int i=0; i<x.len || i < y.len || d != 0; ++i)
      {  if (i<x.len) d += x.ptr[i];
         if (i<y.len) d += y.ptr[i];
         s.reserve(s.len+1);
         s.ptr[s.len++] = d % 10;
         d /= 10;
      }
      return s;
   }

   friend verylongint operator*(const verylongint &x, 
      const verylongint &y)
   {  if (x.len > y.len)
         return y * x;
      // Now x.len <= y.len
      if (x.len == 0) return verylongint();
      verylongint p(y), prod;
      for (int i=0; i<x.len; ++i)
      {  prod = prod + p.mul(x.ptr[i]);
         p.tentimes();
      }
      return prod;
   }

   friend ostream &operator<<(ostream &os, const verylongint &x)
   {  if (x.len == 0) os << 0;
      for (int i=x.len-1; i>=0; --i) os << x.ptr[i];
      return os;
   }

private:
   void check()
   {  while (len > 0 && ptr[len-1] == 0) --len;
   }
   void tentimes()
   {  if (len > 1 || ptr[0] != 0) 
      {  reserve(len + 1);
         for (int i=len; i>0; --i) ptr[i] = ptr[i-1];
         ++len;
         ptr[0] = 0;
      }
   }
   verylongint mul(int k)const// k = 0, 1, ..., 9
   {  verylongint y;
      if (k == 0 || len == 1 && ptr[0] == 0)
         return verylongint(); 
      int d = 0;
      for (int i=0; i<len; ++i)
      {  d += ptr[i] * k;
         y.reserve(y.len + 1);
         y.ptr[y.len++] = d % 10;
         d /= 10;
      }
      if (d != 0) 
      {  y.reserve(y.len + 1);
         y.ptr[y.len++] = d;
      }
      y.check(); 
      return y;
   }         

   void reserve(int n)
   {  if (nph < n)
      {  if (nph < 1) nph = 1;
         while (nph < n) nph *= 2; 
         int *ptr0 = ptr;
         ptr = new int[nph];
         for (int i=0; i<len; ++i) ptr[i] = ptr0[i];
         delete[] ptr0;
      }
   }
   int *ptr, len, nph; 
      // len = logical length, nph = physical length.
};

verylongint kwad(verylongint x)
{  return x * x;
}

int main()
{  verylongint x(30000), y(20000), y1(y), 
            z = "123456789012345", result;
   result = x * x * x * x + y * y * y * y1 + z;
   cout << result << endl;
   return 0;
}


Exercise 6.6

// p06_06.cpp: Write a program that reads an integer n and
//             displays all possible sequences of n bits in
//             which no successive zeros occur.
#include <iostream>
using namespace std;

class BitSequences {
public:
   BitSequences(int n)
   {  this->n = n; 
      r = new int[n];
   }
   ~BitSequences(){delete[]r;}

   void generate(int k = 0)
   {  // This function will print the fixed
      // values r[0], r[1], ..., r[k-1],
      // followed by all possible values of
      // r[k], r[k+1], ..., r[n-1].
      // To achieve this, both for r[k] = 0 (if allowed) 
      // and for r[k] = 1,
      // we recursively call generate(k + 1):
      if (k == n) printn(); else
      {  if (k == 0 || r[k-1] != 0)
         {  r[k] = 0; 
            generate(k+1);
         }
         r[k] = 1; 
         generate(k+1);
      }
   }
private:
   int n, *r;

   void printn()
   {  for (int i=0; i<n; ++i) cout << r[i];
      cout << endl;
   }
};

int main()
{  cout << "Enter the sequence length n: ";
   int n;
   cin >> n;
   BitSequences b(n);
   b.generate();
   return 0;
}


Exercise 7.1

// p07_01.cpp: Function template to display three values
//             in ascending order.
#include <iostream>
#include <string>
using namespace std;
template <class T>
void displaysorted3(T p, T q, T r)
{  T t;
   if (q < p){t = p; p = q; q = t;}
   if (r < q){t = q; q = r; r = t;}
   // Now r is the largest
   if (p < q) 
      cout << p << " " << q;
   else
      cout << q << " " << p;
   cout << " " << r << endl;
}
int main()
{  double x = 3.4, y = 7.5, z = 1.2;
   string s("John"), t("Peter"), u("Nicholas");
   displaysorted3(x, y, z);
   displaysorted3(s, t, u);
   return 0;
}


Exercise 7.2

// p07_02.cpp: Class 'row' of Section 6.9 turned 
//             into a template.
#include <iostream>
#include <string>
using namespace std;

template <class T>
class row { 
public:
   row(int n = 3);                // Default constructor
   row(const row &r);             // Copy constructor
   ~row();                        // Destructor
   row &operator=(const row &r);  // Copy assignment operator
   void printrow(const string &str)const;
private:
   T *ptr;
   int len;
};

template <class T>
row<T>::row(int n)              // default = 3 not repeated here
{  len = n; ptr = new T[n];
   for (int i=0; i<n; ++i) ptr[i] = 10 * i;
}

template <class T>
row<T>::row(const row<T> &r)            // Copy constructor
{  len = r.len;
   ptr = new T[len];
   for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
}

template <class T>
row<T>::~row() {delete[] ptr;}       // Destructor

template <class T>
row<T> &row<T>::operator=(const row<T> &r) // Copy assignment operator
{  if (&r != this)
   {  delete[] ptr;
      len = r.len;
      ptr = new T[len];
      for (int i=0; i<len; ++i) ptr[i] = r.ptr[i];
   }
   return *this;
}

template <class T>
void row<T>::printrow(const string &str)const
{  cout << str;
   for (int i=0; i<len; ++i) cout << ptr[i] << ' ';
   cout << endl;
}

int main()
{  row<int> ri, si(5), ti(si);
   ri = si;
   ri.printrow("ri: ");
   si.printrow("si: ");
   ti.printrow("ti: ");

   row<double> rd, sd(5), td(sd);
   rd = sd;
   rd.printrow("rd: ");
   sd.printrow("sd: ");
   td.printrow("td: ");

   return 0;
}


Exercise 8.1

// p08_01.cpp: Input of integers with exception handling.
#include <iostream>
using namespace std;

class NumInputFailure { };

void readInt(int &x)
{  cin >> x;
   if (cin.fail())
      throw NumInputFailure();
}

int main()
{  int k, n;
   cout << "Enter two integers:\n";
   try
   {  readInt(k);
      cout << "Read: k = " << k << endl;
      readInt(n);
      cout << "Read: n = " << n << endl;
   }
   catch (NumInputFailure)
   {  cout << "Could not read a number.\n";
      exit(1);
   }
   return 0;
}


Exercise 8.2

// p08_02.cpp: Exception handling dealing with negative
//             argument of square-root function.
#include <iostream>
#include <cmath>
using namespace std;

class NegArg {};

double sqrt1(double x)
{  if (x < 0) throw NegArg();
   return sqrt(x);
}

int main()
{  try
   {  cout << sqrt1(0.04) << endl;  // Output: 0.2
      cout << sqrt1(-0.03) << endl; // Throws a NegArg exception
      cout << sqrt1(0.09) << endl;  
                          // No output due to previous statement
   }
   catch(NegArg)
   {  cout << "Negative argument used for sqrt1.\n";
   }
   return 0;
}


Exercise 9.1

// p09_01: Read an integer and display its digits in
//         the number system with base b, where b (at
//         least 2 and at most 10) is also read from 
//         the keyboard. 
//         Use a stack to store these digits.
#include <iostream>
#include <stack>
using namespace std;

int main()
{  cout << "Enter an integer: ";
   long x;
   cin >> x;
   cout << 
      "Enter the base of the desired number system (2-10): ";
   int b;
   cin >> b;
   if (b < 2 || b > 10){cout << "Invalid.\n"; return 1;}

   stack<int> s;
   if (x == 0){cout << "0\n"; return 0;}
   if (x < 0){cout << "-"; x = -x;}
   while (x)
   {  s.push(x % b);
      x /= b;
   }
   while (!s.empty())
   {  cout << s.top();
      s.pop();
   }
   cout << endl;
   return 0;  
}


Exercise 9.2

// p09_02.cpp: Pairs of gears.
//    The q-values will appear in ascending order.
#include <iostream>
#include <iomanip>
#include <utility>
#include <algorithm>
using namespace std;
using namespace std::rel_ops;

struct line {
   bool operator<(const line &y)const
   {  return q < y.q;
   }
   bool operator==(const line &y)const
   {  return q == y.q;
   }
   int a, b; 
   float q;
};

int main()
{  int a, b, s, k = 0;
   float q;
   int z[]={30, 35, 37, 40, 45,
      	    47, 50, 52, 55, 57,
	         60, 65, 68, 70, 75,
	         78, 80, 82, 85, 86,
	         87, 90, 95, 97, 99};
   const int n = sizeof(z)/sizeof(z[0]);
   line pairs[n * n / 2 + 1];

   // In total, there are n * n ordered pairs (a, b).
   // Among these, there are as many with q < 1 as there
   // are with q > 1. Only those with q < 1 are acceptable,
   // which means that the number of output lines will
   // not exceed n * n / 2 + 1. This explains the size of 
   // the above array pairs, in which we store triples 
   // (a, b, q) before we sort them:

   for (int i=0; i<n; ++i)
   for (int j=i+1; j<n; ++j) 
   {  a = z[i]; 
      b = z[j]; 
      s = a + b;
      if (s >= 130 && s <= 140)
      {  q = float(a)/b;
         if (q >= 0.5) // q < 1 is true because z[i] < z[j]
         {  pairs[k].a = a; 
            pairs[k].b = b;
            pairs[k++].q = q;
         }
      }
   }
   sort(pairs, pairs + n);
   cout << "The following " << k << 
           " pairs satify the requirements:\n";
   cout << "   a   b        q\n";
   for (int h=0; h<k; ++h)
   {  cout << setw(4) << pairs[h].a 
           << setw(4) << pairs[h].b
           << fixed << setw(12) << setprecision(5) 
           << pairs[h].q << endl;
   }
   return 0;
}


Exercise 9.3

// p09_03.cpp: A deque in action.
#include <iostream>
#include <deque>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{  deque<int> D;
   int n;
   cout << "How many modification of the deque do you want? ";
   cin >> n;
   cout << "i    Deque contents\n";
   srand(time(NULL));
   for (int i=0; i<n; ++i)
   {  int x = rand();
      int d = x % 10;
      if (d < 6)
      {  if (d < 3) 
            D.push_front(x); 
         else
            D.push_back(x);
      }
      else
      if (!D.empty())
      {  if (d < 8) 
            D.pop_front();
         else
            D.pop_back();
      }
      cout << i << "    ";
      for (int j=0; j<D.size(); ++j)
         cout << D[j] << " ";
      cout << endl;
   }
   return 0;
}


Exercise 9.4

// p09_04.cpp: Words read from the keyboard are shown,
//             along with the numbers of the lines on
//             which they occur.
#include <iostream>
#include <iomanip>
#include <ctype.h>
#include <string>
#include <set>
#include <map>
using namespace std;

typedef set<int> settype;
typedef map<string, settype> maptype;

bool wordread(string &word, int &linenr)
{  char ch;
   // scan for first letter:
   for (;;)
   {  cin.get(ch);
      if (isalpha(ch)) break;
      if (ch == '\n') 
      {  linenr++;
         cin.get(ch);
         if (ch == '.') return false;
         cin.putback(ch);
      }
   }
   word = "";
   // scan for first non-alpha character:
   do
   {  word += tolower(ch);
      cin.get(ch);
   }  while (isalpha(ch));
   cin.putback(ch); // ch may be '\n'
   return true;
}
   
int main()
{  maptype M;
   maptype::iterator im;
   settype::iterator is, isbegin, isend;
   string word;
   int linenr = 1;
   cout << "Enter lines of text, "
           "terminated by a line containing\n"
           "only a period (.):\n";
   while (wordread(word, linenr)) 
   {  im = M.find(word);
      if (im == M.end()) 
         im = M.insert(maptype::value_type(word, 
            settype())).first;
      (*im).second.insert(linenr);
   }
   cout << "\nWords and line numbers:\n";
   for (im = M.begin(); im != M.end(); im++)
   {  cout << setiosflags(ios::left) << setw(15)
           << (*im).first.c_str();
      isbegin = (*im).second.begin();
      isend = (*im).second.end();
      for (is=isbegin; is != isend; is++)
         cout << " " << *is;
      cout << endl;
   }
   return 0;
}


Exercise 9.5

// p09_05.cpp: Read a sequece a of integers, followed by a
//             nonnumeric character. Skip this character and
//             then read another sequence, b, of equal length.
//             Build yet another sequence, c, again of the same
//             length, such that each element a[i] is equal to
//             the larger of a[i] and b[i].    
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{  vector<int> a, b, c;
   int x;
   char ch;
   cout << "Enter two sequences (of integers) of equal\n"
           "length, separated by a nonnumeric character:\n";
   while (cin >> x) a.push_back(x);
   cin.clear();
   cin.get(ch);
   int n = a.size(), i;
   for (i=0; i<n; ++i)
   {  cin >> x;
      b.push_back(x);
      c.push_back(max(a[i], b[i]));
      // Only vector a is really useful here, while
      // the use of b and c can be easily avoided.
   }
   cout << "Pairwise maximum values c[i]:\n";
   for (i=0; i<n; ++i)
      cout << c[i] << " ";
   cout << endl;                  
   return 0;
}


Exercise 9.6

// p09_06.cpp: Write a program that reads two lines 
//             of text. Produce
//             a. A line of output containing all 
//                characters that occur in the input text.
//             b. A line of output containing all characters 
//                that occur on both the first and the 
//                second input line.
//             On each output line, a character must not 
//             occur more than once, and the characters 
//             must occur in alphabetic order. 
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;

int main()
{  set<char> S1, S2, unionOfSets, intersection;

   cout << "Enter two lines of text:\n";
   char ch;
   while (cin.get(ch), ch != '\n') S1.insert(ch);
   while (cin.get(ch), ch != '\n') S2.insert(ch);
   set_union(S1.begin(), S1.end(), S2.begin(), S2.end(),
      inserter(unionOfSets, unionOfSets.end()));
   set_intersection(S1.begin(), S1.end(), S2.begin(), S2.end(),
      inserter(intersection, intersection.end()));
   cout << "Characters, just entered, in alphabetic order:\n";
   set<char>::iterator i;
   for (i=unionOfSets.begin(); i!=unionOfSets.end(); ++i)
      cout << *i;
   cout << "\nCharacters occurring on both input lines:\n";
   for (i=intersection.begin(); i!=intersection.end(); ++i)
      cout << *i;
   cout << endl;       
   return 0;
}


Exercise 9.7

// p09_07.cpp. Sieve of Eratosthenes
// (computing all prime numbers under 100000).

#include <iostream>
#include <fstream>
#include <bitset>
using namespace std;

int main()
{  int i;
   long k, maximum, howmany = 0;

   const int n = 100000, sqrtn = 317;
   // 316 * 316 = 99856 and 317 * 317 = 100489.
   // If you change n, you should make sqrtn equal to the
   // square root of n, rounded up to an integer.

   bitset<n> b;
   // b[i] = 1 means: the integer i has a nontrivial divisor 
   // (i = 2, 3, 4, ...)
   for (i=2; i<sqrtn; ++i)
     if (!b.test(i)) // i.e. b[i] == 0, i is prime,
       for (k=long(i)*i; k<n; k+=i) b.set(k);
   ofstream out("prime.dat");
   for (k=2; k<n; ++k)
   {  if (!b.test(k))
      {  out << k << endl;
         maximum = k;
         howmany++;
      }
   }
   cout << "There are " << howmany 
        << " prime numbers less than " 
        << n 
        << ".\n";
   cout << "The largest of these is " 
        << maximum 
        << " (see also the file prime.dat).\n";
   return 0;
}


Exercise 9.8

// p09_08.cpp: Josephus problem, solved with list container.
#include <iostream>
#include <list>
using namespace std;

typedef list<int>::iterator iter;

iter step(list<int> &L, iter i)
{  iter i1 = ++i;
   return (i1 == L.end() ? L.begin() : i1);   
}

int main()
{  int n, k, j;
   cout << "Initially, n persons are placed in a circle.\n"
           "All persons in the circle are visited in turn\n"
           "and each time the kth person is removed.\n"
           "Enter n and k: ";
   cin >> n >> k;
   list<int> L;
   for (j=1; j<=n; ++j) L.push_back(j);
   iter i1 = L.end(), i;
   --i1;
   for (j=0; j<n; ++j) 
   {  for (int h=1; h<=k; ++h)
      {  i = i1;
         i1 = step(L, i);
      }
      cout << "This person is now removed: " << *i1 << endl;
      L.erase(i1);
      i1 = i;
   }      
   return 0;
}


Exercise 9.9

// p09_09.cpp: As Exercise 6.5 (class verylongint), 
//             but using a vector rather than a pointer.
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class verylongint {
public:
   verylongint(const string &s = "0")
   {  for (int i = s.size()-1; i>=0; --i)
         v.push_back(s[i] - '0');
      check();
   }
   verylongint(const verylongint &x)
   {  v = x.v;
   }

   verylongint(long x)
   {  v.push_back(x % 10);
      for (;;)
      {  x /= 10;
         if (x == 0) break;
         int r = x % 10;
         v.push_back(r);
      }
      check();
   }

   verylongint &operator=(const verylongint &x)
   {  v = x.v;
      return *this;
   }

   friend verylongint operator+(const verylongint &x, 
      const verylongint &y)
   {  verylongint s;
      int d = 0;
      for (int i=0; 
           i<x.v.size() || i < y.v.size() || d != 0; 
           ++i)
      {  if (i<x.v.size()) d += x.v[i];
         if (i<y.v.size()) d += y.v[i];
         s.v.push_back(d % 10);
         d /= 10;
      }
      return s;
   }
   friend verylongint operator*(const verylongint &x, 
      const verylongint &y)
   {  if (x.v.size() > y.v.size())
         return y * x;
      // length of x <= length of y
      if (x.v.size() == 0) return verylongint();
      verylongint p=y, prod;
      for (int i=0; i<x.v.size(); ++i)
      {  prod = prod + p.mul(x.v[i]);
         p.tentimes();
      }
      return prod;
   }
   
   friend ostream &operator<<(ostream &os, const verylongint &x)
   {  if (x.v.size() == 0) os << 0;
      for (int i=x.v.size()-1; i>=0; --i)
         os << x.v[i];
      os << endl;
      return os;
   }

private:
   void check()
   {  while (v.size() > 0 && v[v.size()-1] == 0) v.pop_back();
   }
   void tentimes()
   {  v.insert(v.begin(), 0);
   }
   verylongint mul(int k)// k = 0, 1, ..., 9
   {  verylongint y;
      if (k == 0 || v.size() == 0)
         return verylongint(); 
      int d = 0;
      for (int i=0; i<v.size(); ++i)
      {  d += v[i] * k;
         y.v.push_back(d % 10);
         d /= 10;
      }
      if (d != 0) y.v.push_back(d);
      return y;
   }               
          
   vector <int> v;
};

verylongint kwad(verylongint x)
{  return x * x;
}

int main()
{  verylongint x(30000), y(20000), y1(y), 
            z = "123456789012345", result;
   result = x * x * x * x + y * y * y * y1 + z;
   cout << result << endl;
   return 0;
}


Exercise 10.1

// p10.01.cpp: Display the longest line of a given text file.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main()
{  string filename, s, longest = "";
   int maxlen = 0;
   cout << "Name of input file: ";
   cin >> filename;
   ifstream in(filename.c_str());
   if (in.fail())
   {  cout << "Cannot open input file\n";
      return 1;
   }
   while (getline(in, s, '\n'), !in.fail())     
      if (s.length() > maxlen) 
      {  longest = s;
         maxlen = s.length();
      }
   cout << "Longest line read:\n";
   cout << longest << endl;
   return 0;
}


Exercise 10.2

// p10.02.cpp: Counting words (separated by space characters)
//             in an input file.
#include <fstream>
#include <iostream>
#include <string>
#include <set>
using namespace std;

int main()
{  set<string> words;
   string filename, s, longest = "";
   int maxlen = 0;
   cout << "Name of input file: ";
   cin >> filename;
   ifstream in(filename.c_str());
   if (in.fail())
   {  cout << "Cannot open input file\n";
      return 1;
   }
   while (in >> s) words.insert(s);
   cout << "There are " << words.size() 
        << " distinct words in the input file.\n\n";
   // The following is not really required in the exercise:
   for (set<string>::iterator i=words.begin(); 
      i != words.end(); ++i)
      cout << *i << endl;
   return 0;
}


Exercise 10.3

// p10.03.cpp: Make sure that every comma is followed by a 
//             space character.
#include <fstream>
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

int main()
{  string sIn, sOut;
   char ch;
   ifstream in;

   ofstream out;
   cout << "Name of input file: ";
   cin >> sIn;
   in.open(sIn.c_str());
   if (in.fail())
   {  cout << "Cannot open input file.\n";
      exit(1);
   }
   cout << "Name of output file: ";
   cin >> sOut; 
   out.open(sOut.c_str());
   if (out.fail())
   {  cout << "Cannot open output file.\n";
      exit(1);
   }
   while (in.get(ch))
   {  out.put(ch);
      if (ch == ',')
      {  in.get(ch);
         if (ch != ' ') out.put(' ');
         in.putback(ch);
      }
   }
   cout << "Ready.\n";
   return 0;
}


Exercise 10.4

// p10.04.cpp: Merging two sorted files of integers.
#include <fstream>

#include <iostream>
#include <iomanip>
#include <string>
#include <stdlib.h>
using namespace std;

int main()
{  int n=0, x1, x2, y;
   ifstream in1, in2;
   ofstream out;
   cout << "Enter the names of two input files and\n"
        << "of one output file:\n";
   string sIn1, sIn2, sOut;
   cin >> sIn1;  
   in1.open(sIn1.c_str());
   if (in1.fail())
   {  cout << "Cannot open first input file.\n";
      exit(1);
   }
   cin >> sIn2; 
   in2.open(sIn2.c_str());
   if (in2.fail())
   {  cout << "Cannot open second input file.\n";
      exit(1);
   }
   cin >> sOut;  
   out.open(sOut.c_str());
   if (in1.fail())
   {  cout << "Cannot open output file.\n";
      exit(1);
   }
   in1 >> x1;
   in2 >> x2;
   while (!in1.fail() && !in2.fail())
   {  if (x1 <= x2)
      {  y = x1;
         in1 >> x1;
      }  else
      {  y = x2;
         in2 >> x2;
      }
      out << setw(5) << y << (++n % 10 == 0 ? "\n" : " ");
   }
   while (!in1.fail())
   {  out << setw(5) << x1 << (++n % 10 == 0 ? "\n" : " ");
      in1 >> x1;
   }
   while (!in2.fail())
   {  out << setw(5) << x2 << (++n % 10 == 0 ? "\n" : " ");
      in2 >> x2;
   }
   cout << "Ready.\n";
   return 0;
}


Exercise 10.5

// p10.05.cpp: Merging two sorted files of words.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{  string x1, x2, y;
   ifstream in1, in2;
   ofstream out;
   cout << "Enter the names of two input files and\n"
        << "of one output file:\n";
   string sIn1, sIn2, sOut;
   cin >> sIn1;  
   in1.open(sIn1.c_str());
   if (in1.fail())
   {  cout << "Cannot open first input file.\n";
      exit(1);
   }
   cin >> sIn2; 
   in2.open(sIn2.c_str());
   if (in2.fail())
   {  cout << "Cannot open second input file.\n";
      exit(1);
   }
   cin >> sOut;  
   out.open(sOut.c_str());
   if (in1.fail())
   {  cout << "Cannot open output file.\n";
      exit(1);
   }
   in1 >> x1;
   in2 >> x2;
   while (!in1.fail() && !in2.fail())
   {  if (x1 <= x2)
      {  y = x1;
         in1 >> x1;
      }  else
      {  y = x2;
         in2 >> x2;
      }
      out << y << endl;
   }
   while (!in1.fail())
   {  out << x1 << endl;
      in1 >> x1;
   }
   while (!in2.fail())
   {  out << x2 << endl;
      in2 >> x2;
   }
   cout << "Ready.\n";
   return 0;
}


Exercise 10.6

// p10.06.cpp: Binary I/O and random access.
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{  char ch, ch1;
   string fname;
   fstream f;
   int x=0;
   long k, n;
   cout << "Name of input file: ";
   cin >> fname;
   f.open(fname.c_str(), 
      ios_base::in | ios_base::out | ios_base::binary);
   if (f.fail())
   {  // The file does not exist. We will now create it:
      cout << "Enter the desired file length "
              "(number of integers): ";
      cin >> n;
      f.clear();
      f.open(fname.c_str(), ios_base::out | ios_base::binary);
      if (f.fail())
      {  cout << "Cannot open output file.\n";
         exit(1);
      }
      for (k=0; k<n; k++) f.write(reinterpret_cast<char *>(&x), 
         sizeof(int));
      cout << "The file now contains " << n << " zeros.\n"
              "Start the program again to modify the file.\n";
      return 0;
   }  
   // The file already exists. We will determine its length
   // and modify it.
   f.seekg(0, ios_base::end);
   n = f.tellg()/sizeof(int);
   cout << "The file accommodates " << n <<
           " numbers of type int.\n";
   for (;;)
   {  cout << "Enter a position number k less than "
      << n << " or enter\n"
      "anything else to terminate the program: ";
      cin >> k;
      if (cin.fail() || k < 0 || k >= n) break;
      f.seekg(k * sizeof(int), ios_base::beg);
      f.read(reinterpret_cast<char *>(&x), sizeof(int));
      cout << "This position contains " << x << endl;
      cout << "Do you want to change this value? (Y/N): ";
      cin >> ch;
      while (cin.get(ch1) && ch1 != '\n') ; // Skip the rest
      if (ch == 'Y' || ch == 'y')
      {  cout << "New value: ";
         cin >> x;
         f.seekg(k * sizeof(int), ios_base::beg);
         f.write(reinterpret_cast<char *>(&x), sizeof(int));
      }
   }
   return 0;
}


Exercise 10.7

// p10.07.cpp: From text file to (sorted) binary file.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
using namespace std::rel_ops;

class rec {
public:
   rec(const string &s = "", int i = 0)
   {  strncpy(name, s.c_str(), 25);
      name[25] = '\0';
      nr = i;
   }
   bool operator<(const rec &r)const
   {  return strcmp(name, r.name) < 0;
   }
   bool operator==(const rec &r)const
   {  return strcmp(name, r.name) == 0;
   }
   char *getName(){return name;}
   int getNr(){return nr;}
private:
   char name[26];
   int nr;
};

int main()
{  string fNameIn, fNameOut, name;
   cout << "Name of input file: ";
   cin >> fNameIn;
   ifstream fIn(fNameIn.c_str());
   if (fIn.fail())
   {  cout << "Cannot open input file.";
      exit(1);
   }
   cout << "Name of output file: ";
   cin >> fNameOut;
   ofstream fOut(fNameOut.c_str(), ios_base::binary);
   if (fOut.fail())
   {  cout << "Cannot open output file.";
      exit(1);
   }
   int i, n = 0;
   vector<rec> table;
   while (fIn >> name >> i)
   {  table.push_back(rec(name, i));
      ++n;
   }
   cout << n << " records read from input file.\n";
   if (!fIn.eof())
   {  cout << "File contents incorrect.\n";
      exit(1);
   }

   sort(table.begin(), table.end());

   for (int k=0; k<table.size(); ++k)
      fOut.write(reinterpret_cast<char*>(&table[k]),
         sizeof(rec));
   fOut.close();
   // We now open the same file for input:
   ifstream fBin(fNameOut.c_str(), ios_base::binary);
   rec r;
   while (fBin.read(reinterpret_cast<char*>(&r), sizeof(rec)))
   {  cout << setw(27) << left << r.getName() 
           << right << setw(8) << r.getNr() << endl;
   }
   return 0;
}


Exercise 10.8

// p10_08.cpp: Read the numbers 
//             n, a1, a2, ..., an, b1, b2, ..., bn,
//             in that order, from an input file, and
//             compute the sum of all values max(ai, bi) 
//             (i = 1, 2, ..., n).

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

void error(const char *s)
{  cout << s << endl;
   exit(1);
}
int main()
{  cout << "Input file name: ";
   string fname;
   cin >> fname;  
   ifstream in(fname.c_str());
   if (in.fail()) error("Cannot open input file.\n");
   int i, n;
   double *a, sum = 0, x;
   in >> n;
   a = new double[n];
   for (i=0; i<n; ++i)
   {  in >> a[i];
      if (in.fail()) error("Too few numbers in input file");
   }
   for (i=0; i<n; ++i)
   {  in >> x;  
      if (in.fail()) error("Too few numbers in input file");
      sum += (a[i] > x ? a[i] : x);
   }
   cout << 
      "The sum of all max(ai, bi) values is " << sum << endl;
   delete[] a;
   return 0;
}


Exercise 10.9

// p10_09.cpp: Compute the coefficients a and b of the 
//             regression line y = a + bx.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{  int n = 0;
   double x, y, sx = 0, sx2 = 0, sy = 0, sxy = 0, D;
   cout << "Enter the name of an input file, which\n"
        << "contains pairs of numbers x, y, to be used\n"
        << "for linear regression: ";
   string fname;
   cin >> fname;
   ifstream in(fname.c_str());
   if (in.fail())
   {  cout << "Cannot open input file.\n";
      return 1;
   }
   while (in >> x >> y)
   {  ++n;
      sx += x;
      sx2 += x * x;
      sy += y;
      sxy += x * y;
   }
   D = n * sx2 - sx * sx;
   if (D == 0) 
      cout << "Incorrect input (determinant = 0)\n"; 
   else
   {  cout << 
         "The regression line y = a + bx approximates the\n";
      cout << "given points, where\n";
      cout << "a = " << (sy * sx2 - sx * sxy)/D << endl;
      cout << "b = " << (n * sxy - sx * sy)/D << endl;
   }
   return 0;
}


Exercise 10.10

// p10_10.cpp: The name of a text file is
//    given as a program argument. This file contains
//    the integers k and n, followed by a table of
//    k rows and n columns. The table contains real
//    numbers and is read row by row.
//    This program computes the average of each column.
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

void error(const char *s)
{  cout << s << endl;
   exit(1);
}    

int main(int argc, char *argv[])
{  if (argc != 2) 
      error("File name as program argument. please.");
   ifstream f(argv[1]);
   if (!f) error("Cannot open input file.");
   int k, n, i, j;
   f >> k >> n;
   if (f.fail()) error("Cannot read k and n."); 
   double x, *sum = new (double [n]);  // Row of n column sums
   for (j=0; j<n; ++j) sum[j] = 0;
   for (i=0; i<k; ++i)
   {  for (j=0; j<n; ++j)
      {  f >> x;
         if (f.fail())
         {  cout << "k = " << k << "    n = " << n << endl;
            error("Cannot read k x n numbers.");
         }
         sum[j] += x;
      }
   }
   f >> x; // This should fail!
   if (!f.eof())
      error("More than k x n numbers in input file.");
   for (j=0; j<n; ++j)
      cout << "The average of column " << j
           << " is " << sum[j]/k << ".\n";
   delete[] sum;
   return 0;
}


Exercise 10.11

// p10_11.cpp: Count how many integers there are in a
//             given text file and compute their sum.
//             These integers may be separated by any 
//             nonnumeric character sequences.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class NumFile {
public:
   NumFile()
   {  okFlag = true;
      n = s = 0;
      string fname;
      cout << "Input file name: ";
      cin >> fname;
      fstream in(fname.c_str());    
      if (in.fail())
         okFlag = false; 
      else
      {  for (;;)
         {  int x;
            in >> x;
            if (in.fail())
            {  in.clear();
               in.get(); // Try to read a single character  
               if (in.eof()) break;
            }
            else
            {  ++n;
               s += x;
            }
         }
      }
   }
   bool ok() {return okFlag;}
   int nr(){return n;}
   int sum(){return s;}
private:
   bool okFlag;
   int n, s;
};

int main()
{  NumFile nf;  // Constructor does everything.
   if (nf.ok())
   {  cout << "The input file contains " << nf.nr() 
           << " integers.\n";
      cout << "Their sum is " << nf.sum() << endl;
   } 
   else
      cout << "Cannot open input file.\n";
   return 0;
}


Exercise 10.12

// p10_12.cpp: Concordance.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctype.h>
#include <string>
#include <set>
#include <map>
using namespace std;
typedef set<int> settype;
typedef map<string, settype> maptype;

bool wordread(ifstream &ifstr, string &word, int &linenr)
{  char ch;
   // scan for first letter:
   for (;;)
   {  ifstr.get(ch);
      if (ifstr.fail()) return false;
      if (isalpha(ch)) break;
      if (ch == '\n') ++linenr;
   }
   word = "";
   // scan for first non-alpha character:
   do
   {  word += tolower(ch);
      ifstr.get(ch);
   }  while (!ifstr.fail() && isalpha(ch));

   if (ifstr.fail()) 
      return false;
   ifstr.putback(ch); // ch may be '\n'
   return true;
}
   
int main()
{  maptype M;
   maptype::iterator im;
   settype::iterator is, isbegin, isend;
   string inpfilename, word;
   ifstream ifstr;
   int linenr = 1;
   cout << "Enter name of input file: ";
   cin >> inpfilename;
   ifstr.open(inpfilename.c_str());
   if (!ifstr)
   {  cout << "Cannot open input file.\n"; 
      exit(1);
   }
   
   while (wordread(ifstr, word, linenr)) 
   {  im = M.find(word);
      if (im == M.end()) 
         im = M.insert(maptype::value_type(word, 
            settype())).first;
      (*im).second.insert(linenr);
   }
   
   for (im = M.begin(); im != M.end(); ++im)
   {  cout << left 
           << setw(15)
           << (*im).first.c_str();
      isbegin = (*im).second.begin();
      isend = (*im).second.end();
      for (is=isbegin; is != isend; ++is)
         cout << " " 
              << setw(2) 
              << *is;
      cout << endl;
   }
   return 0;
}


Exercise 10.13

// p10_13.cpp: A textfile and a word are given as program
//             arguments. When reading all lines of the
//             textfile, we display each line that contains 
//             the given word.

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

class FileWord {
public:
   FileWord(const char *s)
   {  in.open(s);
      if (in.fail())
      {  cout << "Cannot open input file.\n";
         exit(1);
      }
   }

   void readlines(const char *w) // We will look for w
   {  string str;

      while (getline(in, str), !in.fail())
      {  if (str.find(w) != string::npos)
            cout << str 
                 << endl;
      }
   }

private:
   ifstream in;
};

int main(int argc, char *argv[])
{  if (argc < 3)
   {  cout << "Supply file name and word as "
              "program arguments.\n";
      return 1;
   }

   FileWord fs(argv[1]);
   fs.readlines(argv[2]);
   return 0;
}


Exercise 10.14

// p10_14.cpp: For an input file (genenerated if it
//    does not exist), we count how many bits are in
//    position 0, in position 1, ..., in position 7
//    of each byte.

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

int main()
{  ifstream in;
   int ch, count[8]={0}, i;
   in.open("element.dat", ios_base::binary);
   if (in.fail())
   {  cout << "Because there is no input file element.dat,\n"
            "an example of such a file will be generated.\n";
      in.close();
      in.clear();
      ofstream out("element.dat", ios_base::binary);
      if (out.fail())
      {  cout << "Cannot open file 'element.dat' for "
                 "output either.\n";
         return 1;
      }
      out.put('\x3E');
      out.put('\xA2');
      out.put('\x77');
      out.close();
      cout << "The file 'element.dat' now contains:\n"
              "0011 1110 (= hex 3E)\n"
              "1010 0010 (= hex A2)\n"
              "0111 0111 (= hex 77)\n";
      in.open("element.dat", ios_base::binary);
      if (in.fail())
      {  cout << 
            "Cannot open this file for input (strange).\n";
         return 1;
      }
   }
   while ((ch = in.get()) != EOF)
   {  for (i=0; i<8; i++)
      {  count[i] += ch & 1;
         ch >>= 1;
      }
   }
   cout << "Count result (= bit frequencies):\n";
   cout << "Count result:\n";
   puts("    E0    E1    E2    E3    E4    E5    E6    E7");
   for (i=0; i<8; i++)
      cout << setw(6) << count[i];
   cout << endl;
   return 0;
}


Exercise 10.15

// p10_15.cpp: The longest and the second longest
//             lines of a given textfile are displayed.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

class InputLines {
public:
   InputLines(const string &fname)
   {  in.open(fname.c_str());
      if (!in)
      {  cout << "Cannot open input file.\n";
         exit(1);
      }
      n = n1 = -1;
   }

   void readFile()
   {  string s;
      int len;
      for (;;)
      {  getline(in, s);
         if (in.fail())
            break;
         len = s.length();
         if (len > n){max1 = max; n1 = n; max  = s; n = len;}
         else
         if (len < n && len > n1){max1 = s; n1 = len;}
      }
   }

   void showResults()
   {  if (n1 == -1)
      {  cout << 
            "There were no two lines of different length.\n";
         exit(1);
      }
      cout << "Longest line:\n" << max << endl;
      cout << "Second longest line:\n" << max1 << endl;
   }
private:
   ifstream in;
   string max, max1;
   int n, n1;
};

int main()
{  string fname;
   cout << "Input file name: ";
   cin >> fname;
   InputLines inputlines(fname);
   inputlines.readFile();
   inputlines.showResults();
   return 0;
}


Exercise 10.16

// p10_16.cpp Count how often a given (whole) word occurs 
//    in an input file. Hyphenation is dealt with correctly.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;

int readWord(string &buffer, ifstream &in)
{  int ch, n=0;
   // Skip any nonalphabetic text:
   while (ch = in.get(), ch != EOF && !isalpha(ch))  ;
   if (ch == EOF) return EOF;
   // Read a (possibly hypenated) word:
   buffer = "";
   do
   {  buffer += static_cast<char>(tolower(ch));
      ch = in.get();
      if (ch == '-')
      {  ch = in.get();
         if (ch == '\n') ch = in.get();
      }
   }  while (isalpha(ch));
   return buffer.length();
}

int main()
{  string word, fname, buffer;
   int wordLength, len, count=0;
   cout << "Enter the word to be counted: ";
   cin >> word;
   wordLength = word.length();
   cout << "Input file name: ";
   cin >> fname;
   ifstream in(fname.c_str());
   if (in.fail())
   {  cout << "Cannot open input file.\n"; 
      return 1;
   }
   for (;;)
   {  len = readWord(buffer, in);
      if (len == EOF) break;
      if (len == wordLength && word == buffer) count++;
   }
   cout << "The given word occurs " << count 
        << " times in the given file.\n";
   return 0;
}


Exercise 10.17

// p10_17.cpp: Sets of words, read from two files, tested 
//             for equality.

#include <iostream>
#include <fstream>
#include <string>
#include <set>
using namespace std;

int main()
{  string nameA, nameB;
   cout << "Enter name of first input file: ";
   cin >> nameA;
   ifstream inA(nameA.c_str());   
   if (inA.fail())
   {  cout << "Cannot open this file.\n";
      return 1;
   }
   cout << "Enter name of second input file: ";
   cin >> nameB;
   ifstream inB(nameB.c_str());   
   if (inA.fail())
   {  cout << "Cannot open this file.\n";
      return 1;
   }
   set<string> A, B;
   string s;
   while (inA >> s)
      A.insert(s);
   while (inB >> s)
      B.insert(s);
   if (A == B)
      cout << "The files contain the same words.\n";
   else
      cout << "The files do not contain the same words.\n";
   return 0;
}


Exercise 10.18

// p10_18.cpp: Justification of text.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;

class Words {
public:
   Words(const char *fNameIn, const char *fNameOut)
   {  in.open(fNameIn);
      if (!in) 
      {  cout << "Cannot open input file.\n";
         exit(1);
      }
      out.open(fNameOut);
      if (!out) 
      {  cout << "Cannot open output file.\n";
         exit(1);
      }
   }
   void askLineLength()
   {  cout << "What is the desired line length? ";
      cin >> lineLength;
   }
   void readAndWrite()
   {  vector<string> wordList;
      string s;
      int cumLength = 0;
      int nWordsOnLine = 0;
      for (;;)
      {  in >> s;
         if (in.fail()) break;
         int len = s.length(), nWords = wordList.size();
         if (cumLength + nWords + len > lineLength)
         {  // s cannot be added to current line, so write
            // all nWords words that are stored in wordList:
            if (nWords > 1)
            {  // There are nWords - 1 word separators, each 
               // taking at least one space character:
               int nRemaining = 
                   lineLength - cumLength - (nWords - 1),
                   nOpenSpaces = nWords - 1,
                   q = nRemaining / nOpenSpaces,
                   r = nRemaining % nOpenSpaces;
               // nRemaining = q * nOpenSpaces + r
               // We rewrite this to show the number of extra
               // spaces (besides the one already taken 
               // account of) between each two successive 
               // words:
               // nRemaining = 
               //        (nOpenSpaces - r) * q + r * (q + 1)
               for (int j=0; j<nWords; ++j)
               {  out << wordList[j];
                  if (j < nOpenSpaces - r) 
                     writeSpaces(q + 1);  
                  else
                  if (j < nOpenSpaces)
                     writeSpaces(q + 2);
                  else // if (j == nOpenSpaces) 
                     out << endl;
               }
            }
            else
            if (nWords == 1) // Justification impossible
            {  out << wordList[0];
               out << endl;
            }
            wordList.clear();
            cumLength = 0;
         }
         wordList.push_back(s);
         cumLength += len;
      }
      // Words on last line not justified:
      for (int j=0; j<wordList.size(); ++j)
      {  out << wordList[j];
         if (j < wordList.size() - 1)
            cout << ' ';
      }
      out << endl;
   }
private:
   ifstream in;
   ofstream out;
   int lineLength;
   
   void writeSpaces(int k)
   {  for (int i=0; i<k; ++i)
         out << ' ';
   }
};

int main(int argc, char *argv[])
{  if (argc != 3)
   {  cout << "Supply input and output file "
              "names as program arguments.\n";
      exit(1);
   }
   Words w(argv[1], argv[2]);
   w.askLineLength();
   w.readAndWrite();
   return 0;
}


Exercise 10.19

// p10_19.cpp: Check if parentheses and {curly} braces match.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;

class SyntaxCheck {
public:
   SyntaxCheck(const string &fname)
   {  in.open(fname.c_str());
      if (!in)
      {  cout << "Cannot open input file.\n";
         exit(1);
      }
   }
   void validSequence()
   {  while (parentheses() || braces()) ;
   }
   void read(int ch0)
   {  if (!trychar(ch0))
      {  cout << "Parentheses and braces do not match.\n";
         exit(1);
      }
   }

private:
   ifstream in;
   
   bool trychar(int ch0)
   {  int ch;
      for (;;)
      {  ch = in.peek();
         if (ch == EOF || ch == '(' || ch == '{'
          || ch == ')' || ch == '}')
         break;
         in.get();
      }          
      // Everything has been skipped until ch is one
      // of the following five: EOF ( { } ). We now read
      // this if this is the desired character ch0:
      if (ch == ch0)
      {  in.get();
         return true;
      }
      return false;
   }
   
   bool parentheses()
   {  if (trychar('('))
      {  validSequence();
         read(')');
         return true;
      }
      return false;
   }
   bool braces()
   {  if (trychar('{'))
      {  validSequence();
         read('}');
         return true;
      }
      return false;
   }
};

int main()
{  string fname;
   cout << "Input file name: ";
   cin >> fname;
   SyntaxCheck check(fname);
   check.validSequence();
   cout << "Input OK.\n";
   return 0;
}


Exercise 10.20

// p10_20.cpp: Test comments and string literals.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;

class CheckComment {
public:
   CheckComment(const string &fname)
   {  in.open(fname.c_str());
      if (in.fail())
      {  cout << "Cannot open input file.\n";
         exit(1);
      }
   }
   void check()
   {  int ch;
      while ((ch = readChar()) != EOF)
      {  if (ch == '/') 
            CPPstyleComment() || CstyleComment(); 
         else
         if (ch == '"' || ch == '\'') 
            StringOrCharConst(ch); 
         else
         if (ch == '*' && in.peek() == '/')
            error("unmatched */");
      }
      cout << 
         "\nThe file is correct with respect to comment.\n";
   }
private:
   string line, oldLine;
   ifstream in;

   int readChar()
   {  int ch;
      ch = in.get();
      cout << static_cast<char>(ch);
      if (ch == '\n')
      {  oldLine = line;
         line = "";
      }  else
      if (ch != EOF)
         line += ch;
      return ch;                                             
   }

   void error(const string &s)
   {  cout << "\nError: " << s << endl;
      exit(1);
   }

   bool CPPstyleComment() // Slash (/) read; if possible, read
                         // second slash and rest of comment:
   {  int ch = in.peek();
      if (ch == EOF) return true;
      if (ch == '/')
      {  do 
         {  ch = readChar(); 
         }  while (ch != '\n' && ch != EOF);
         return true; 
      }  
      return false; 
   }

   bool CstyleComment()  // Slash (/) read; if possible, read
                        // asterisk and all text until '*/'
   {  int ch = in.peek();
      if (ch == EOF) return true;
      if (ch == '*')
      {  readChar();  // Now '/*' has been read
         for (;;)
         {  ch = readChar();
            if (ch == EOF) error("unmatched /*");  
            if (ch == '*')
            {  ch = in.peek();
               if (ch == EOF) error("unmatched /*");
               if (ch == '/') 
               {  readChar();   // Now */ has been read
                  return true; 
               }
            }
         }
      }
      return false;
   }

   void StringOrCharConst(char chr) 
      //  chr (= single or double quote) has been read
   {  int ch;                         
      for (;;)               
      {  ch = readChar();       
         if (ch == '\n' || ch == EOF) 
            error("string or char literal does not "
                  "end correctly.");
         if (ch == '\\')       
         {  ch = readChar(); 
            if (ch == EOF) error("EOF in literal after \\");
         }  else
         if (ch == chr) return;
      }
   }
};

int main()
{  string fname;
   cout << "Enter name of a C++ program file: ";
   cin >> fname;
   CheckComment cmnt(fname);
   cmnt.check();
   return 0;
}


Exercise 11.1

// p11.01.cpp: Demonstration of the functions
//             isalpha, isxdigit, and toupper.
#include <cctype>
#include <iostream>
using namespace std;

int main()
{  char ch;
   cout << "Enter a character: ";
   cin >> ch;
   if (isalpha(ch))
      cout << "This is a letter.\n";
   else
      cout << "This is not a letter.\n";
   if (isxdigit(ch)) 
      cout << "This is a hexadecimal digit.\n";
   else
      cout << "This is not a hexadecimal digit.\n";
   char ch1 = toupper(ch);
   cout << "Result of applying toupper: " << ch1 << endl;
   return 0;
}


Exercise 11.2

// p11_02.cpp: Demonstrating C-style output.
#include <stdio.h>

int main()
{  printf(" x         f(x)\n\n");
   for (int i=20; i<=40; i+=2)
   {  double x = i/10.0;
      printf("%3.1f %15.10f\n", x, x * x + x + 1/x);
   }
   return 0;
}


Exercise 11.3

// p11.03.cpp: Random three-letter sequences.
#include <cstdlib>
#include <iostream>
#include <string>
#include <ctime>
using namespace std;

string gen3()
{  string s;
   for (int k=0; k<3; ++k)
   {  int j = rand() % 26;
      char ch = 'A' + j;
      s += ch;
   }
   return s;
}

int main()
{  // To obtain different sequences each time we
   // run the program, we start as follows:
   srand(time(NULL)); 
   for (int i=0; i<50; ++i)
   {  cout << gen3();
      cout << (i % 10 == 9 ? '\n' : ' ');
   }
   return 0;
}


Exercise 11.4

// p11.04.cpp: A simple problem with NDEBUG.
#define NDEBUG
#include <assert.h>

// This program solves the problem.
// This version terminates normally because
// NDEBUG is defined BEFORE the inclusion of
// the header assert.h. 
// In contrast, NDEBUG has no effect if we
// define it AFTER that header, as was done
// in the exercise.

int main()
{  assert(false);
   return 0;
}
