0

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:

  • in class header:
#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);

};
  • in class cpp:

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!!

  • Typo: `if (m_MapData[{i, j}] = num)` -> `if (m_MapData[{i, j}] == num)` – user4581301 Jun 29 '21 at 02:56
  • By the way, what's wrong? What output do you expect? For all I know I just picked off the bug you need to solve in the comment above and there's no way for me to know. – user4581301 Jun 29 '21 at 02:58
  • Sorry I was editing that function just a minute ago – Shreeyash Shrestha Jun 29 '21 at 03:02
  • Groovy. Could you add a sample input, the expected output and the output you receive to the question? This will help clarify everyone's understanding of the problem. – user4581301 Jun 29 '21 at 03:04
  • wait a minute i will edit now – Shreeyash Shrestha Jun 29 '21 at 03:05
  • Just Edited Please check now – Shreeyash Shrestha Jun 29 '21 at 03:12
  • Thank you. I see what you want to do now. Suggestion: If you step through this function with a with a debugger and watch what the program does as it does it, you'll probably figure out what went wrong and how to fix it before anyone can write up a good answer. Mind you, to do that quickly you should reduce the size of the array to 4x4 or something smaller. This means you would have to replace a bunch of 10s and 20s in the code, leading to a side note: [What is a magic number, and why is it bad?](https://stackoverflow.com/questions/47882) – user4581301 Jun 29 '21 at 03:24

2 Answers2

1

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.

user4581301
  • 33,082
  • 7
  • 33
  • 54
0

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

Nimantha
  • 6,405
  • 6
  • 28
  • 69