-3

All the examples of multimap, yet to find a multi-dimensional example...

System: Visual Studio 2019, C++. Winapi with no extra libraries Expected result: stores a multi-dimensional array of key/value pairs. Able to pull up a key pair by specifying parent key pairs (similar to hashes in Perl)

Using multimap instead of map since some of the fields have the same header. Example of my data:

conversationID(int)
 |
 ConversationType(wstring)
 lineID(int)
    |
     lineType(wstring)
     originalLine(wstring)
     taggedLine(wstring)
     wordID
        |
    ...

Declare the structure:

#include <map>
multimap< int, multimap <int, multimap <wstring, multimap <wstring, multimap <wstring, multimap<wstring, wstring> > > > > > conversation;                        
multimap< int, multimap <int, multimap <wstring, multimap <wstring, multimap <wstring, multimap<wstring, wstring> > > > > > ::iterator conversationIt;         

Try to store some stuff in it... (error: "no instance of overloaded function")

conversation.insert(make_pair<int,int>(2, 1 make_pair<wstring, wstring>(L"originalLine", line)));

Also tried the following but found that multimap does not support [] insert:

conversation[0][0][L"originalLine"][line];
IInspectable
  • 46,945
  • 8
  • 85
  • 181
kbaud
  • 25
  • 7
  • 3
    You forgot to ask a question. Please take the [tour] and read [ask]. – IInspectable Aug 06 '20 at 21:58
  • The fact that the compiled code has to conform to the data structure is quite a code smell. Even just nesting six container deep would be problematic IMO. I'd suggest you consider something lighter, unless you are after the inception-movie style. – Jeffrey Aug 06 '20 at 22:02
  • I'm not sure multimaps of multimaps even make sense. If I want to add or use M[x][y], but `M` contains multiple submaps with key `x`, which should I add to / look in with key `y`? – aschepler Aug 06 '20 at 22:09
  • If you want to use pairs or tuples as keys, you can, but just declare it that way: `std::map,`... – aschepler Aug 06 '20 at 22:09
  • Thanks. I know I am stating the obvious that I have a lot to learn about multimap but then I wouldn't have posted my problem if that were not the case. I have been reading about "multimap in a multimap", which might be the ticket. Also looked at hash, sets, arrays of arrays, classes, etc. Each level that can have multiple variables hanging off it would be another multimap. Sometime like: map1 (conversation(int), line(int)) map2 (map1, conversation type(wstring)) map3 (map1, lineID(int)) map4 (map1:lineID, lineType(wstring)) how to connect part of a multimap to another multimap. – kbaud Aug 06 '20 at 22:40
  • how's this? have the same variable used more than once across multiple multimaps? map1: conversationID, type map2: conversationID, lineID map3: lineID, type map4: lineID, wordID – kbaud Aug 06 '20 at 22:59
  • To search for a given field, the maps would be navigated until the target map and key are found. Then that target map is queried with that key to return the desired value. I would be surprised if there was not already some pre-existing structure for this. – kbaud Aug 06 '20 at 23:02
  • The way I understood your description, you don't need multimap. A plain map would do. Plain map can be nested, too. But then, I don't see why do you want to nest them. A single map with your custom structure type as a key would do, provided you define strict ordering for that structure type. But I may be missing your point since I don't quite understand what are all those `conversationID(int)`, `lineType(wstring)` etc. – Igor G Aug 06 '20 at 23:51

1 Answers1

0

Based on the tree diagram above, the best approach is a simple multidimensional array.

  • this allows for duplicate "keys"
  • mixed variable types can be achieve by using supporting tables (see example below)

Compared to other methods:

  • map does not allow duplicate keys
  • multimap. could not get this to work. tried for weeks.
  • class inheritance. does not link sub branches to branches above. it is just a method for exposing variables and methods without having to duplicate your work.
  • also looked at multisets, vectors, etc.

note: for a large multidimensional array, you will need to use heap memory.

void conversationArray(LPWSTR line)
    {
        auto conversation = new int[5][10000][100][50];       // conversationID, lineID, objectID, tagid = tag/text
        wstring conversationType[3];
        auto lineType = new wstring[5][10000];                // conversationID, lineID = string
        wstring text[50];
    
        conversationType[0] = L"chat gui";
        lineType[0][0] = L"chat";
        conversation[0][0][14][12] = 25;
        conversation[0][0][15][12] = 30;
        lineType[0][1] = L"chat1";
        conversation[0][1][15][12] = 500;
        lineType[0][2] = L"chat2";
        conversation[0][2][15][12] = 60;
    
        conversationType[1] = L"chat gui1";
        lineType[1][0] = L"chat-also";
        conversation[1][0][15][12] = 33;
        
        // if tag id = 0 then tag is text
        conversation[0][0][14][0] = 0;
        conversation[0][0][15][0] = 20;
        text[0] = line;
        text[20] = L"dog";
    
        // print out
        int records = 0;
        for (int conversationID = 0; conversationID < 5; conversationID++)
        {
            //sendToReportWindow(L"conversationID: %d\n", conversationID);
    
            for (int lineID = 0; lineID < 10000; lineID++)
            {
                //sendToReportWindow(L"lineID:%d\n", lineID);
    
                for (int objectID = 0; objectID < 100; objectID++)
                {
                    //sendToReportWindow(L"objectID:%d\n", objectID);
    
                    for (int tagID = 0; tagID < 50; tagID++)
                    {
                        if (conversation[conversationID][lineID][objectID][tagID] >= 0)
                        {
                            if (tagID > 0)
                            {
                                sendToReportWindow(L"conversationID:%d type:%s\n", conversationID, conversationType[conversationID].c_str());
                                sendToReportWindow(L"lineID:%d type:%s\n", lineID, lineType[conversationID][lineID].c_str());
                                sendToReportWindow(L"conversation[%d][%d][%d][%d]= %d\n", conversationID, lineID, objectID, tagID, conversation[conversationID][lineID][objectID][tagID]);
                                sendToReportWindow(L"\n");
    
                            }
                            else
                            {
                                sendToReportWindow(L"conversationID:%d type:%s\n", conversationID, conversationType[conversationID].c_str());
                                sendToReportWindow(L"lineID:%d type:%s\n", lineID, lineType[conversationID][lineID].c_str());
                                sendToReportWindow(L"conversation[%d][%d][%d][%d] text = %s\n", conversationID, lineID, objectID, tagID, text[conversation[conversationID][lineID][objectID][tagID]].c_str());
                                sendToReportWindow(L"\n");
                            }
                            records++;
                        }          
                    }
                }
            }
        }
        sendToReportWindow(L"records:%d\n", records);
        sendToReportWindow(L"\n");
    
        // print all records on a specific branch. all lines for conversation 1, line 0
        int conversationID = 1; int lineID = 0;
        sendToReportWindow(L"Just print a subset of conversation:%d and Line:%d\n", conversationID, lineID);
    
        for (int objectID = 0; objectID < 100; objectID++)
        {
            for (int tagID = 0; tagID < 50; tagID++)
            {
                if (conversation[1][0][objectID][tagID] >= 0)
                {
                    if (tagID > 0)
                    {
                        sendToReportWindow(L"conversationID:%d type:%s\n", conversationID, conversationType[conversationID].c_str());
                        sendToReportWindow(L"lineID:%d type:%s\n", lineID, lineType[conversationID][lineID].c_str());
                        sendToReportWindow(L"conversation[%d][%d][%d][%d]= %d\n", conversationID, lineID, objectID, tagID, conversation[conversationID][lineID][objectID][tagID]);
                        sendToReportWindow(L"\n");
    
                    }
                    else
                    {
                        sendToReportWindow(L"conversationID:%d type:%s\n", conversationID, conversationType[conversationID].c_str());
                        sendToReportWindow(L"lineID:%d type:%s\n", lineID, lineType[conversationID][lineID].c_str());
                        sendToReportWindow(L"conversation[%d][%d][%d][%d] text = %s\n", conversationID, lineID, objectID, tagID, text[conversation[conversationID][lineID][objectID][tagID]].c_str());
                        sendToReportWindow(L"\n");
                    }
                }
            }
        }
    
        delete[] conversation; delete[] lineType;
    }
kbaud
  • 25
  • 7