CSc 109 Final Examination 4 PM Sunday 14 May 2000 PL 455 >>>>>>>>>>>>>>>>>>>>>>SUGGESTED ANSWERS<<<<<<<<<<<<<<<<<<<<<<< 1. (20 pts) In class I presented an algorithm for converting a string containing an expression in infix form to a string containing an expression in postfix form. The algorithm involves the input string, a stack, and the output string. For the string "2+3+4*5>6*3+2", considering each character as a token and assuming the C++ precedence for operators, in the table below show the status of the stack and the output string after each token is read. I have provided the list of tokens read. Token Stack Output String ------------------------------------------------------------------ 2 | ) | 2 ------------------------------------------------------------------ + | ) + | 2 ------------------------------------------------------------------ 3 | ) + | 2 3 ------------------------------------------------------------------ + | ) + | 2 3 + ------------------------------------------------------------------ 4 | ) + | 2 3 + 4 ------------------------------------------------------------------ * | ) + * | 2 3 + 4 ------------------------------------------------------------------ 5 | ) + * | 2 3 + 4 5 ------------------------------------------------------------------ > | ) > | 2 3 + 4 5 * + ------------------------------------------------------------------ 6 | ) | 2 3 + 4 5 * + 6 ------------------------------------------------------------------ * | ) * | 2 3 + 4 5 * + 6 ------------------------------------------------------------------ 3 | ) * | 2 3 + 4 5 * + 6 3 ------------------------------------------------------------------ + | ) + | 2 3 + 4 5 * + 6 3 * ------------------------------------------------------------------ 2 | ) > + | 2 3 + 4 5 * + 6 3 * 2 ------------------------------------------------------------------ ) | | 2 3 + 4 5 * + 6 3 * 2 + > ------------------------------------------------------------------ 2. (15 pts) Write Simpletron code for the C++ program below, assuming a Simpletron machine with 100 words of memory. void main(){ for(int i=1; i<=10; i++) cout<<(i*i); } 2012 3312 2113 1113 2012 3010 2112 3111 4100 4300 0001 0011 0001 END 3. (15 pts) Write SimPL code for the following C++ program. void main(){ int s=0; for(int i=1; i<=10; i++) s+=i*i; cout<='a' && ch[chLoc-1]<='z') while(ch[chLoc]>='a' && ch[chLoc]<='z') copy(ch,buff,chLoc,buffLoc); else if(ch[chLoc-1]>='0' && ch[chLoc-1]<='9') while(ch[chLoc]>='0' && ch[chLoc]<='9') copy(ch,buff,chLoc,buffLoc); else switch(ch[chLoc-1]){ case '<': case '>': case '=': case '!': while(ch[chLoc]=='=' || ch[chLoc]=='!' || ch[chLoc]=='<' || ch[chLoc]=='>') copy(ch,buff,chLoc,buffLoc); break; default: ; //do nothing for single chars: +,-,/,*,),( } buff[buffLoc]=' '; buffLoc++; } buff[buffLoc]='\0'; return buff; } 5. (35 pts) In designing our tables of records, our table entries consisted of the nominal information stored in a record, plus a variable for storing the key (usually a string). A second approach consists of having a record class and then creating a subclass of the record class which adds a data member for the key and which adds methods for accessing the key (the subclass inherits the methods for accessing the record). Below is the declaration of a record class Rek. Write the declaration and definition (code) of the class Entry as a subclass of Rek so that the code in the program below compiles and runs. class Rek{ public: Rek(); Rek(int t,int sc); Rek(const Rek&r); friend ostream &operator<<(ostream&out,const Rek &r); int getScore(); int getTest(); protected: int test,score; //'test' is the number of the test }; void main(){ Entry ent1(1,90,"Tom"),ent[3]={Entry(),Entry(2,95,"Dick"),Entry(ent1)}; if(strcmp(ent[2].getKey(),"Tom")==0) cout< class Entry: public REK{ public: Entry(); Entry(const Entry &e); Entry(int t,int sc,char *k); ~Entry(); char * getKey(); friend ostream &operator<<(ostream&out,const Entry &e); private: char *key; }; template Entry::Entry(){key=NULL;} template Entry::Entry(const Entry &e):REK(e.test,e.score){ if(e.key==NULL) key=NULL; else{ key=new char[strlen(e.key)+1]; strcpy(key,e.key); } } template Entry::Entry(int t,int sc,char *k):REK(t,sc){ if(k==NULL) key=NULL; else{ key=new char[strlen(k)+1]; strcpy(key,k); } } template Entry::~Entry(){ if(key!=NULL) delete key; } template char * Entry::getKey(){ return key; } template ostream &operator<<(ostream&out,const Entry &e){ out<<"{"<"< 1 3 --> 1 3 5 ==> 3 --> 3 --> 3 1 5 1 5 7 1 5 7 9 ==> 3 7 --> 3 7 --> 3 7 ==> 3 7 9 1 5 9 1 5 9 10 1 5 8 9 10 1 5 8 10 ==> 7 ---> 7 3 9 3 9 1 5 8 10 1 5 6 8 10 1 --> 1 3 --> 1 3 5 --> 1 3 5 7 --> 1 3 5 7 9 ==> 5 1 3 7 9 --> 5 --> 5 --> 5 1 3 7 9 10 1 3 7 8 9 10 1 3 6 7 8 9 10 ==> 5 8 1 3 6 7 9 10 8. (20 pts) In class I discussed creating a binary file containing instances of the class Junk below. Assume that I have created such a file and stored it in "final.dat". Write a program which modifies the contents of "final.dat" by adding 7 to the value of f for every record whose value for n is 3. class Junk{ public: int n; double f; char name[5]; Junk(); Junk(int en, double ef, char nam[]); }; void main(){ Junk a; fstream f("final.dat",ios::in | ios::out); int loc; loc=0; while(f.read((char *)&a,sizeof(a))){ if(a.n==3){ a.f+=7; f.seekp(loc*sizeof(a)); f.write((char*)&a,sizeof(a)); } loc++; } } 9. (35 pts) On a consulting job I once wrote a program whose sole purpose was to determine whether a very large file had any repeated entries. One way to solve the problem is to hash each entry, halting if any duplicate is found. Suppose the entries are all positive integers. Then we can use the integer itself to give the hash value. Write a class HashTable which could be used to solve this problem. It should simply store integers, using the integer itself for the (initial) hash value. It should be of fixed size, say 101, it should store its data in an array, and it should use linear probing to resolve collisions. Keep the answer simple. Include a member function add(int) which returns a value of 0 if the number was successfully added to the table, a value of 1 if the table was full, and a value of 2 if the number was already in the table. class HashTable{ public: HashTable(); HashTable(const HashTable&t); int add(int x); void dump(); private: int tab[101]; }; HashTable::HashTable(){ for(int j=0;j<101;j++) tab[j]=-1; } HashTable::HashTable(const HashTable&t){ for(int j=0;j<101;j++) tab[j]=t.tab[j]; } int HashTable::add(int x){ int look,loc; look=0; loc=x%101; while(look<101 && tab[loc]!=-1 && tab[loc]!=x){ look++; loc=(loc+1)%101; } if(look>=101) return 1; if(tab[loc]==x) return 2; tab[loc]=x; return 0; }