have a problem with std::map when use a custom class as key

Here, I want to find the line appears most int a vector, but the map seems not work correctly.The element doesnt insert to the map.

PRINT:
 A: 123 B: 566 C: 3 counts[line]:1
 A: 89 B: -4 C: 5 counts[line]:0
 A: -6545 B: 6 C: 3 counts[line]:0
 A: 235 B: -8 C: 6 counts[line]:0
 counts.size():7
1



When I use condition 4 only, it seems back to normal.

PRINT:
 A: 123 B: 566 C: 3 counts[line]:1
 A: 89 B: -4 C: 5 counts[line]:1
 A: -6545 B: 6 C: 3 counts[line]:2
 A: 235 B: -8 C: 6 counts[line]:1
 counts.size():3
2


When I use condition 3-4, wrong again..

PRINT:
A: 123 B: 566 C: 3 counts[line]:1
 A: 89 B: -4 C: 5 counts[line]:0
 A: -6545 B: 6 C: 3 counts[line]:0
 A: 235 B: -8 C: 6 counts[line]:0
 counts.size():7
1


CODE(GCC9.1.0):
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
#include <iostream>
#include <vector>
#include <map>
using namespace std;

/** 
 * @brief
 * Use A,B,C to describe a line in a 2-dims plane:
 *      A * x + B * y +C = 0 ,
 * where x,y is the 2 axis.
 * */
struct Line
{
    int A;
    int B;
    int C;
    Line() : A(0), B(0), C(0) {}
    Line(int a, int b, int c) : A(a), B(b), C(c) {}
};

struct cmp
{
    bool operator()(const Line &p, const Line &q) const
    {
        /** 
         * @mark: condition 1:
         * @note: same line if: 
         *  A1     B1     C1
         * ---- = ---- = ---- 
         *  A2     B2     C2
         * */
        if (((p.A * q.B) == (p.B * q.A)) && ((p.A * q.C) == (p.C * q.A)) && ((p.B * q.C) == (p.C * q.B)))
            return false;

        /** @mark: condition 2 */
        if (p.A < q.A)
            return true;

        /** @mark: condition 3 */
        if (p.B < q.B)
            return true;

        /** @mark: condition 4 */
        if (p.C < q.C)
            return true;

        return false;
    }
};

class Solution
{
public:
    /** 
     * @brief: find the line appears most in a sort of lines. 
     * @note: here we used a vector of lines as input instead of a list of 2-dims points.
     * so we dont need to construct a line with 2 points
     * */
    int getCounts()
    {
        map<Line, int, cmp> counts{};
        vector<Line> lines{{123, 566, 3}, {89, -4, 5}, {-6545, 6, 3}, {235, -8, 6}};
        for (auto i : lines)
        {
            ++counts[i];
            cout << " A: " << i.A
                 << " B: " << i.B
                 << " C: " << i.C
                 << " counts[line]:" << counts[i] << endl;
        }
        cout << " counts.size():" << counts.size() << endl;
        int max = 0;
        for (auto &&i : counts)
            if (max < i.second)
                max = i.second;
        return max;
    }
};

int main()
{
    Solution solution{};
    cout << solution.getCounts();
}
Last edited on
Try

1
2
3
4
5
6
7
8
9
10
11
12
13
struct cmp
{
    bool operator()(const Line &p, const Line &q) const
    {
        if (p.A * q.B == p.B * q.A &&
            p.A * q.C == p.C * q.A &&
            p.B * q.C == p.C * q.B)
            return false;
        return p.A <  q.A ||
              (p.A == q.A && (p.B <  q.B ||
                             (p.B == q.B && p.C < q.C)));
    }
};

Now that I think about it, I don't understand the if part.

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
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
using namespace std;

struct Line
{
    int A, B, C; // A * x + B * y + C = 0
    Line(int a=0, int b=0, int c=0) : A(a), B(b), C(c) {}
    bool operator<(const Line &q) const;
};

bool Line::operator<(const Line &q) const
{
    if (A * q.B == B * q.A && A * q.C == C * q.A && B * q.C == C * q.B)
        return false;
    return A <  q.A ||
          (A == q.A && (B <  q.B ||
                       (B == q.B && C < q.C)));
}

int getCounts(vector<Line>& lines)
{
    map<Line, int> counts{};

    for (auto i : lines)
    {
        ++counts[i];
        cout << "A: "    << setw(5) << i.A
             << "   B: " << setw(5) << i.B
             << "   C: " << setw(5) << i.C
             << "     counts[line]: " << counts[i] << '\n';
    }

    cout << "counts.size(): " << counts.size() << '\n';

    int max = 0;
    for (auto& x : counts)
        if (x.second > max)
            max = x.second;
    return max;
}

int main()
{
    vector<Line> lines
    {
        {  123, 566,  3},
        {   89,  -4,  5},
        {-6545,   6,  3},
        {  235,  -8,  6}
    };
    auto m{ getCounts(lines) };
    cout << "max: " << m << '\n';
}

Last edited on
Thx dutch very much.
THe cmp func does have problems. The program works well now with your help.
THx you again.
Topic archived. No new replies allowed.