#include #include #include #include #include using namespace std; ////////////////////// // Function prototypes // used for extra credit part bool OffByABit(vector , vector ); vector HexToBits(unsigned short); //////////////////////////////////////////// // // Seal class definition class seal{ friend ostream &operator<<(ostream&, seal); friend istream &operator>>(istream&, seal &); public: seal(); int getMark(); void setMark(int); unsigned short getDNA(); void setDNA(unsigned short); float getWeight(); void setWeight(float); bool Related(seal); bool maybeRelated(seal); void input(); ~seal(); private: int mark; unsigned short dna_marker; float weight; }; // seal constructor seal::seal(){ mark = -1; dna_marker = 0x00; weight = 0; } // seal destructor seal::~seal(){ // empty destructor } // return what the seal's mark is int seal::getMark(){ return mark; } // set the seal's mark void seal::setMark(int newmark){ mark = newmark; } // return the bit string representing the DNA mark unsigned short seal::getDNA(){ return dna_marker; } // Set the DNA marker string void seal::setDNA(unsigned short dna){ dna_marker = dna; } // get the weight float seal::getWeight(){ return weight; } // set the weight // elephant seals can be big! void seal::setWeight(float newweight){ weight = newweight; } // Make it easy to input a seal void seal::input(){ dna_marker = 0; cout << "Please input the seal ID mark: "; cin >> mark; do{ cout << "Please input the seal DNA string: "; cin >> hex >> dna_marker; } while (dna_marker == 0); cout << "Please enter the seal weight (zero if not known): "; cin >> dec >> weight; } // Test and see if the seal is related // to its possible relative bool seal::Related(seal possible_relative){ return (dna_marker == possible_relative.getDNA()); } // Test and see if the seal may be related - I used a different method // name for clarity in the solution between people who did not try the // extra credit bool seal::maybeRelated(seal maybe_relative){ vector me; vector relative; me = HexToBits(dna_marker); relative = HexToBits(maybe_relative.getDNA()); return OffByABit(me,relative); } // overload the output operator ostream &operator<<(ostream &output, seal s) { output << s.mark << " 0x" << hex << s.dna_marker << " " << dec << s.weight; return output; } // overload the input operator istream &operator>>(istream &input, seal &s){ input >> s.mark >> hex >> s.dna_marker >> dec >> s.weight; return input; } // // end the seal class definition //////////////////////////////////////////// //////////////////////////////////////////// // // The seal lists object // class seal_list{ public: seal_list(); void add_daddy(seal); void add_baby(seal); void load_daddies(string); void load_babies(string); void save_daddies(string); void save_babies(string); void show_paternity(); private: vector daddies; vector babies; }; // default constructor seal_list::seal_list(){ // not much to do, really } // end seal_list void seal_list::add_daddy(seal new_daddy){ // this is easy, just add the new one to the // end of the vector daddies.push_back(new_daddy); } // end add_daddy void seal_list::add_baby(seal new_baby){ // another easy one babies.push_back(new_baby); } // end add_baby void seal_list::load_daddies(string daddyfilename){ seal some_seal; // open the file and make sure that it worked ifstream daddyfile(daddyfilename.c_str()); if (!daddyfile){ cerr << "File " << daddyfilename << " not found." << endl; exit (1); } // end if (!daddyfile) // read lines from the file and addd them to the // vector end int i = 0; while (daddyfile >> some_seal){ daddies.push_back(some_seal); } } // end load_daddies void seal_list::load_babies(string babyfilename){ seal some_seal; // open the file and make sure that it worked ifstream babyfile(babyfilename.c_str()); if (!babyfile){ cerr << "File " << babyfilename << " not found." << endl; exit (1); } // end if (!babyfile) // read babies from the file and add them to the vector. while (babyfile >> some_seal){ babies.push_back(some_seal); } } // end load_babies void seal_list::save_daddies(string daddyfilename){ seal some_seal; // open the output file and check that it worked ofstream daddyfile(daddyfilename.c_str()); if (!daddyfile){ cerr << "File " << daddyfilename << " not found." << endl; exit (1); } // loop over each element in the vector and // write it out to the file for (int i = 0; i < daddies.size(); i++){ daddyfile << daddies[i] << endl; } } // end save_daddies void seal_list::save_babies(string babyfilename){ seal some_seal; // open the file and make sure that it worked ofstream babyfile(babyfilename.c_str()); if (!babyfile){ cerr << "File " << babyfilename << " not found." << endl; exit (1); } // end if (!babyfile) // loop over each element in the vector and // write it out to the file for (int i = 0; i < babies.size(); i++){ babyfile << babies[i] << endl; } } // end save_babies void seal_list::show_paternity(){ // Set up the output cout << endl << endl; cout << setw(15) << "Daddy ID" << setw(15) << "Baby ID" << endl; cout << setw(15) << "--------" << setw(15) << "-------" << endl; // Need to loop across each member of the // daddy vector for (int dad_num = 0; dad_num < daddies.size(); dad_num++){ // Now loop across the baby vector for (int baby_num = 0; baby_num < babies.size(); baby_num++){ // check if the particular daddy fathered the baby if (babies[baby_num].maybeRelated(daddies[dad_num])){ // here's your daddy cout << setw(15) << daddies[dad_num].getMark() << setw(15) << babies[baby_num].getMark() << endl; } } // end for baby_num loop cout << endl; } // end for dad_num loop } // end show paternity // // //////////////////////////////////////////// //////////////////////////////////////////// // // class seal_paternity_app class seal_paternity_app{ public: seal_paternity_app(); seal_paternity_app(string,string); void process_commands(); private: string daddyfilename; string babyfilename; seal_list elephant_seals; void show_menu(); }; seal_paternity_app::seal_paternity_app(){ // set some known null filenames daddyfilename = ""; babyfilename = ""; } seal_paternity_app::seal_paternity_app(string dads, string kids){ // set the initial file names if we want daddyfilename = dads; babyfilename = kids; } void seal_paternity_app::show_menu(){ // Outputs possible commands cout << setw(31) << "Available Commands:" << setw(9) << "Key:" << endl; cout << setw(31) << "-------------------" << setw(9) << "----" << endl; cout << setw(30) << "Add New Father" << setw(9) << "A" << endl; cout << setw(30) << "Add New Baby" << setw(9) << "C" << endl; cout << setw(30) << "Load Seal Fathers File" << setw(9) << "F" << endl; cout << setw(30) << "Load Seal Babies File" << setw(9) << "B" << endl; cout << setw(30) << "Save Seal Fathers File" << setw(9) << "D" << endl; cout << setw(30) << "Save Seal Babies File" << setw(9) << "K" << endl; cout << setw(30) << "Show Paternity" << setw(9) << "P" << endl; cout << setw(30) << "Quit" << setw(9) << "Q" << endl; cout << endl << "Your choice: "; } void seal_paternity_app::process_commands(){ char input; seal new_seal; while (1){ show_menu(); cin >> input; switch(input){ case 'A': case 'a': cout << "Please input father information:" << endl; new_seal.input(); elephant_seals.add_daddy(new_seal); break; case'C': case'c': cout << "Please input seal pup information:" << endl; new_seal.input(); elephant_seals.add_baby(new_seal); break; case 'F': case 'f': cout << "Please enter the seal father input file name: "; cin >> daddyfilename; elephant_seals.load_daddies(daddyfilename); break; case 'B': case 'b': cout << "Please enter the seal children input file name: "; cin >> babyfilename; elephant_seals.load_babies(babyfilename); break; case 'D': case 'd': cout << "Please enter the seal father output file name: "; cin >> daddyfilename; elephant_seals.save_daddies(daddyfilename); break; case 'K': case 'k': cout << "Please enter the seal children output file name: "; cin >> babyfilename; elephant_seals.save_babies(babyfilename); break; case 'P': case 'p': elephant_seals.show_paternity(); cout << endl << endl << endl << endl << endl; break; case 'Q': case 'q': exit (0); break; default: cout << "Bad command. " << endl << endl; break; } // end switch input } // end while(1) } // end process-commands // // //////////////////////////////////////////// //////////////////////////////////////////// // // Main Function int main(){ seal_paternity_app elephant_seals; elephant_seals.process_commands(); return 0; } // // end Main //////////////////////////////////////////// //////////////////////////////////////////// // // Function declarations bool OffByABit(vector first, vector second){ // We need to do a bitwise comparison between the two // and count the bits that are different int difference = 0; for (int i = 0; i < first.size(); i++){ if (first[i] != second[i]) difference++; } // if the difference is zero or one, return true if (difference < 2) return true; else return false; } vector HexToBits(unsigned short number){ // Convert into a bit sequence bu doing multiple divs and mods just // like converting from decimal to binary. There are other (better) // ways to do this, but this uses methods that people in 071 could // reasonably know. // Notice that using push_back reverses the order of the bits. vector bits; int numbits = 0; while (number > 0){ bits.push_back(number % 2); number /= 2; numbits++; } while (numbits < 16){ bits.push_back(0); numbits++; } // I used this for debugging this function // for (int i = bits.size()-1 ; i >= 0 ; i--) // cout << bits[i]; // cout << endl; return bits; } // // end function declarations ////////////////////////////////////////////