Problem in choosing data structure

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tonyaim83
    New Member
    • Dec 2007
    • 4

    Problem in choosing data structure

    Hi...
    My input file is as follows :-
    A<-B<-C<-D
    A<-C<-E<-F<-P
    .......
    .....

    What i want is to first store the given input as follows :-
    {{{A,B},{B,C},{ C,D}},{{A,C},{C ,E},{E,F},{F,P} }}
    and then make a check if the pair is present in particular subset of a set.
    For e.g if the user can give index 0 and pair {B,C} we need to search the first index value i.e {{A,B},{B,C},{C ,D}} and return true or false based on its presence.
    Till now my code is as follows which reads each line of the given file and retrieve the element values by using tokenizer of boost lib. How to proceed further i tried using vector and map for storing in the above format but it is not helping me much.
    In case of any doubts on the problem statement kindly let me know that
    Kindly help




    Code:
     
                    void main(int argc,char* argv[])
     
                     std::ifstream datafile(argv[1]);
                      if (!datafile) 
                         {
                          std::cerr << "No " << datafile << " file found" << std::endl;
                             exit(1);
                          }
                          int line_no=0;
                          string first_element;
                          string second_element;
                          int count=0;
                          char_delimiters_separator < char >sep(false, "", "<-");
                          for (std::string line; std::getline(datafile, line);)
                              {
                               tokenizer <> line_toks(line, sep);
                               tokenizer <>::iterator iter = line_toks.begin();
                               line_no++;
                               if (line_toks.begin() == line_toks.end()) 
                                   continue;
                              
                               for(;iter!=line_toks.end();iter++)
                                  {
                                   if(count==0)
                                     { 
                                       first_element=*iter;
                                       count++;
                                       continue;
                                     }
                                    else
                                       {
                                         second_element=*iter;
                                        } 
                                         first_element=second_element;
                                   
                                        /*******
                                          Now i got the values of first element and second  element correctly how to store it and retrieve in the above mentioned structure 
                                       ***********/                     
        
                                     count++;
                                    }//End-for --i 
                               
                               }//End-for getline
  • DumRat
    New Member
    • Mar 2007
    • 93

    #2
    You can use a vector of maps to store your data. But you have to organize the data into a structure I guess.

    ex:

    Code:
    struct TwoLetters
    {
       char first;
       char second;
    
       //Overload the operator < or > here. There's another way with a function, but I haven't tried it. Let's say that you overloaded the < (less operator).
    };
    Now, you have a way of comparing two structs.


    Code:
    //try a map.
    typedef map<TwoLetters, int, less<TwoLetters> > MyMap;
    typedef map<TwoLetters, int, less<TwoLetters> >::iterator MyIterator;
    
    //create the vector
    vector<MyMap*>* v;
    Now you can check if a certain line has the combination {S,Z} by,

    Code:
    //The wanted element
    TwoLetters tLetters = {'S', 'Z'};
    
    //The wanted line
    int line = wantedLine;
    
    //Get the relevant map
    MyMap* wantedMap = (*v)[wantedLine];
    
    //Find element
    MyIterator it = wantedmap->find(tLetters);
    if the element is in the map, it points to the element (pair). If not, it points to the end of the map. You can check it and find this out. Hope it helped.

    DumRat

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      Originally posted by DumRat
      You can use a vector of maps to store your data. But you have to organize the data into a structure I guess.

      ex:


      Code: ( text )
      struct TwoLetters
      {
      char first;
      char second;

      //Overload the operator < or > here. There's another way with a function, but I haven't tried it. Let's say that you overloaded the < (less operator).
      };
      The map requires a pair<> conrtainer for the entries.

      [code=cpp]
      pair<char, char> data;
      [/code]

      Here data.first is the lirst letter and data.second is the second letter.

      The map would be:
      [code=cpp]
      map<char, char> theMap;
      [/code]

      In the map data.first is the key and data.second is a value associated woith that key.

      If this does not fit your data model, then don't use a map.

      Comment

      • DumRat
        New Member
        • Mar 2007
        • 93

        #4
        WeaknessForCats << On the above problem I guess your method is the best. But say the set of character pairs are like this :

        {A,B}, {A,E}, {A,F}, {C,K}, {C, G}, ....

        Now can a map be used in the way you have indicated?

        Comment

        • Laharl
          Recognized Expert Contributor
          • Sep 2007
          • 849

          #5
          You could use a single map there, a map<char, char>, assuming your desire is to get the second character if the first is inputted.

          Comment

          • DumRat
            New Member
            • Mar 2007
            • 93

            #6
            Originally posted by Laharl
            You could use a single map there, a map<char, char>, assuming your desire is to get the second character if the first is inputted.
            Suppose you want to check if there's a certain character pair {X,Y} in the map?

            Comment

            • Laharl
              Recognized Expert Contributor
              • Sep 2007
              • 849

              #7
              At that point...since a map's [] give you the value, you can check if the second value appears when you put in the first. Or you could use a vector<pair<cha r> >, I guess.

              Comment

              • DumRat
                New Member
                • Mar 2007
                • 93

                #8
                Originally posted by Laharl
                At that point...since a map's [] give you the value, you can check if the second value appears when you put in the first. Or you could use a vector<pair<cha r> >, I guess.
                But this is the point. Say u have

                {A,B}, {A,C}, etc.

                If u use the first character as the key, you can only have one of these in the map. So u can't use a map like that. The other alternative is to use a multimap - but then, if you had 25 pairs starting with A, you'd have to traverse through that entire 25 elements to find your element - which is inefficient. The best method then is to use both the characters combined as the key. That's what I did in my first post.

                Comment

                Working...