Que esta mal en este codigo o que me falta??? JAVA es con recursividad

Iniciado por FiitcherxX, 15 Septiembre 2018, 01:36 AM

0 Miembros y 1 Visitante están viendo este tema.

FiitcherxX

Código (java) [Seleccionar]


public class Primos {

   public static int SumaArreglo(int a[]) {
       return SumaArreglo(a, a.length - 1);
   }

   public static int SumaArreglo(int a[], int i) {
       if (i == 0)
       {
       return a[0];
       }
        else if (Primo(a[i]) == true) {
           return a[i] + SumaArreglo(a, i - 1);
       } else {
           return SumaArreglo(a, i - 1);
       }
   }

   public static boolean Primo(int n, int contador) {

       if (contador == 1) {
           return true;
       } else if (n % contador == 0) {
           return false;
       } else {
           return Primo(n, contador - 1);
       }
   }

   public static boolean Primo(int n) {
       if (n == 1) {
           return true;
       } else {
           return Primo(n, n / 2);
       }
   }

   public static void main(String[] args) {
       int A[] = {10,7,8,23,9,2};
       showMessageDialog(null, SumaArreglo(A));
   }
}



[MOD] para publicar código se usan las etiquetas GeSHi.

Mr.Moonlight

#1
por favor usa las etiquetas código GeSHi para poner fragmentos de código ya que de no ser así el código no es 100% correcto ya que se pueden producir errores como el producido en esta linea de codigo
Código (java) [Seleccionar]

 else if (Primo(a[i]) == true)

en la que ha interpretado a[ i ] como si estuvieras utilizando una letra cursiva

Serapis

De entrada te diré que no tienes errores de sintaxis, los errores que tiene son semánticos...

Lo primero es el nombre de la función: SumaArreglo... es falso.
Al final lo que (intenta) suma, son los números primos que contenga el array, luego procede cambiar el nombre de la función a lo que hace realmente, ergo: SumaPrimosDelArreglo

Luego mirando del final hacia arriba (funcion... Primo(int n)), tienes esta línea:
Código (java) [Seleccionar]
return Primo(n, n / 2); //raízcuadrada, no división entre 2
No. El valor mayor con posibilidades de ser divisor, para un valor dado no es la mitad de ese, sino su raíz cuadrada... por ejemplo; para 100, no es 50 (100/2), si no 10 (sqr(100)).

Es decir, calcula previamente la raíz cuadrada y si el resultado es par, ni siquiera necesitas invocar la sobrecarga, porque el único primo par es el 2. Luego ya es cuando puedes invocar a la sobrecarga de primo, con 'n' y el valor precalculado como máximo divisor posible, y así...  para que revise el resto... de posibles divisores.
...luego modificamos bastante la función...
Código (java) [Seleccionar]

public static boolean Primo(int n) {
       int v;

       if (n == 1) {
           return true;
       } else {
          if ((n & 1) == 0 ){  //  'n' es par ????
              if (n == 2) {      // 'n' es 2 ???
                 return true;
              } else {
                 return false;
              }
           } else {                   // entonces calcular si tiene divisores...
               v = Math.sqrt(n);
               return Primo(n, v);
          }
       }
   }


Finalmente en la sobrecarga de SumaArreglo (SumaArreglo(int a[], int i)), también hay otro error... asumes que el índice cero del array es primo... Es fin de la recursión, vale, pero nada se sabe sobre si es primo o no...
Es decir has ido calculando todos los valores del array por encima de ese, y cuando llegas al último (de la recursividad, el primero del array), simplemente devuelves ese valor. .....fíjate que en la lista que le pasas (por ejemplo)... el primeor es 10, luego estarás sumando 10 además del resto de primos.

Ese valor también debe ser probado si es o no primo, luego la línea:
Código (java) [Seleccionar]
return a[0];
Debe ser cambiada por una ligera modificación del código que tienes debajo:
Código (java) [Seleccionar]

       if (Primo(a[i]) == true) {
           return a[i] ;  // nota que i vale 0, da igual poner a[0], que a[i]
       } else {
           return 0;


...y listo...

p.d.: Nota que hay más optimizaciones (simples) que pueden hacerse, igual que descubrimo si es par... podemos descubrir si es múltiplo de 3 y/o de 5.... de 5 es fácil pués basta saber si acaba en 5 (si acaba en 0, ya cae en el tratamiento de par)...
Para el caso del 3 hay que sumar sus cifras, si tras sumas todas las cifras de 'n', son múltiplo exacto de 3, entonces 'n' tiene como divisor al 3, luego salvo que n== 3, no es primo...