Re: Search only one column of a multi-dimensional array
On Mar 9, 1:48 pm, Angus <anguscom...@gmail.com> wrote:
On Mar 7, 10:32 pm, James Kanze <james.ka...@gmail.com> wrote:
On Mar 7, 6:05 pm, Victor Bazarov <v.baza...@comcast.invalid> wrote:
[...]
I have had a go as below. But there is a problem if lookup value is
smaller than any code in first column. What am I doing wrong? I
assume my predicate is not quite correct?
I've not analysed your code completely, but a couple of things
do stick out.
#pragma warning(disable: 4786)
#include <iostream>
#include <algorithm>
using namespace std;
struct errorinfo
{
errorinfo() : category(0), error(0) {}
int category;
int error;
};
bool lessthanrow1(const int (&arr)[3], const int other)
{
return arr[0] < other;
}
I'm not sure what the standard says on the issue, but I could
easily imagine the implementation trying to do the less than in
both directions: entry < key, and key < entry, When both have
the same type, no problem, but when they don't... That's why I
always define a functional object which supports the comparison
in both directions.
bool maperror2code(const int bw_error, errorinfo& csta_error)
{
const int cols = 3;
//in real life much bigger array.
static const int tbl[6][cols] = {
1000, 10, 0,
1001, 11, 1,
1200, 12, 2,
4002, 13, 3,
8090, 14, 4,
121105, 15, 5
};
int tblsize = sizeof(tbl) /( sizeof(int) * cols);
int* result = (int*)lower_bound(tbl, tbl+tblsize, bw_error,
lessthanrow1);
Why the cast? The results will be an int (*)[3]; thats what you
should use.
int idx = ((result - (int*)tbl) / cols);
If you used the correct type, you wouldn't need all the casts,
nor the division.
Of course, there's really no need to calculate the index at all.
You can do everything you need with pointers (as iterators).
if(idx != tblsize){
Check what lower_bound returns when it doesn't find the element.
It's *not* a pointer to end. In general, lower_bound is a lot
more complex to use than find; avoid it unless the profiler says
you really have to.
csta_error.category = tbl[idx][1];
csta_error.error = tbl[idx][2];
} else {
cout << "item not found\n";
return false;
}
cout << "Your error: " << bw_error << " category=" << tbl[idx][1]
<< " errcode=" << tbl[idx][2] << endl;
return true;
}
int main(){
//4002 found ok. 90 returns first element in array. large number
is ok.
In general, anything less than the last value will be "found" by
the code you've written. lower_bound returns an iterator to
where you should insert the new element in order to maintain
order. It's not really a lookup function.
Note that your code would be a lot cleaner if you used a few
typedef's (e.g. typedef int Row[cols]), if you used the usual
begin and end template functions for returning the corresponding
pointers to a C style array, and, since you're using the STL, if
you stuck with pointers (aka iterators), rather than switching
to indexes in mid field.
--
James Kanze