Jak najprościej sprawdzić, czy "n" zmiennych jest różnowartościowe?

0

Jak najprosciej sprawdzic, czy n zmiennych jest rożnowartościowe?
Konkretnie jedna zmienna i 8 iteratorów.

if(a!=*it!=*it2!=*it3!=*it4!=*it5!=*it6!=*it7!=*it8)

To coś nawala.

0

wielki będzie ten if: if(a!=*it && a!=*it2 && a!=*it3 && a!=*it4 && a!=*it5 && a!=*it6 && a!=*it7 && a!=*it8 && *it!=*it1 && *it!=*it2 && *it!=*it3 ... )
najlepiej wpisz to do tabelki, posortuj po czym sprawdź czy nie ma dwóch sąsiednich jednakowych.

0

Właśnie chciałbum uniknąc klepania tego ifa ;p Może wrzucic do seta i sprawdzic, czy set.size()==9?
EDIT: zmiana koncepcji.

bool czyrozne(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
{
  int tmp[]={a1, a2, a3, a4, a5, a6, a7, a8, a9};
  sort(tmp, tmp+9);
  for(unsigned int i=1;i!=9;i++)
    if(tmp[i-1]==tmp[i])
        return false;
  return true;
}

Mam naruszenie ochrony pamięci, problem leży w tej funkci, jednak nie moge znalezc, gdzie konkretnie.
Wywołuje ją:

if(czyrozne(a, *it, *it2, *it3, *it4, *it5, *it6, *it7, *it8)==true)
4

Masz tu C++ way:

template <typename T>
bool isAllUnique(std::vector<T> values) {
  std::sort(values.begin(), values.end());
  return std::adjacent_find(values.cbegin(), values.cend()) == values.cend();
}

Po prostu użyj tak:

if(isAllUnique<int>({a, *it, *it2, *it3, *it4, *it5, *it6, *it7, *it8})) { // ...

Zapewne jest milion innych sposobów.

Wersja w sumie fajniejsza chyba:

template <typename Tf, typename ...T>
bool isAllUnique(Tf first, T... rest) {
  // Liczba zmiennych. Kropki sa brzydkie, lepiej sobie zapisac na boku raz.
  constexpr std::size_t size = sizeof...(T);

  // Sprawdzmy, czy to co robimy ma sens.
  static_assert(size > 0, "Wut?");
  // Tutaj w zasadzie przydalby sie jakis static_assert, ktory sprawdza, czy wszystkie typy w T sa takie same jak Tf (albo konwertowalne do Tf).
 
  // std::array jest lepszy od std::vector, bo to zwyczajna tablica na stosie.
  std::array<Tf, size + 1> values = {first, rest...};

  // To samo co poprzednio.
  std::sort(values.begin(), values.end());
  return std::adjacent_find(values.cbegin(), values.cend()) == values.cend();
}

// ...

if(isAllUnique(a, *it, *it2, *it3, *it4, *it5, *it6, *it7, *it8)) { // ...

Chyba powinno być "areAllUnique". ;-)

0

main.cpp ostrzeżenie:extended initializer lists only available with -std=c++0x or -std=gnu++0x [enabled by default]
main.cpp błąd:no matching function for call to 'isAllUnique(<brace-enclosed initializer="initializer" list="list">)'

Nigdy nie korzystałem jeszcze z szalbonow, wiec jestem w tym całkiem zielony. Mam takie błędy przy wowołaniu tej funkcji.

2

Ja bym użył std::set<>, dodał wszystkie i sprawdził czy std::set<>::size() zwraca liczbę równą ilości dodanych elementów.

W formie funkcji:

template<typename T>
bool areAllUnique(std::initializer_list<T> init){
     std::set<T> check{init};
     return check.size() == init.size();
}

Przykład użycia: http://coliru.stacked-crooked.com/a/b945a12f0f1ab1fe

Użycie setu to jedna dodatkowa alokacja, ale jeśli wydajność co do milisekundy nie jest aż tak wydajna to wydaje mi się, że jest to najczytelniejsze rozwiązanie.

1

Tak na to patrzę i mi się wydaje że nie potrzebujesz tego o co pytasz.
Podaj kawałek kodu w którym chcesz to użycz.
Podejrzewam że to co próbujesz osiągnąć to marna podobizna next_permutation() z osmu pętli.

0
void el4(pair<int, vector<int> >  (&tab)[10])
{
  for(int a=1;a!=10;a++)
    {
      for(vector<int>::iterator it=tab[a].second.begin(); it!=tab[a].second.end(); ++it)
        {
          for(vector<int>::iterator it2=tab[*it].second.begin(); it2!=tab[*it].second.end(); ++it2)
            {
              for(vector<int>::iterator it3=tab[*it2].second.begin(); it3!=tab[*it2].second.end(); ++it3)
                {
                  if(isAllUnique<int> ( {a, *it, *it2, *it3} )  )
                    {
                      printf("%i: %i->%i->%i->%i\n", licznik, a, *it, *it2, *it3);
                      licznik++;
                    }
                }
            }
        }
    }
}

To jest funkcja licząca wszystkie możliwości dla dlugosci wzoru rownej 4. Trzymam to w std::pair<int, std::vector<int> > w ten sposób:

1:{2, 4, 5, 6, 8};
2:{1, 3, 4, 5, 6, 7, 9};
3:{2, 4, 5, 6, 8};
[...]

dodanie znacznika <code> - fp

0

Czy to coś jest symetryczne?
Czyli czy taka sytuacja jest niemożliwa:

....
X: { ..., Y,  ... }; // tu jest Y
...
Y: { ... }; // tu brak X
...

?

Czemu nie zrobisz prościej:
void elX(map<int,vector<int> > &mp,int n)

0

Oczywiście, jest symetroczne. Pole numeruje:

1 2 3
4 5 6
7 8 9

jeśli z pola n można przejść do pola m, to i odwrotnie można.
Faktycznie - mapa byłaby bardziej przejrzysta, ale nie zastanawiałem sie nad tym dlugo, po prostu byłem ciekaw ilości wariacji tego wzoru - nic poza tym.

dodanie znacznika <code> - fp

0

Czy kombinację 1 2 5 i 1 5 2 muszą być liczone jako różne ?

0

Oczywiście.

1

No to masz uniwersalne:

void rec(map<size_t,pair<bool, vector<size_t> > > &mp,size_t i,size_t n,size_t &counter)
  {
   pair<bool, vector<size_t> > &cur=mp[i];
   cur.first=true;
   for(vector<size_t>::iterator k=cur.second.begin();k!=cur.second.end();++k)
     {
      if(!mp[*k].first)
        {
         if(n) rec(mp,*k,n-1,counter)
         else ++counter;
        }
     }
   cur.first=false;
  }

size_t el(map<size_t,pair<bool, vector<size_t> > > &mp,size_t n)
  {
   size_t counter=0;
   for(map<int,pair<bool, vector<int> > >::iterator i=mp.begin();i!=mp.end();++i) i->second.first=false;
   for(map<int,pair<bool, vector<int> > >::iterator i=mp.begin();i!=mp.end();++i) rec(mp,i->first,n,&counter);
   return  counter;
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1