⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cw.cpp

📁 C++的一个源代码练习
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////////// Crossword Puzzle Helper//// From Chapter 15 of:// "C++: The Core Language" by Gregory Satir and Doug Brown.// O'Reilly & Associates, Inc. Sebastopol, CA. 1995.///////////////////////////////////////////////////////////////////////////////#include <stdlib.h>     // to get exit()#include <string.h>     // to get strlen() and strcpy()#include <stdio.h>      // to get old-style input#include <iostream.h>   // to get new-style output#include <new.h>        // to get set_new_handler()// big trouble if any word in the dictionary // exceeds this ('\0' terminator included)#define maxwordsize 256 // These are now C++ keywords, take them out if your compiler has them.// If not, use these definitions.typedef int bool;#define true 1#define false 0 // length of hexword generalized // You could have a puzzle with a different length, but we haven't seen any.#define hex 6// error exitvoid oops(char *msg) {  cerr << msg << "\n";  exit(1);}// called by new if insufficient memoryvoid dearth_o_mem() {  oops("out of memory");}///////////////////////////////////////////////////////////////////////////////// String: wrapper class for array of characters///////////////////////////////////////////////////////////////////////////////class String {public:    String();                       // default constructor    ~String();                      // destructor    void operator=(String &s);      // assignment operator    String(String &s);              // copy constructor    void set(char *s);              // set from char*    char *s();                      // return pointer to string    char c(int n);                  // return nth char    int length();                   // return length of string    void print(ostream *os);        // print string to output stream    bool read(FILE *is);            // read string from old-style inputprivate:    char *str;                      // pointer to string    int lth;                        // length of string};// default constructor - initialize objectString::String() {  str = 0;                          // make nothing for set() to deallocate  set("");                          // set() copies empty string} // destructor - free object memoryString::~String() {  delete[] str;                     // deallocate string}// assignment operator - define meaning of operator=() for this classvoid String::operator=(String &s) {  if (this == &s) return;           // don't assign to self  set(s.str);                       // set() makes a copy} // copy constructor - initialize object as copy of another objectString::String(String &s) {   str = 0;                          // make nothing for set() to deallocate  set(s.str);                       // set() makes a copy}// set value from stringvoid String::set(char *s) {  delete[] str;                     // deallocate old string  lth = strlen(s);                  // set length of new string  str = new char[lth+1];            // alloc space for string and terminator  strcpy(str, s);                   // copy string and terminator}// return pointer to stringchar *String::s() {  return str;                       // return the pointer} // return nth character of stringchar String::c(int n) {  // check to make sure n is inside string  if (n < 0 || n >= lth) oops("string index error");  return str[n];                    // return the char} // return length of stringint String::length() {  return lth;                       // return the length} // print string to output streamvoid String::print(ostream *os) {  *os << str;                       // op<<() already knows how to print char*}// overload << for Stringostream &operator<<(ostream &os, String &s) {  s.print(&os);                     // call our print member function  return os;                        // so you can write: cout << a << b} // read string from old-style input// This routine uses fscanf() directly into a buffer, which is unsafe.// If the input file has a word that's too long it will write outside// the buffer.  The code to do this right, typically using a getc()// and checking the buffer size with each character, is left as an// exercise for the reader because it contains nothing new for C++.bool String::read(FILE *is) {  char buf[maxwordsize];            // temp buffer  int n = fscanf(is, "%s", buf);    // read word into buffer  if (n != 1) return false;         // EOF or other failure  set(buf);                         // set String to word  return true;                      // successful return}///////////////////////////////////////////////////////////////////////////////// Rule: class for rules that decide if a word matches some criterion.// This class defines the interface for the acceptance rule.// It has no default for accepts() so all the rules that can be instantiated// are derived from this.///////////////////////////////////////////////////////////////////////////////class Rule {public:    // test word and return true if it meets the criterion    virtual bool accepts(String word) = 0;}; ///////////////////////////////////////////////////////////////////////////////// CwRule: class for crossword puzzle rules///////////////////////////////////////////////////////////////////////////////class CwRule : public Rule {public:    // member function declared in base class    bool accepts(String word);    // set the rule    void set(String cmd);private:    // where to store the rule    String cword;};// Test a word to see if it matches a crossword puzzle rule.// The rule is stored as a String with ?'s where any character// can match, and the rest of the characters must match exactly.bool CwRule::accepts(String dword) {  int i, dlth = dword.length();  // The word must match the rule length exactly  if (dlth != cword.length()) return false;  // loop through each character in the rule  for (i = 0; i < dlth; i++) {    // get the character in the rule    char c = cword.c(i);    // word doesn't match if characters don't match,    // unless rule character is a ?    if (c != '?' && c != dword.c(i)) return false;  }  // word matches if all the characters match  return true;} // set crossword puzzle rulevoid CwRule::set(String cmd) {  cword = cmd;  // uses assignment operator from String class} ///////////////////////////////////////////////////////////////////////////////// HwRule: class for hexword puzzle rules///////////////////////////////////////////////////////////////////////////////class HwRule : public Rule {public:    // member function declared in base class    bool accepts(String word);    // set the rule    void set(String cmd);private:    // where to store the rule    String hword;}; // Test a word to see if it matches a hexword puzzle rule.// The rule is stored as a String with ?'s where any character// can match, and the rest of the characters must match exactly.// Unlike the crossword puzzle word, the hexword puzzle word doesn't// have to match the size of the rule.  The word must be exactly// 6 characters long, and the rule must match consecutive characters// in the dictionary word, going in either direction, possibly// wrapping around the end or beginning.bool HwRule::accepts(String dword) {  int d, h;   // dictionary word length must be 6  if (dword.length() != hex) return false;   // For every starting point d in the dictionary word,  // we scan forward and backward from d to see if the rule matches.  // Instead of d going from 0 to 6 it goes from 6 to 12 so we  // can add or subtract (to go forward or backward) then take the  // modulo 6 to get a character position in the dictionary word.  // If d started at 0 it would go negative and we don't trust  // modulo of negative numbers.  for (d = hex; d < 2 * hex; d++) {    // at each new starting point of the dictionary word,    // assume the forward and backward searches are successful so far    bool fwd = true, bwd = true;    int hlth = hword.length();    // scan the rule, and fwd and bwd in the dictionary word    for (h = 0; h < hlth; h++) {      // get rule character      char c = hword.c(h);      // fail fwd at this d if it doesn't match exactly, unless ?      fwd = fwd && (c == '?' || c == dword.c((d+h)%hex));      // fail bwd at this d if it doesn't match exactly, unless ?      bwd = bwd && (c == '?' || c == dword.c((d-h)%hex));      // optimization - give up on this d if fwd and bwd have already failed      if (!fwd && !bwd) break;    }    // optimization - match if fwd or bwd matched at any d    if (fwd || bwd) return true;  }  // failed if neither fwd nor bwd matched for any d  return false;} // set hexword puzzle rulevoid HwRule::set(String cmd) {  hword = cmd; // uses assignment operator from String class} ///////////////////////////////////////////////////////////////////////////////// Scanner: Class to scan the dictionary searching for words that match// a given rule.///////////////////////////////////////////////////////////////////////////////class Scanner {public:    // default constructor    Scanner();    // destructor    ~Scanner();    // set the dictionary file    void dict(String name);    // scan the dictionary for a given rule    void scan(Rule *the_rule);private:    // assignment operator    void operator=(Scanner &s);    // copy constructor    Scanner(Scanner &s);    // store pointer to dictionary file stream here    FILE *dictionary;};// default constructor - initialize objectScanner::Scanner() {    // no dictionary to start with    dictionary = 0;}Scanner::~Scanner() {    // close dictionary if it's open    if (dictionary != 0) fclose(dictionary);}// set dictionary filevoid Scanner::dict(String name) {  // open the file for old-style reading  dictionary = fopen(name.s(), "r");  // error if it won't open for reading  if (dictionary == 0) oops("can't open dictionary");} // scan the dictionary with a rulevoid Scanner::scan(Rule *the_rule) {  String word;   // make sure we have a dictionary  if (dictionary == 0) oops("no dictionary to search");  // the dictionary needs to be rewound after the first scan  rewind(dictionary);  // read a word from the dictionary  while (word.read(dictionary)) {    // check if the word matches the rule    if (the_rule->accepts(word)) {      // print it if it does      cout << word << "\n";    }  }}///////////////////////////////////////////////////////////////////////////////// mainline code///////////////////////////////////////////////////////////////////////////////// The input loop.  Pass it an instantiation of a scanner.void input_loop(Scanner *the_scanner) {  String cmd;   // command word goes here  CwRule cr;    // crossword rule goes here  HwRule hr;    // hexword rule goes here   // read in typed-in commands  while (cmd.read(stdin)) {    // word beginning with q means quit (or quite enough)    if (cmd.c(0) == 'q') break;    // check for one of our rules    switch (cmd.c(0)) {    // c for crossword rule    case 'c':        // read next word into a String        if (!cmd.read(stdin)) return;        // set the crossword rule with it        cr.set(cmd);        // scan the dictionary with the crossword rule        the_scanner->scan(&cr);        break;    // h for hexword rule    case 'h':        // read next word into a String        if (!cmd.read(stdin)) return;        // set the hexword rule with it        hr.set(cmd);        // scan the dictionary with the hexword rule        the_scanner->scan(&hr);        break;    // otherwise it's an error    default:        cout << "unrecognized command\n";        break;    }  }}// The main function. Parameter argv[1] should be dictionary file name.int main(int argc, char**argv) {  // we want new to exit on memory exhaustion  set_new_handler(dearth_o_mem);  // keep things in sync while we mix the stdio and iostream libraries  ios::sync_with_stdio();  // the scanner we use for scanning the dictionary  Scanner the_scanner;  // String for dictionary name  String dictName;  argc--; argv++;  if (argc != 1) oops("must specify a single dictionary");  // set dictionary name String from command argument  dictName.set(*argv);  // give dictionary name to scanner  the_scanner.dict(dictName);  // pass scanner to input loop  input_loop(&the_scanner);  // exit when input loop is done  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -