Shreeyash Shrestha
Shreeyash Shrestha

Reputation: 174

Replacing the value of map elements isnt working

I'm just Learning about std::map and its functions . I recently got this problem. I tried making a program which prints out a grid type data where I used std::map for the keys and values . The program prints out fine but I wanted to make a program where once I erased a data in that grid, other data above that should move down one step and the topmost would have 0 in it . somehow I tried but it doesn't seem to work . I don't know where I did wrong in that . My code:

#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<map>

#define x_Pair std::pair<unsigned int,unsigned int>
class MapCheck
{

public:
    std::map<x_Pair, unsigned int>m_MapData;

    void SetMapData();

    x_Pair GetBlockCell(int num);
    void EraseCell(int cell);

};

void MapCheck::SetMapData()
{
    int count = 1;
    for (int j = 0; j < 20; j++)
    {
        for (int i = 0; i < 10; i++)
        {
            m_MapData[{i, j}] = count;
            count++;
        }
    }
}

x_Pair MapCheck::GetBlockCell(int num)
{
    for (int j = 0; j < 20; j++)
    {
        for (int i = 0; i < 10; i++)
        {
            if (m_MapData[{i, j}] == num)
            {
                return x_Pair(i, j);
            }
        }
    }
    return x_Pair(-1, -1);
}

void MapCheck::EraseCell(int cell)
{
    x_Pair pair = GetBlockCell(cell);

    for (int i = pair.second; i < 20; i++)
    {
        m_MapData[{pair.first, i}] = m_MapData[{pair.first, i - 1}];
        m_MapData[{pair.first, i - 1}] = 0;
    }

}

-and in main:

#include"MapCheck.h"

int main()
{
    MapCheck mc;
    mc.SetMapData();

    std::string input;

    do
    {
        system("cls");
        for (int j = 0; j < 20; j++)
        {
            for (int i = 0; i < 10; i++)
            {
                std::cout << mc.m_MapData[{i, j}] << "      ";
            }
            std::cout << std::endl;
        }
        std::cout << "Enter a number to erase or E to exit";
        std::cin >> input;
        mc.EraseCell(std::atoi(input.c_str()));
    } while (input != "E");
    return 0;
}

the output without any inputs : this

after entering number 191 in the input : enter image description here

expected result: enter image description here

All Except the printing is fine . I dont Get Where I did Wrong. Any help would be appreciated. Thanks in advance!!

Upvotes: 0

Views: 142

Answers (2)

user7571491
user7571491

Reputation:

You have following:

x_Pair MapCheck::GetBlockCell(int num) which is used as x_Pair pair = GetBlockCell(cell);

This will invoke copy constructor of std::pair<>.

I think you need to return and use reference:

x_Pair& MapCheck::GetBlockCell(int num) which is used as x_Pair& pair = GetBlockCell(cell);

Upvotes: 0

user4581301
user4581301

Reputation: 33982

The order of

    for (int i = pair.second; i < 20; i++)
    {
        m_MapData[{pair.first, i}] = m_MapData[{pair.first, i - 1}];
        m_MapData[{pair.first, i - 1}] = 0;
    }

is element found to the bottom. When you want to move everything above the item removed down one slot, this isn't all that useful. So lets flip it around.

    for (int i = pair.second; i > 0; i--)
    {
        m_MapData[{pair.first, i}] = m_MapData[{pair.first, i - 1}];
    }
    m_MapData[{pair.first, 0}] = 0;

This starts at the item being removed and goes up to slot 1, copying each item down one slot. To handle the top of the column, we have m_MapData[{pair.first, 0}] = 0; to set the top item to zero, something we only need to do once.

Side note: Unless we have a sparse array, this would be a lot more efficient with a 2D array in place of the map.

Upvotes: 1

Related Questions