LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-23-2013, 12:02 PM   #1
R2B Boondocks
LQ Newbie
 
Registered: Nov 2012
Posts: 16

Rep: Reputation: Disabled
Creating a multimap in C++


Hey guys,

I was hoping to get some clarification on some things. I know this is the set up for maps / multimaps:

typedef pair<const Key, T> value_type;

replchoices.h
Code:
#ifndef REPLCHOICES_H
#define REPLCHOICES_H

// Spellcheck program: choosing replacements for misspelled words

#include "cs361set.h"
#include <string>
#include <vector>


// This class implements a policy for choosing "plausible"
// replacements for a misspelled word. Many such policies are possible.
// For example, we might choose words from the system dictionary that
// "look like" the misspelled word, or words from the system dictionary that
// "sound like" the misspelled word, or some combination of these.
//



 struct ReplacementChooserData;


class ReplacementChooser
{
public:
  typedef CS361Set<std::string> Dictionaries;

  // Plan for replacements to be suggested from the
  // given dictionary.
  ReplacementChooser(const Dictionaries& dictionary); // constructor
  ~ReplacementChooser(); // destructor


  // Choose some number of "plausible" replacements for the given word,
  // returning them in the order we want them listed to the user.
  std::vector<std::string> getPlausibleReplacements(const std::string& word)
    const;

private:
  ReplacementChooserData* d;
  // This is an ilustration of a common programming idiom in C++. Normally,
  // the implementing data structure for an ADT is visible in the private
  // portion of a class's .h file. Thus if the ADT designer wants to later
  // change the data structure, he/she must edit the .h file as well as the
  // .cpp file.  We can, at a slight cost, however, hide the data structure
  // from the .h file by placing the implementing data structure inside
  // another class/struct, and simply having a pointer to that class/struct
  // in the ADT.


  // Don't allow copying and assignment of this ADT
  ReplacementChooser(const ReplacementChooser&) {}
  void operator= (const ReplacementChooser&) {}

};


#endif
replchoices.cpp
Code:
#include "replchoices.h"
#include "edit1.h"
#include "soundex.h"

#include <algorithm>
#include <map>

using namespace std;

// This class implements a policy for choosing "plausible"
// replacements for a misspelled word. Many such policies are possible.
// For example, we might choose words from the system dictionary that
// "look like" the misspelled word, or words from the system dictionary that
// "sound like" the misspelled word, or some combination of these.
//


 struct ReplacementChooserData
 {
/*!!
  This is the data structure for the "off-by-one-character"
  suggestion strategy.  You will want to replace this data members
  here by a multimap that maps soundex codes to words having that
  soundex.  Then rewrite the function bodies below accordingly.
 !!*/
  const ReplacementChooser::Dictionaries& dict;

  ReplacementChooserData(const ReplacementChooser::Dictionaries& d): dict(d) {}
 };

typedef multimap< ReplacementChooser, ReplacementChooserData, less <ReplacementChooser> > my_Map;
my_Map mm;
pair < multimap < string , string >::iterator, bool > d;


ReplacementChooser::ReplacementChooser(const Dictionaries& dictionary)
{
  // d = new ReplacementChooserData(dictionary);
  d = mm.insert(ReplacementChooser, ReplacementChooserData(dictionary));
}

ReplacementChooser::~ReplacementChooser()
{
  mm.clear();
}


// Choose some number of "plausible" replacements for the given word,
// returning them in the order we want them listed to the user.
vector<string> ReplacementChooser::getPlausibleReplacements
  (const string& word) const
{
  vector<string> replacements;

  for (Dictionaries::const_iterator w = d->dict.begin();
       w != d->dict.end(); ++w)
    {
      if (oneEditAway(word, *w))
	replacements.push_back (*w);
    }

  return replacements;
}
This is what I am trying to accomplish with my multimap.
  • When the public constructor is called, a multimap is constructed that, for each word W in the dictionary, maps that word's soundex code (computed as extendedSounded(W,-1)) onto W. In other words, this map, when completed, will let you look up words given their soundex codes. We use a multimap for this precisely because many words are supposed to have identical soundex codes.
  • When a set of replacements for a misspelled word is requested, your code should consult the earlier-constructed multimap to get all dictionary words that sound like the misspelling. These should be sorted these into ascending ASCII lexicographic (i.e., the "usual" case-sensitive string <) order.If there are 10 or fewer such words, return them all. Otherwise, return the first 10 of them.

Am I even on the right track towards implementing this properly? (in regards to my replchoices.cpp as that is the only file that I should change per my instruction).

Thanks everyone
 
Old 07-23-2013, 12:28 PM   #2
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 318

Rep: Reputation: Disabled
You've defined your multimap variable, mm, in global scope, meaning it can only have a single instance. Is there anything in ReplacementChooser's interface that precludes client code making multiple instances of it? What would happen with your current design if someone created two ReplacementChoosers?
 
Old 07-23-2013, 12:35 PM   #3
R2B Boondocks
LQ Newbie
 
Registered: Nov 2012
Posts: 16

Original Poster
Rep: Reputation: Disabled
I believe I only need one instance of it so that I can load the information from a file onto the map. This .cpp doesn't have the main so I don't think I have any other choice than making it global correct?

I believe I am also supposed to use the algorithm from soundex.cpp too.
"The crucial code in this assignment is the ReplacementChooser ADT in replchoices.* and the extendedSoundex() function in soundex.* The extendedSoundex function computes a code string for a word such that similarly pronounced words are supposed to produce identical codes (it's a very crude approach). ReplacementChooser encapsulates the strategy for selecting potential replacement words. You should rewrite the implementation of ReplacementChooser so that (refer to bullets above in OP)"

Code:
#include "soundex.h"
#include <algorithm>

//
// The Soundex code is a rather primitive way of encoding the way words
// (especially names) sound so that variant spellings of the same word may
// be identified by the same code.
//
// Traditional Soundex codes have 4 alphanumeric characters
//   1 Letter and 3 Digits
//  - The Letter of the word is the first character of the Soundex code.
//  - The 3 digits are defined sequentially from the word using the
//    Soundex Key below.
//  - Adjacent letters in the word which belong to the same Soundex Key
//    code number are assigned a single digit.
//  - If the end of the word is reached prior to filling 3 digits,
//    use zeroes to complete the code. All codes have only 4 characters,
//    even if the word is long enough to yield more.
//
//    The Soundex Key:
//     1: b p f v
//     2: c s k g j q x z
//     3: d t
//     4: l
//     5: m n
//     6: r
//     no code: a e h i o u y w


// This function computes an "extended" Soundex code of k code characters
// If k<0, the code returned contains as many characters as can be obtained
// from the word by the above rules without adding zeroes at the end.


using namespace std;

string extendedSoundex (const string& word, int k)
{
  //                   "abcdefghijklmnopqrstuvwxyz";
  static const char* keys  = " 123 12  22455 12623 1 2 2";

  string soundexCode;

  char lastCode = ' ';
  for (int i = 0; i < word.size(); ++i)
    {
      char c = word[i];
      //convert to lowercase, if necessary
      if (c >= 'A' && c <= 'Z')
	c += 'a' - 'A';

      if (i == 0)
	// First char of soundex code is the unencoded character
	soundexCode += c;
      else if (c >= 'a' && c <= 'z')
	{
	  // append the soundex character code
	  char soundexChar = keys[c - 'a'];
	  if (soundexChar != lastCode && soundexChar != ' ')
	    soundexCode += soundexChar;
	  lastCode = soundexChar;
	}
    }

  if (k >= 0)
    {
      if (soundexCode.size() > k)
	// truncate code to k characters
	soundexCode = soundexCode.substr(0, k);
      else
	// pad code with zeros
	soundexCode += string(k-soundexCode.size(), '0');
    }

  return soundexCode;
}
Was I correct in the Key / T values being ReplacementChooser / ReplacementChooserData?
 
Old 07-23-2013, 02:52 PM   #4
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 318

Rep: Reputation: Disabled
Quote:
Originally Posted by R2B Boondocks View Post
I believe I only need one instance of it so that I can load the information from a file onto the map. This .cpp doesn't have the main so I don't think I have any other choice than making it global correct?
The comment in the code has your professor asking you to make the multimap collection be a member of ReplacementChooserData. Besides that your teacher has gone to the trouble of controlling how items of the class can be created by hiding its copy operations, so I'd guess if she wanted a singleton (https://en.wikipedia.org/wiki/Singleton_pattern) she would have either designed it that way or made some kind of comment to that effect. Instead you have this: "We can, at a slight cost, however, hide the data structure from the .h file by placing the implementing data structure inside another class/struct, and simply having a pointer to that class/struct in the ADT."

Quote:
Was I correct in the Key / T values being ReplacementChooser / ReplacementChooserData?
No. Read this article or anything else you can find on the pimpl idiom that's more clear to you, and then read your teacher's code and comments again: https://en.wikibooks.org/wiki/C%2B%2...on_.28pImpl.29.

Then think more about what the soundex values would be used for, what multimap provides you, what you might want to look up in your application based on what key to get what value(s).

Perhaps it would be helpful if you wrote the program without the pimpl idiom first, putting the multimap directly into ReplacementChooser. Then when you have that working you could move it over to ReplacementChooserData to fit your professor's structure. I'm not saying it's a bad structure, but maybe the issues of separate compilation and preparing you to engineer for large programs is distracting here from grasping what your program is supposed to be doing.
 
Old 07-23-2013, 04:28 PM   #5
R2B Boondocks
LQ Newbie
 
Registered: Nov 2012
Posts: 16

Original Poster
Rep: Reputation: Disabled
Thank you very much! I will read up on those links and follow your suggestions.
 
Old 07-25-2013, 12:44 PM   #6
R2B Boondocks
LQ Newbie
 
Registered: Nov 2012
Posts: 16

Original Poster
Rep: Reputation: Disabled
I've thought of a new route.

Code:
#include "replchoices.h"
#include "edit1.h"
#include "soundex.h"

#include <algorithm>
#include <map>

using namespace std;

// This class implements a policy for choosing "plausible"
// replacements for a misspelled word. Many such policies are possible.
// For example, we might choose words from the system dictionary that
// "look like" the misspelled word, or words from the system dictionary that
// "sound like" the misspelled word, or some combination of these.
//

 typedef multimap<string, string> my_map; //have a blank multimap of types stringx2 and load ReplacementChooser etc onto it.
 typedef multimap<string, string>::const_iterator it;
 my_map extendedSoundex(); //Will become key value of my_map

 struct ReplacementChooserData
 {
/*!!
  This is the data structure for the "off-by-one-character"
  suggestion strategy.  You will want to replace this data members
  here by a multimap that maps soundex codes to words having that
  soundex.  Then rewrite the function bodies below accordingly.
 !!*/
  const ReplacementChooser::Dictionaries& dict;

  ReplacementChooserData(const ReplacementChooser::Dictionaries& d): dict(d) {}


 };



ReplacementChooser::ReplacementChooser(const Dictionaries& dictionary)
{
   d = new ReplacementChooserData(dictionary);
   my_map::insert(extendedSoundex(stuff?), d); //to load the multimap 

}

ReplacementChooser::~ReplacementChooser()
{
  delete d; //destructor
}


// Choose some number of "plausible" replacements for the given word,
// returning them in the order we want them listed to the user.
vector<string> ReplacementChooser::getPlausibleReplacements    //Will handle this later
  (const string& word) const
{
  vector<string> replacements;
  

  for (Dictionaries::const_iterator w = d->dict.begin();
       w != d->dict.end(); ++w)
    {
      if (oneEditAway(word, *w))
	replacements.push_back (*w);
    }

  return replacements;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
multimap with > 1 million entries = problems? true_atlantis Programming 14 09-11-2008 11:23 PM
Useradd not creating home directory when creating newuser meneedham Linux - Newbie 4 10-05-2007 12:11 PM
Creating a bootable cd zirtik Linux - Software 1 12-03-2005 02:16 PM
Creating a RAID jdozarchuk SUSE / openSUSE 1 02-10-2005 12:13 PM
Creating CD's badogg Mandriva 2 05-18-2004 10:25 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration