Rekurencja i modulo

0

Cześć ktoś wie jak zapisać dzielenie modulo w rekurencji?
Zadanie: a∗b mod m

Mam zwykłe:

#include<iostream>
using namespace std;

int main()
{
    long long  int n,a,c;
    cin>>a>>n>>c;
    cout<<n%c*a%c;
    return 0;
}
0

A czasami nie chodzi tu o wyliczenie reszty z dzielenia za pomocą rekurencji zamiast %? Coś w stylu - https://math.stackexchange.com/questions/580907/recursive-function-mod-5

0

Użyj funkcji rekurencyjnej do pobierania danych, która będzie zwracała ich iloczyn.
Nie będzie to głęboka rekurencja - tylko jedno zagnieżdżenie.
Następnie w main() oblicz modulo z wyniku funkcji i wczytanego m.

0

Takie coś ci wyrzeźbiłem na szybko.
Twoim zadaniem jest obliczenie modulo z recmod() ...

using std::cin;
using std::cout;

long long recmod();
int counter=0;

int main() {
    
    cout<< recmod();
    
    return 0;
}

long long recmod() {
    
    long long a=1;
    while (counter<2) {
        cout<<"Podaj "<<counter+1<<" element: ";
        cin>>a;
        counter++;
        cout<<"\n";
        a*=recmod();
        
    }
    return a;
}

i wyczyszczenie ładnie tego kodu.

0

A ile ma mnozyc wg ciebie?

0

Moja próba na podstawie zalinkowanego wcześniej przykładu:

#include <iostream>
#include <cmath>

int recmod(int a,  int b, int m ) {
if  (a*b < m) {
    return a*b;

} else {
  if (a>b) {
     return abs(recmod(a-m, b, m));
  }
  else {
    return abs(recmod(a,b-m,m));
  }

}
}

int main() {
  std::cout << recmod(2,3, 4);
  std::cout<<recmod(2,21,10);
}

Edit:
Dodałem abs na wypadek(m>a || m >b).

0

Taki kod ale sprawdzaczka pokazuje błędne odpowiedzi :-(


#include <iostream>
#include <cmath>

long long int recmod(int a,  int b, int m ) {
if  (a*b < m) {
    return a*b;

} else {
  if (a>b) {
     return abs(recmod(a-m, b, m));
  }
  else {
    return abs(recmod(a,b-m,m));
  }

}
}

int main()

{
   long long int a;
   long long int b;
   long long int m;
    
    std::cin>>a;
   std:: cin>>b;
    std::cin>>m;
    
std:: cout << recmod(a,b,m);

}

0

Nie wnikam, ale coś czuje, że czepia się o

if (a*b <m)

Jak wiadomo z lekcji matematyki jeżeli a x b < m to a < m/b

if(a < m/b)

lub

if (b < m/a)

czepiać się nie powinno, bo nijak dopuszczalnych maksymalnych wartości nie przekroczy. Dodałbym też przypadek a x b = m (a = m/b), który jak wiadomo ma zwrócić 0.
Edit:
Na moje wypociny nie zwracajcie uwagi. Znalazłem przypadek. który dla a<10, b<10 i m<10 daje zły wynik.

0

Jest to jakiś postęp, ale dalej może być overflow w (a % m) * (b % m):

#include <iostream>
#include <climits>

#define ull unsigned long long int 

ull recmod(ull a,  ull b, ull m ) {
	if (a <= LONG_LONG_MAX / b){
	
		if  (a*b < m) {
			return a*b;

		} else {
			if (a>b) {
				return recmod(a-m, b, m);
			}
			else {
				return recmod(a,b-m,m);
			}

		}
	}
	else {
		return ((a % m) * (b % m)) % m;
	}
}

int main() {
  std::cout << recmod(13, 5, 4) << "\n";
}

1

Przy małych liczbach pewnie by wystarczyło takie coś:

#include <iostream>

int recmod(int a,  int b, int m ) {
if  (a*b < m) {
    return a*b;
    } 
else {
  return recmod(1, a*b-m, m);
  }
}

int main() {
  std::cout << recmod(5,4,7);
}

Przy większych - axb na 99.99% da overflow.
Chyba znalazłem:
https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/

0

Rozwiązanie.

Taki kod napisałem:

#include <iostream>

using namespace std;
long long p = 0, n = 0;
long long m(long long a, long long b, long long c)
{
    if (b == 0) {
        return 0;
    }
    if (b == 1) {
        return a % c;
    }
    else {
        p = b / 2;
        n = m(a, p, c);
        if (b % 2 == 0) {
            return (n + n) % c;
        }
        else {
            return (n + a + n) % c;
        }
    }
}
int main()
{
    long long a, b, c;
    cin >> a >> b >> c;
    if (c == 1 || a == 0 || b == 0) {
        cout << 0;
    }
    else
        cout << m(a, b, c) % c;
}

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