Map with an array as the value type?

Jun 18, 2010 at 12:21am
Basically, I need to know if I can have a one-dimensional array as a value type in a map. Here's some basic code that kind of resembles what I'm doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <map>
 
using namespace std;
 
int main()
{
    map<string, int> wordcounts;
    string s;
 
    while (cin >> s && s != "end")
        ++wordcounts[s];
 
    while (cin >> s && s != "end")
        cout << s << ' ' << wordcounts[s] << '\n';
}


This basically has a user enter words, stores how many times each word has been entered into a map, and then prints out the word and how many times it was entered.
What I would want is for a user to be able to enter sentences and then be able to distinguish how many times a the person entered a word in a particular sentence. What I was thinking of for code is the following:

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
#include <iostream>
#include <string>
#include <map>

using namespace std;
 
int main()
{
    map<string, int[5]> wordcounts;
    string s;
    int sentence[5];
 
    while (cin >> s && s != "end")
    {
      for(int i = 0; i < 5; i++)
      { sentence[i];
        while (cin >> s && s != "/n")
          wordcounts[s]++;  //error here
      }
    }

 
    while (cin >> s && s != "end")
        cout << s << ' ' << wordcounts[s] << '\n';
}


However, I get an error message with this that says:
error C2105: '++' needs l-value

I tried changing the error line of code to:
wordcounts[s][i]++;

And get the following error message:
c:\program files\microsoft visual studio 9.0\vc\include\map(173) : error C2440: '<function-style-cast>' : cannot convert from 'int' to 'int [5]'
There are no conversions to array types, although there are conversions to references or pointers to arrays
c:\program files\microsoft visual studio 9.0\vc\include\map(168) : while compiling class template member function 'int (&std::map<_Kty,_Ty>::operator [](const std::basic_string<_Elem,_Traits,_Ax> &))[5]'
with
[
_Kty=std::string,
_Ty=int [5],
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\documents and settings\bakerkar\my documents\visual studio 2008\projects\mapattempt\mapattempt\maptry.cpp(9) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=std::string,
_Ty=int [5]
]


Does this mean I cannot have an array as a value type for a map?






Here's some more information on what I'm actually trying to do just in case you think there might be a better way of doing this:

I need to count how many times each word appears in each sentence in a document (capitalization does not matter, punctuation is disregarded, and each sentence occupies its own line). Let’s say my document contained the following:

The dog jumped
My friend ate
My friend jumped

I should, after running my program, have a matrix that looks something like:


the, 1, 0, 0
dog, 1, 0, 0
jumped, 1, 0, 1
my, 0, 1, 1
friend, 0, 1, 1
ate, 0, 1, 0

As you can probably tell, the first column corresponds to the first sentence, the second column to the second sentence, etc.

I was told that the best way to go about this is a hash table (or, in the case of C++, a map). My instructor told me this would be a better option than an array because our documents are rather large and the matrix will be rather sparse.

Jun 18, 2010 at 12:46am
Use a vector instead of an array and you should have no more problems.
Jun 18, 2010 at 1:13am
I've never used vectors before, but I attempted it and I guess I failed.
I tried updating the sample code I gave above using the vector suggestion before putting it in my actual project:

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
#include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;
 
int main()
{
    map<string, vector<int> > wordcounts;
    string s;
    vector<int> sentence;
 
    while (cin >> s && s != "end")
    {
      for(int i = 0; i < 5; i++)
      { sentence[i];
        while (cin >> s && s != "/n")
          wordcounts[s][i]++; 
      }
    }

 
    while (cin >> s && s != "end")
    {
      for(int i = 0; i < 5; i++)
      { sentence[i];
        while (cin >> s && s != "/n")
         cout << s << ' ' << wordcounts[s][i] << '\n';
      }
        
    }
}



It compiled just fine, but I got the following error message at runtime after entering my first string:

Debug Assertion Failed!

Program: …s\Visual Studio 2008\Projects\mapAttempt\Debug\mapAttempt.exe
File: c:\program files\microsoft visual studio 9.0\vc\include\vector
Line: 779

Expression: vector subscript out of range

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

Last edited on Jun 18, 2010 at 1:14am
Jun 18, 2010 at 9:22am
Your vector's size() is 0. You can resize your vector by push_back()-ing items, or by calling the appropriate constructor vector<int> sentence(5);, or by calling the resize() member function.
Jun 18, 2010 at 11:08am
you are making life very difficult.
you don't need an array, just a word and a count:
(If i understand you correctly)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <map>
using namespace std;

typedef map<string, int> mapper; // i like typedefs

int main(int argc, char ** argv) {

    string s;
    mapper m;

    while ( cin >> s ) {
        m[s]++;
    }
    mapper::iterator p = m.begin();
    mapper::iterator end = m.end();

    for( ;p != end; ++p ) {
        cout << p->first << ":" << p->second << endl;
    }

    return 0;
}


now go and study how map and pair work!
Last edited on Jun 18, 2010 at 11:09am
Jun 18, 2010 at 8:33pm
@R0mai

I set the size by using your vector<int> sentence(5); suggestion but still got the same error.

@bigearsbilly

I am not sure that you understand what I'm trying to do.
For this code, a user enters a sentence. The user presses enter. This sentence should store each word as a key in the map and an integer for how many times the key was in that sentence in the vector. Then the user enters another sentence, presses enter; if a word is repeated from the first sentence, it should find that key and add the number of times it was found in that sentence into the vector.... etc etc.... until the user enters "end". Then the program should print out the key and the corresponding vector:
(Word_1) (# of occurrences in sentence_1) (# of occurrences in sentence_2)...(# of occurrences in sentence_n)
.....
(Word_n) (# of occurrences in sentence_1) (# of occurrences in sentence_2)...(# of occurrences in sentence_n)


If I'm understanding your code correctly (couldn't actually get it to work, there was a compiler error:
error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
), but it seems like yours is just counting the total number of times the word occurs and not how many times it occurs in each sentences as follows:
(Word_1)(# of occurrences in sentence_1+sentence_2+...+sentence_n)
...
(Word_n)(# of occurrences in sentence_1+sentence_2+...+sentence_n)
Jun 18, 2010 at 11:20pm
ok I get you, apologies.
Jun 19, 2010 at 3:30am
Got it working properly... code ended up looking -completely- different from what's on here haha.
Thanks for the help though =)
Topic archived. No new replies allowed.