patterncppMinor
Simple class for 2D <-> 1D array index conversion
Viewed 0 times
conversionsimplearrayforindexclass
Problem
I made a class to convert the index between 2D and 1D arrays.
For example,
between
{1,3,5,7,9,11} and {{1,3},{5,7},{9,11}}
And so on...
I would be able to convert between the
For example,
between
{1,3,5,7,9,11} and {{1,3},{5,7},{9,11}}
- When
iis 0,xyshould be (0,0)
- When
iis 1,xyshould be (0,1)
- When
iis 2,xyshould be (1,0)
And so on...
I would be able to convert between the
i-index and the xy-index to find get the equivalent location. I feel like this piece of code may be too long for its purpose.class IndexConv {
public:
IndexConv(int rows, int cols);
bool check_i(int i) const;
bool check_xy(int x, int y) const;
pair to_xy(int i) const;
int to_i(int x, int y) const;
private:
const int rows_;
const int cols_;
};
IndexConv::IndexConv(int rows, int cols)
:rows_(rows), cols_(cols) {}
bool IndexConv::check_i(int i) const
{
return i>=0 || i=0 && y>=0 && x IndexConv::to_xy(int i) const
{
if(!check_i(i)) throw out_of_range("IndexConv: i out of bounds.");
int x = i/cols_;
int y = i-x*cols_;
return make_pair(x,y);
}
int IndexConv::to_i(int x, int y) const
{
if(!check_xy(x,y)) throw out_of_range("IndexConv: xy out of bounds.");
int i = x*cols_+ y;
return i;
}Solution
Use modulus
Instead if this
Use a unsigned type.
If you use unsigned there is no need to check for
EDIT: Changed the answer to keep check_xy. Keeping
Instead if this
i-x*cols_ you can use the modulus operator i % cols_.Use a unsigned type.
If you use unsigned there is no need to check for
x >= 0 && y >= 0. Also you can con throw the exception directly in check. And you just need check_xy.void IndexConv::check(unsigned x, unsigned y) const
{
if(x >= rows_ || y >= cols_)
throw std::out_of_range("IndexConv: parameter out of bounds.");
}
pair IndexConv::to_xy(unsigned i) const
{
int x = i / cols_;
int y = i % cols_;
check(x, y);
return make_pair(x, y);
}
int IndexConv::to_i(unsigned x, unsigned y) const
{
check(x, y);
return x * cols_ + y;
}EDIT: Changed the answer to keep check_xy. Keeping
check_i can map (0,2) to 2 when it should throw an exception (Following your example).Code Snippets
void IndexConv::check(unsigned x, unsigned y) const
{
if(x >= rows_ || y >= cols_)
throw std::out_of_range("IndexConv: parameter out of bounds.");
}
pair<int, int> IndexConv::to_xy(unsigned i) const
{
int x = i / cols_;
int y = i % cols_;
check(x, y);
return make_pair(x, y);
}
int IndexConv::to_i(unsigned x, unsigned y) const
{
check(x, y);
return x * cols_ + y;
}Context
StackExchange Code Review Q#120827, answer score: 5
Revisions (0)
No revisions yet.