Mam za zadanie napisać funkcję nwd(unsigned int n...). Pozostałe argumenty wywołania funkcji to liczby a1, a2, ... , an typu unsigned int. Funkcja ma obliczyć i zwrócić największy wspólny dzielnik tych liczb. Próbowałem coś pisać, ale wszystko wywala się już przy implementacji funkcji o nieokreślonej liczbie argumentów. Pomoże ktoś?
Pewnie, to całkiem prosta sprawa.
template<typename T, typename... Us>
auto nwd(T t, Us... us)
{
static_assert(is_constructible_v<unsigned, T>);
if constexpr(sizeof...(Us) > 1){
return gcd(t,nwd(us...));
} else {
static_assert(is_constructible_v<unsigned, Us...>);
return gcd(t, us...);
}
}
kq napisał(a):
Pewnie, to całkiem prosta sprawa.
template<typename T, typename U> auto nwd(T t, U u); template<typename T, typename... Us> auto nwd(T t, Us... us) { static_assert(is_constructible_v<unsigned, T>); return gcd(t,nwd(us...)); } template<typename T, typename U> auto nwd(T t, U u) { static_assert(is_constructible_v<unsigned, T>); static_assert(is_constructible_v<unsigned, U>); return gcd(t,u); }
Tyle tylko, że nigdy nie korzystałem z tego wszystkiego (template, static_assert itp.) i raczej w tej funkcji też mi nie wolno. Muszę to zrobić za pomocą va_list, va_arg itp.
@kq: Jak mówiłem, muszę to zrobić za pomocą va_list, va_arg itp. Jak dla mnie ten kod nadal jest zbyt skomplikowany.
Otagowałeś temat "C++", więc takie podałem rozwiązanie. Nie chce mi się bawić w przestarzałe i niewydajne rozwiązania, ale może ktoś się zjawi i napisze to w "prosty" sposób.
@kq: Dzięki za pomoc.
Wersja z va_arg:
#include <stdarg.h>
int nwd(unsigned int n, ...)
{
va_list list_pointer; // Wskaźnik na pierwszy element listy argumentów
va_start(list_pointer, n); // Inicjalizacja wskaźnika
unsigned int number = va_arg(list_pointer, int);
// Po wywołaniu va_arg list_pointer zostanie zinkrementowany
va_end(list_pointer); // Ważne aby użyć va_end kiedy używamy va_start. Dzięki temu zwalniamy wskaźnik.
return sum;
}
atmal napisał(a):
Wersja z va_arg:
#include <stdarg.h> int nwd(unsigned int n, ...) { va_list list_pointer; // Wskaźnik na pierwszy element listy argumentów va_start(list_pointer, n); // Inicjalizacja wskaźnika unsigned int number = va_arg(list_pointer, int); // Po wywołaniu va_arg list_pointer zostanie zinkrementowany va_end(list_pointer); // Ważne aby użyć va_end kiedy używamy va_start. Dzięki temu zwalniamy wskaźnik. return sum; }
Coś takiego to ja już miałem w sumie..
double nwd(unsigned int n,...)
{
va_list ap;
int i;
va_start (ap,n);
for(i=1;i<n;i++)
{
if
}
va_end (ap);
}
Tylko że największy problem mam z samym NWD. Nie wiem, jak to zrobić w środku funkcji dla n liczb.
Licz NWD parami, tak jak w moim przykładzie. Czyli NWD(pierwsza, druga), potem NWD(wynik, trzecia) itd.
@kq: Wiem, że tak trzeba to robić, tylko nie wiem, jak to zaimplementować...