Erasing an element from Vector<Vecter<short>>

Hello,
I ask if any one knows how it is possible to erase a random element in the vector< vector< cell> >?

Also, I would appreciate help with the verify function to check order of the Sudoku game.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
 #define DEBUG
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <algorithm>
#include <vector>

using namespace std;

class cell{
	bool m_occu; //occupied is shown '.'
	int m_num;

public:
	cell() : m_occu(false), m_num(0) {}
	void setMark(const int num){m_num = num; m_occu = true;}
	bool isMarked() const { return m_occu; }
	int getNum(){ return m_num;}
	friend ostream& operator << (ostream& o, const cell& c){
		if (!c.m_occu) return o << setw(2) << '-';
		return o << setw(2) << c.m_num;
	}
};

class board {
	vector<vector <cell> >m_map;
	bool col_row;

public:
	board() {
		vector<cell> a_row(9);
		col_row = false;
for (int i = 0; i < 9; ++i)
		{
			for(int j = 0; j < 9; j++)
			{
				a_row[j].setMark(j+1);
			}
			random_shuffle(a_row.begin(), a_row.end());
			m_map.push_back(a_row);
		}
	}

	void erase(){

	}

	bool verify()
	{
		// check rows
		int compareNUM = 0;
		for(int row = 0; row < 9; row++)
		{
			for (int col = 0; col < 9; col++)
			{
				compareNUM = m_map[row][col].getNum();

				// compares first element in every row with every other element in the same row.
				// However, issue is comparing compareNUM variable to itself in this loop.
				// come up with condition to handle comparison to itself. Will always return false
				// if  not handled.
				for(int iter = 8 - col; iter <= 8; iter--)
				{
					if(compareNUM == m_map[row][iter].getNum())
					{
						return false;
					}
				}

			}
		}

		//check cols
	}

	bool setMark(const int num, const int r, const int c){
		if (m_map[r][c].isMarked()) return false;
		m_map[r][c].setMark(num);

		return true;
	}
	void swap(){

		int src = rand()%9;
		int dst = rand()%9;

		while (src == dst)// make sure that src and dst are different
		{
			dst = rand()%9;
		}

	if (col_row == false)//swap rows
	{
		m_map[src].swap(m_map[dst]);
		cout<<"Rows Switched"<<endl;
		col_row = true;
	}
	else				// swap columns
	{
		cell hold;
		for(int j = 0; j < 9; j++)
		{
			hold = m_map[j][src];
			m_map[j][src] = m_map[j][dst];
			m_map[j][dst] = hold;
		}
		cout<<"columns switched"<<endl;
		col_row = false;
	}

	}

	bool isMarked(const int r, const int c) const {return m_map[r][c].isMarked();}

	friend ostream& operator << (ostream& o, const board& b){
			cout << "  ";
			for (int col = 0; col < 9; ++col) o << setw(2) << char('A' + col);
			o << endl;
			for (int row = 0; row < 9; ++row){
				o << setw(2) << char('P' + row);
				for (int col = 0; col < 9; ++col) o << b.m_map[row][col];
				o << endl;
			}
			return o;
		}

};



int main() {
	board b;
	string command;
	cout<<"Welcome to Sudoku Initializer!"<<endl;


	while(true)
	{
		cin>>command;
		if (command == "show") cout << b << endl;
		else if (command == "swap") b.swap();
		else if (command == "verify")cout << b << endl;
		else if (command == "erase")cout << b << endl;
		else if (command == "quit")cout << "Bye "<< endl; break;

	}

	return 0;
}
Last edited on
Don't copy this exactly, but it should show you how you can erase an element from a vector.

1
2
3
4
5
template<typename T>
void eraseElementInVector(int index, std::vector<T> &vec)
{
    vec.erase(vec.begin() + index);
}
But how can I access any number on the board because it is a vector within a vector?
Last edited on
But how can I access any number on the board because it is a vector within a vector?

Same way as you would with a 2D array.
vec[0][0]; // element at first row and first column
Erasing an element from Vector<Vecter<short>>


Should it be :
Erasing an element from Vector<Vector<short>>

So I tried using this function:

void erase(){
int row = rand()%9; int col = rand()%9;
int r, c;
m_map[row][col].erase(m_map[row][col].begin() + row);
}
however there is an error with the erase
So, m_map has type vector<vector <cell> >.

Thant means that m_map[row][col] has type cell.

So you're trying to call the erase() method of a cell object. Does cell have an erase() method?

I'm guessing that what you really want to do is call erase() on one of the vectors, rather than on a cell.

The above is also true of m_map[row][col].begin() on the same line.

By the way, telling us "there is an error" is not very helpful. Your compiler is giving you helpful information about what that error is. Why would you withhold that information from us? The more help you give us, the more help we can give you.
closed account (48T7M4Gy)
If this is a straightforward Soduko grid then erase() is surely not deleting a cell but simply clearing its contents and resetting to some default value.
OP: You are using the term 'erase' erroneously as it means something entirely different in vector-speak. In STL 'erase' removes either a single element or a range of elements from the vector. So if you were to call erase on your board you'd just be left with gaping hole(s). What you need really is to reach inside any cell of the board and manipulate it's m_num data members with the setter you've already defined, setMark() (whose parameter should be passed by reference incidentally):

Now you define a cell_change method in class board:
1
2
3
4
5
6
void board::cell_change(const size_t& i, const size_t& j, const int& n)
//scroll down I notice later board::setMark() is doing this why does it have to return bool?;
{

	m_map[i][j].setMark(num);
}


Couple of other points:

- in class cell, method getNum()const should be const qualified;
- the insertion operator overload needs to be re-worked a bit and defined outside the class since it's a friend function:

1
2
3
4
5
6
7
8
9
10
11
12
13
friend ostream& operator << (ostream& o, const cell& c)
{
		if (c.m_occu)
		{
			o << setw(2) << c.m_num;//additional newline and/or tab may be required here to attain desired visual effect; 
		}
		else
		{
			o << setw(2) << '-';
		}
		
		return o;
}

Last edited on
I was thinking, how would it be possible for me to set a random cell to the value of 0, and then show that if cell = 0 then show "-", this was my attempt

1
2
3
4
5
void erase(){
		srand(time(0));
		int row = rand()%9; int col = rand()%9;
		m_map[row][col].getNum() = 0;
	}


however, at m_map[row][col]... I get a compiler error that says that: "lvalue required as left operand of assignment."

This logic was inspired by the above comment, I am thinking if 0is a default value, I can set a random cell to 0 within the vector and the vector will show as "-".
Last edited on
Because you used getNum(), not setMark()
I guess my question should be that in this case with respect to user-defined types, how could I change the value of a cell of type cell in a vector<vector<cell> >.
By using setters for the respective user-defined type. As mentioned above, your board::setMark() is already doing that through cell::setMark()
Thanks for the help, I got it to work and now its working without error.

All that is left is the verify() function. How can I check for the correctness of the board as per the rules of Sudoku, especially in a 3 by 3 box like below?

A B C D E F G H I 
P  3 4 5 9 1 - 7 6 8 
Q  6 7 8 3 4 5 1 9 2 
R  9 1 2 6 7 8 4 3 5 
S  2 3 4 8 9 1 6 5 7 
T  5 6 7 2 3 4 9 8 1 
U  8 9 1 5 6 7 3 2 4 
V  1 2 3 7 8 9 5 4 6 
W  4 5 6 1 2 3 8 7 9 
X  - 8 9 4 5 6 2 1 3 
> verify 
- Found inconsistency in row P... 
- Found inconsistency in row X... 
- Found inconsistency in column A... 
- Found inconsistency in column F... 
- Found inconsistency in component starting at row P and column D... 
- Found inconsistency in component starting at row V and column A...
> quit
Bye...
Actually I am moving this to another thread.
Topic archived. No new replies allowed.