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.
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.
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.
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)
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". ;-)
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.
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.
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.
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
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)
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
Czy kombinację 1 2 5
i 1 5 2
muszą być liczone jako różne ?
Oczywiście.
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;
}