Есть ли способ сохранить ключ, значение, значение на карте?

Прочитав большую часть maps вопросы, в конце концов я получил представление по этой ссылке: Как уникальные мои данные, которые хранятся в объекте, которые хранятся в векторе?

У меня есть задача хранения X, Y, Z координаты из пользовательского ввода. Чтобы пользователь не мог вводить дублированные данные, я решил использовать контейнеры карт, поскольку они не допускают дублирование данных.

Я проверил код.

я использую X как key и Y как value

Я могу хранить X а также Y через это:

map<int, int> mapp2d;
mapp2d.insert(pair<int, int>(X, Y));

И получить к ним доступ через это:

map<int, int>::iterator p = mapp2d.begin();
map<int, int>::iterator e = mapp2d.end();
while ( p != mapp2d.end())
{
cout << "X: " << p->first << " Y: " << p->second << endl;
p++;
}

Можно ли сделать это для X, Y, Z ? Как это:

map<int, int, int> mapp3d
mapp3d.insert(pair<int, int, int>(X, Y, Z))

Я проверил код, но я получил следующие ошибки:

error: wrong number of template arguments (3, should be 2)
error: provided for ‘template<class _T1, class _T2> struct std::pair

Да, я знаю, что это незаконно для меня, но нет никаких учебных пособий о том, как я должен это делать, и у меня вроде как закончились идеи, и как я могу получить к ним доступ?

Благодарю вас, ребята, за то, что взглянули, заранее спасибо.

3

Решение

Вы должны хранить координаты вместе вместо использования одной координаты в качестве ключа:

struct Point
{
int x, y, z;

Point(int x, int y, int z) : x(x), y(y), z(z) {}
};

Затем просто внедрите собственный компаратор:

struct PointComparator
{
bool operator()(const Point& a, const Point& b)
{
if (a.x < b.x) return true;
if (a.x == b.x && a.y < b.y) return true;
if (a.x == b.x && a.y == b.y && a.z < b.z) return true;
return false;
}
};

И, наконец, используйте задавать вместо карты (потому что в вашем случае значения и ключи одинаковые):

#include <set>
std::set<Point, PointComparator> points;

Наборы (как и карты) упорядочены по умолчанию от низких до высоких значений. Вам нужно указать собственный компаратор, потому что он используется по умолчанию, если вы просто std::set<Point> является std::less, Этот компаратор может сравнивать числа и т. Д., Но не имеет понятия, как сравнивать объекты типа Point, Таким образом, набор не может правильно упорядочить свои элементы, а также не определить, идентичны ли два элемента (то, что вам нужно). Если вы делаете std::set<Point, PointComparator>, вы создаете набор, который использует логику в PointComparator сравнить его элементы.

В этом примере будет напечатано «1» и «2»:

points.insert(Point(1, 2, 3));
points.insert(Point(1, 2, 3));
points.insert(Point(2, 3, 4));

std::set<Point, PointComparator>::iterator it = points.begin();
while (it != points.end()) {
std::cout << "x = " << it->x << std::endl;
it++;
}
4

Другие решения

Вы рассматривали возможность использования кортежа? Их можно использовать для удержания более 2-х элементов

http://www.cplusplus.com/reference/tuple/tuple/

Я думаю, еще одна возможность, если вы действительно настроены на использование карты, это сделать что-то вроде ссылки ниже, где значения вашей карты:

Использование найти на карте<пара, инт>

1

Я не эксперт C ++, но я думаю, что вы должны использовать набор, а не карту, и использовать кортеж для значений. Наборы обычно используются для хранения уникальных значений (хотя я говорю о знаниях Java и Python, а не C ++). Посмотрите на set и unordered_set; очевидно, unordered_set быстрее, но набор отсортирован. Ни один из них не отслеживает порядок, в который вы вводите вещи, ни один из них не отображает карту, поэтому, если вам это нужно, вам нужно будет найти другое решение. И я думаю, что кортежи могут хранить произвольное количество элементов.

0

Часто полезно различать, как вы храните данные и как вы к ним обращаетесь.

Например, вы можете хранить точки в векторе, но размещать на них «индекс уникальности», используя, скажем, std :: set. Вот некоторый автономный код, демонстрирующий эту идею:

#include <functional>
#include <iostream>
#include <memory>
#include <set>
#include <vector>

class Point {
public:
Point(int x, int y, int z) : m_x(x), m_y(y), m_z(z) {}

int x() const { return m_x; }
int y() const { return m_y; }
int z() const { return m_z; }

private:
int m_x;
int m_y;
int m_z;
};

bool operator<(const Point & a, const Point & b) {
return (a.x() < b.x()
|| (a.x() == b.x()
&& (a.y() < b.y()
|| (a.y() == b.y()
&& a.z() < b.z()))));
}class Points {
public:
Points() {}

bool add(Point p) {
if (m_uniqueIndex.count(p) == 0) {
m_points.emplace_back(new Point(p));
m_uniqueIndex.emplace(*m_points.back());
return true;
}
return false;
}

private:
std::set<std::reference_wrapper<Point>> m_uniqueIndex;
std::vector<std::unique_ptr<Point>> m_points;
};

const char * s(bool b) {
return b ? "true" : "false";
}

int main(int argc, char * argv[]) {
Point a(1, 2, 3);
Point b(2, 1, 0);
Point c(-1, 0, 1);
Point a2(1, 2, 3);

Points points;

std::cout << "Adding a: " << s(points.add(a)) << std::endl;
std::cout << "Adding b: " << s(points.add(b)) << std::endl;
std::cout << "Adding c: " << s(points.add(c)) << std::endl;
std::cout << "Adding a2: " << s(points.add(a2)) << std::endl;
}

По моему опыту, когда вы используете пространственные данные, вам всегда хочется задавать такие вопросы, как: что это за соседи? Сколько вещей находится на некотором расстоянии от этой координаты и т. Д. Поэтому я также рекомендую вам немного прочитать о k-d деревья (для очков) и г деревья (для фигур).

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector