mapping help!!!

I am trying to insert multiple elements into the same map...they will be stored using a keyword(string), and an address to the map...the map looks like this...

the Exp* is an inherited class, that can store either a string or a sequenece of strings...

I am wanting help figuring out how to insert multiple elements, which I have stored in a vector, into the same map...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 map<string, Exp*> keyword_map;

for(int i = 0; i < token_terminal_vector.size(); i++){
                        cout<<"token: " << i << ": " << token_terminal_vector[i]->getString() << endl;
                        token_choice->addExpression(token_terminal_vector[i]);
                        
                        keyword_map.insert(it, std::pair<string, Exp*>(keyword_in_text, token_choice));
                        
                        choice_vector[x]->addExpression(token_terminal_vector[i]);
                  }

for(it = keyword_map.begin(); it != keyword_map.end(); ++it){
                        
                      cout<<"it first: " << it->first << " => " << it->second << endl;
                        
                        
                     
}


The following code only gives me one of the values that I am trying to store in the map...

how can I store multiple values using the same keyword? I think the proper question is...how do I multi-map?
Last edited on
how do I multi-map?
By using std::multimap instead of std::map  
http://en.cppreference.com/w/cpp/container/multimap
At line 7, it looks like you are inserting the same value over and over again. Do keyword_in_text and token_choice change during the loop? If so then please post the full code.

And what about it? Does it change during the loop? Line 7 would be clearer if written as keyword_map[keyword_in_text] = token_choice;

Perhaps you're looking for a multimap? A map can only store one item for each index value. If you try to insert a second item with a duplicate index value, the new item replaces the old one.
you guys are great...i figured out the multi-map thing...I am now trying to bracket match and pull out the word in between brackets '< string >'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
                  int c = 0;
                  int v = 1;
                  int v2 = 1;
                      for(int i = 0; i < token_as_string.length(); i++){
                            if(token_as_string[i] == '<'){
                              while(token_as_string[c+1] !='>'){
                                c++;
                              }
                              while(token_as_string[v] != '<'){
                                v++;
                              }

                              while(token_as_string[v2] != '>'){
                                v2++;
                              }
                              //terminal_inside_string = token_as_string.substr(c+2, v2-2);
                              key_word_in_string = token_as_string.substr(i+1, c);
                              cout<<"key word in string: " << key_word_in_string << endl;
                              //cout<<"terminal in string: " << terminal_inside_string << endl;

                            }
                              
                      }


then, I will try to use the map to fill in the values stored in the multimap to replace the keywords found in between the '< string >'....

any ideas to improve my attempt?

My current code works if the first word on the line is a keyword, meaning it is in the format '< string>' , but if the line is in this format:

I <keyword> <keyword> and so it doesn't work.

I am stumped as to why it works for one line, but not all cases...

this is my current output:

1
2
3
4
5
6
7
8
9
10
11
12
13


Token sequence: <animal> and <animal> 
key word in string: animal
key word in string: animal
token_copy [3]: start:My <animal> <adverb> ran out the <portal> .
keyword: start
token: 0: My <animal> <adverb> ran out the <portal> .
token sequence: My <animal> <adverb> ran out the <portal> . 
key word in string: animal> <
key word in string: adverb> r
key word in string: portal> .
Last edited on
does anyone have a solution to why my values aren't changing for the variable inside my for loop?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

Choice* token_choice = new Choice();
Sequence* token_sequence = new Sequence();
vector<Choice*> choice_vector;
vector<Keyword*> key_word_vector;
vector<Sequence*> token_sequence_vector;
int x = 0;

    while(!file2.eof()){
                  
              char buf[MAX_CHARS_PER_LINE];
              file2.getline(buf, MAX_CHARS_PER_LINE);
              int n = 0;
              const char* token[MAX_TOKENS_PER_LINE]= {};
              token[0] = strtok(buf, DELIMITER);
              if(token[0]){
                    for(n = 1; n < MAX_TOKENS_PER_LINE; n++){
                          token[n] = strtok(0, DELIMITER);
                          if(!token[n])
                                break;
                    }

              }

              
              for(int i = 0; i < n; i++){
                  //cout<<"token ["<<i<<"]: " << token[i] << endl;
                  token_copy.push_back(token[i]);

              }
             // cout<< endl;

      }

            for(int i = 0; i < token_copy.size(); i++){
                  cout<<"token_copy ["<<i<<"]: " << token_copy[i] << endl;
                  string token_as_string;

                  token_as_string = token_copy[i];
                  
                  size_t pos= token_as_string.find(':');
                  //int count = 0;

        
                  if(pos != string::npos){
                        string keyword_in_text = token_as_string.substr(0, pos);
                        stored_keywords_vector.push_back(keyword_in_text);//keywords vector
                        cout<<"keyword: " << keyword_in_text << endl;
                        //stored_lines_vector.push_back(text_file_line.substr(pos + 1));//lines vector after colon extracted

                        Keyword* text_keyword = new Keyword(&keyword_map, keyword_in_text);
                        Keyword* text_keyword2 = new Keyword(&keyword_map2, keyword_in_text);
                        key_word_vector.push_back(text_keyword);
                        token_as_string = token_as_string.substr(pos + 1);
                        //cout<<"token as string1: " << token_as_string <<  endl;
                        //keyword_map[keyword_in_text] = parse(&keyword_map, stored_lines_vector[loop_count]);

                        //if(token_as_string[i] == ':'){
                          //  Keyword* = new Keyword(&keyword_map, token_copy.substr(0, loc));
                  }

                  pos= token_as_string.find('|');
                  vector<Terminal*> token_terminal_vector;                  

                        
                  while(pos != string::npos){
                        //cout<<"token as string2: " << token_as_string.substr(0, pos) << endl;
                        //Terminal* some_choice = new Terminal(token_as_string.substr(0, pos));
                        //token_terminal_vector.push_back(some_choice);
                        token_terminal_vector.push_back(new Terminal(token_as_string.substr(0, pos)));
                        //token_choice->addExpression(some_choice);
                        token_as_string = token_as_string.substr(pos + 1);
                        //cout<<"token as string: " << token_as_string << endl;
                        pos = token_as_string.find('|');
                        //keyword_map[keyword_in_text] = parse(&keyword_map, stored_lines_vector[loop_count]);
                       // keyword_map.insert(it, std::pair<string, Exp*>(keyword_in_text, token_terminal_vector[i]));

                        //if(token_as_string[i] == ':'){
                          //  Keyword* = new Keyword(&keyword_map, token_copy.substr(0, loc));
                  }

                  if(pos == string::npos){
                    token_as_string = token_as_string.substr(0, pos);
                    //Terminal* some_choice = new Terminal(token_as_string);
                    //token_terminal_vector.push_back(some_choice);
                    token_terminal_vector.push_back(new Terminal(token_as_string));
                    //keyword_map.insert(it, std::pair<string, Exp*>(keyword_in_text, token_terminal_vector[i]));
                    //cout<<"token as string 3: " << token_as_string << endl;

                  }
                  //map<string, Exp*> keyword_map;
                  //cout<<"token terminal size: " << token_terminal_vector.size() << endl;
                  choice_vector.push_back(new Choice());
                  for(int i = 0; i < token_terminal_vector.size(); i++){
                        cout<<"token: " << i << ": " << token_terminal_vector[i]->getString() << endl;
                        cout<< endl;
                        //keyword_map.insert(it, std::pair<string, Exp*>(keyword_in_text, token_terminal_vector[i]));
                        token_choice->addExpression(token_terminal_vector[i]);
                        choice_vector[x]->addExpression(token_terminal_vector[i]);
                        cout<<"token choice inside for: " << choice_vector[x]->getString() << endl;
                        keyword_map2.insert(it2, std::pair<string, Exp*>(stored_keywords_vector[x], choice_vector[x]));


                        if(i+1 == token_terminal_vector.size()){
                            //token_sequence->addExpression(token_terminal_vector[i]);
                            token_sequence_vector.push_back(new Sequence());
                            //token_sequence_vector[x]->addExpression(token_terminal_vector[i]);
                            //token_sequence_vector[x]->addExpression(choice_vector[x]);
                        }
                        
                  }
                  cout<< endl;

                  cout<<"token choice outside for: " << choice_vector[x]->getString() << endl;



this is the output:


1
2
3
4
5
6
7
8
9
10

token choice inside for: quickly
token: 1: stealthily

token choice inside for: quickly
token: 2: 

token choice inside for: quickly

token choice outside for: stealthily
Last edited on
It is really hard to tell without complete code and with such code. Consider separating it into several functions whch do one seprate thing. For example reading data from file and separating string into '|' deleimeted tokens are primary candidates for being own functions.

General rule: if function is larger than 30 lines of code, it should be broken in several separate functions.
Topic archived. No new replies allowed.