2012-11-15 16 views
15

Chcę wypełnić wektor 8 parami. Każda para reprezentuje ruchy w współrzędnych x i y, które może wykonać rycerz w grze w szachy. W tej chwili robię to w ten sposób:Wypełnianie wektora par

vector<pair<int,int>> moves[8]; 

pair<int,int> aPair; 
aPair.first = -2; 
aPair.second = -1; 
moves[0].push_back(aPair); 
aPair.first = -2; 
aPair.second = 1; 
moves[1].push_back(aPair); 
aPair.first = -1; 
aPair.second = -2; 
moves[2].push_back(aPair); 
aPair.first = -1; 
aPair.second = 2; 
moves[3].push_back(aPair); 
aPair.first = 1; 
aPair.second = -2; 
moves[4].push_back(aPair); 
aPair.first = 1; 
aPair.second = 2; 
moves[5].push_back(aPair); 
aPair.first = 2; 
aPair.second = -1; 
moves[6].push_back(aPair); 
aPair.first = 2; 
aPair.second = 1; 
moves[7].push_back(aPair); 

Robię to, aby poznać bibliotekę Std. Wydaje się to być beznadziejnie nieskutecznym sposobem rozwiązania tego problemu.

Ktoś ma bardziej eleganckie rozwiązanie?

+4

Pierwsza obserwacja: użyj 'przesuwa [0] .push_back (std :: make_pair (-2 , -1)); ' druga obserwacja: Masz 8 wektorów, a nie jeden. – andre

Odpowiedz

13

Pętle na ratunek:

for(int k = 0; k < 2; k++) 
    for(int i = -1; i < 2; i += 2) 
     for(int j = -1; j < 2; j+= 2) 
      result.push_back(make_pair(i * (k+1), j * (((k + 1) % 2) + 1))); 

wyjściowa: http://ideone.com/2B0F9b

+0

Wow, to naprawdę fajne rozwiązanie. Dzięki! –

15

Jeśli masz C++ 11 (w przeciwnym razie nie można napisać >>), można użyć następujących:

vector<pair<int,int>> moves = { 
    {-2, -1}, 
    {-2, 1}, 
    {-1, -2}, 
    {-1, 2}, 
    { 1, -2}, 
    { 1, 2}, 
    { 2, -1}, 
    { 2, 1} 
}; 
+0

Potrzebna jest dodatkowa para nawiasów klamrowych wokół każdej pary liczb, wewnętrzna wykonuje agregacyjną inicjalizację 'std :: pair', a zewnętrzna jest wymagana dla konstruktora' vector'. – Praetorian

+0

@Praetorian: 'std :: pair <>' nie jest agregatem, to jest wywołaniem konstruktora. – ildjarn

+0

@ildjarn Hmm, zawsze zakładałem, że to było. Ale gcc 4.7.0 narzeka, jeśli pominiesz dodatkowe nawiasy klamrowe. – Praetorian

6

Jeśli nie masz C++ 11 można wykorzystać make_pair, Pre - przydziel przestrzeń dla wektora bez inicjowania elementów za pomocą rezerwy, a następnie użyj funkcji push_back bez wykonywania nowych alokacji.

Na przykład:

vector<pair<int,int> > moves; 
moves.reserve(8); 
moves.push_back(make_pair(-2, -1)); 
    // and so on 

Nawet jeśli masz C++ 11 technika ta jest przydatna, gdy trzeba obliczyć elementy na bieżąco, a nie ciężko kodem im.

+0

Dziękuję za to. Już zaznaczyłem odpowiedź, ale myślę, że powinno ją zabrać. –

+0

Nie ma za co! –

3

Spróbuj tego:

vector<pair<int,int>> moves{{-2, -1}, {2, 1}, {-1, -2}, {-1, 2}, 
          {1, -2}, {1, 2}, {2, -1}, {2, 1}}; 

Initializer list wraz z Uniform inicjalizacji daje dużo energii w C++ 11.

9

C++ 98/03

moves.push_back(std::make_pair(-2, -1)); 

C++ 11:

moves.emplace_back(-2, -1); 

Alternatywnie C++ 11:

std::vector<std::pair<int, int>> moves = { { -2, -1}, ... }; 
1

Poniżej inna metoda robi to samo.

template <class VectorClass> 
class CreateVector 
{ 
public: 
    typedef typename VectorClass::value_type value_type; 
    CreateVector(const value_type& value) 
    { 
     mVector.push_back(value); 
    } 

    CreateVector& operator()(const value_type& value) 
    { 
     mVector.push_back(value); 
     return *this; 
    } 

    inline operator VectorClass() const 
    { 
     return mVector; 
    } 
private: 
    VectorClass mVector; 
}; 

Zastosowanie:

vector<pair<int,int>> moves = CreateVector<vector<pair<int,int> > > 
(make_pair(1,2)) 
(make_pair(2,3)) 
(make_pair(3,4)) 
(make_pair(4,5)); 

EDIT: Pod warunkiem, że nie używasz C++ 11, to byłby jeden sposób. W przeciwnym razie sugerowałbym pójść drogą sugerowaną przez @ipc.

0

Jeśli używasz C++ 11, to może warto rozważyć std :: tablicę zamiast std :: vector. Podobnie jak w przypadku zwykłej tablicy, std array ma stałą liczbę elementów i ma bardziej koncepcyjny sens, jeśli z góry wiesz, ile danych używasz.

0

Mam nadzieję, że bardziej czytelna wersja z pętlami:

vector<pair<int, int>> result; 
for(int moveX=1; moveX<=2; moveX++) 
{ 
    for(int signX=-1; signX<=1; signX+=2) 
    { 
     for(int signY=-1; signY<=1; signY+=2) 
     { 
      result.push_back(make_pair(moveX*signX, (3-moveX)*signY)); 
     } 
    } 
} 

Full program produkuje następujące Vector:

{-1, -2}, 
{-1, 2}, 
{1, -2}, 
{1, 2}, 
{-2, -1}, 
{-2, 1}, 
{2, -1}, 
{2, 1},