CSE 109 Test 2  Monday 6 April 2009
===========================SUGGESTED ANSWERS=============================
1.  The ADT for a Calculator need not be restricted to doing arithmetic
on doubles.  Indeed the ADT applies to any objects that can be set to 0
and for which +, -, *, and / have been overloaded. Start the development
of such an ADT by developing a templated verison of class Calc that has
sufficient functionality for the code below to compile and produce the
indicated output.
 class A{
    public:
      int j;
      friend A operator+(const A&a, const A&b){return A(a.j+b.j);}
      A(int k=0):j(k){}
 };

   Calc<double> a;
   a+=2.3;
   a+=4;
   cout<<a<<endl; //  Calc(6.3);
   Calc <A>  b(2);
   b+=A(3);
   cout<<b.screen.j<<endl;  //  5
==========================================================================
#include <iostream.h>
template <class A>
class Calc{
public:
  A screen;
  Calc(const A&k=0);
  Calc & operator +=(const A&a);
  template <class B>
    friend ostream & operator<<(ostream&out,const Calc<B>&c);
};
template <class B>
  friend ostream & operator<<(ostream&out,const Calc<B>&c){
    out<<"Calc("<<c.screen<<");
    return out;
  }

template <class B>
Calc<B>:Calc(const A&k):screen(k){}

template <class B>
 Calc<B>::Calc & operator +=(const A&a){
   screen=screen+a;
   return *this;
 }
==========================================================================
2.  A hex number is a string that consist of a leading digit of 0, then
the lower case letter 'x', and then one or more digits and lowercase
letters in the range 'a'...'f'. Write a program that expects one argument
in the form of a hex number and writes either "Success" or "Failure"
depending on whether there is exactly one arugment and that argument is
in the form of a hex number. Thus, if the program is store in p2, the
command
 p2 0x8234fab
would display "Success," while the commands
 p2
 p2  a
 p2  a b
would each display failure.  You may not assume the existence of the
function check() (which is better to avoid anyway).
==========================================================================
#include <iostream>
using namespace std;

bool good(int ct, char * arg[]);

int main(int ct, char*arg[]){
  if(good(ct,arg))
    cout<<"Success\n";
  else
    cout<<"Failure\n";
}

bool good(int ct, char * arg[]){
  int loc;
  if(ct!=2)
    return false;
  if(arg[1][0]!='0' || arg[1][1]!='x' || arg[1][2]=='\0')
    return false;
  loc=2;
  while(arg[1][loc]>='0' && arg[1][loc]<='9'
     || arg[1][loc]>='a' && arg[1][loc]<='f')
    loc++;
  return arg[1][loc]=='\0';
}
==========================================================================
3.  Below is the (the relevant part of) the declaration for class Word.
Write the declaration and code for two methods. The first, upcase(), should
change the instance of Word so that all its letters are in uppercase.  The
second, getUpcase(), should return a new instance of Word that is the same
as the original instance of Word, except that all its letters are uppercase.
class Word{
     private:
          char *string;
          int size;
     public:
          Word(char *c);
          int length()const;
          char & operator[](int k);
          char operator[](int k)const;
          Word & operator+=(const Word &w);
          friend ostream & operator<<(ostream & out, const Word &w);
};
==========================================================================
#include <iostream>
using namespace std;

Word Word::getUpcase()const{
  Word a(string);
  a.upcase();
  return a;
}

void Word::upcase(){
  for(int j=0;j<length();j++)
    if(string[j]>='a' && string[j]<='z')
      string[j]=string[j]-'a'+'A';
}
==========================================================================
4. Assume that the class Node below is used to build a binary tree. A binary
tree is "bushy" if every node in the tree has either no children or two
children. Declare and define (write the code for) the function bushy() that
returns true if and only if a tree bushy.  Below the declaration of class
Node is code that shows how bushy() is called.
class Node{
private:
  int key;//software protection aganst changing.
public:
  double data;
  Node *child[2];
  static const int L=0,R=1;
  Node(int k,double d=0,Node *left=NULL,Node *right=NULL);
  Node(const Node & n);
  int getKey()const;
  friend ostream & operator<<(ostream &out,const Node&n);
};
int main(){
  Node *root;
  ....   //build a binary tree
  ....
  if(bushy(root))
    cout<<"I think I shall never see a poem lovely as a bushy tree\n";
  ....
==========================================================================
bool bushy(Node *rt);

bool bushy(Node *rt){
  if(rt==NULL)
    return true;
  if(rt->child[Node::R]==NULL && rt->child[Node::L]==NULL)
    return true;
  if(rt->child[Node::R]==NULL || rt->child[Node::L]==NULL)
    return false;
  return bushy(rt->child[Node::R]) && bushy(rt->child[Node::L]);
}
==========================================================================
