Search code examples
c++multidimensional-arraymultimap

Are multi-dimensional multi maps possible?


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];

Solution

  • 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;
        }