2014-11-21 2 views
0

Я пытаюсь создать программу, которая выводит период Pisano определенного пользователем номера в последовательности Fibonacci. Слова программы хороши, пока я не доберусь до 10. Программа пеет для бесконечности. Я проверяю массивы, когда у меня есть массив из 120 остатков (Pisano Period of 10 равно 60, поэтому, чтобы проверить, повторяются ли массивы, мне нужно как минимум 60 * 2 = 120 остатков). Но массивы не то же самое. Вот массивы (остаток, число от 1 до 60 и от 61 до 120)Ошибка вычисления периодов Java - Pisano

[1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1, 0] 
    [1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 0, 4, 4, 4, 8, 2, 0, 4, 4, 8, 4, 0, 6, 6, 2, 6, 0, 6, 6, 4, 4, 6, 0, 6, 4, 0, 4, 2, 4, 6, 0, 8, 4, 0, 4, 4, 8, 4, 2, 8, 4, 4] 

Вот мой код:

Основной код: `импорт java.util.Scanner;

общественного класса PisanoPeriod {

public static void main(String[] args) { 
    Scanner scan = new Scanner(System.in); 
    boolean quit = false; 
    while (!quit) { 
     System.out.print("Enter a number: "); 
     int divisor = scan.nextInt(); 
     FibonacciSequence f = new FibonacciSequence(); 
     System.out.println("Computing..."); 
     System.out.println("The Pisano Period for "+divisor+" is: "+f.getPisanoPeriod(divisor));    
     printDivisor(20); 
     System.out.print("Do you want to do another one? (y/n): "); 
     String reply = scan.next(); 
     if (reply.equals("n") || reply.equals("no")) { 
      printDivisor(20); 
      System.out.println("Bye!"); 
      quit = true; 
     } 
    } 

} 

private static void printDivisor(int n) { 
    System.out.print("\n"); 
    for (int i=1; i<=n; i++) { 
     System.out.print("*"); 
     if (i==n) { 
      System.out.print("\n\n"); 
     } 
    } 
} 
} 

И FibonacciSequence класс, где эта проблема может быть: `импорт java.util.Arrays;

общественного класса FibonacciSequence {

private double[] Sequence = new double[2]; 
private BadNumberException badnumexception = new BadNumberException("Number of fibonnacci numbers is too small."); 
private TooLittleNumbersException tlnexception = new TooLittleNumbersException(); 

public FibonacciSequence() { 
    try { 
     generate(10); 
    } 
    catch(BadNumberException e) {System.out.println(e.getMessage());} 
} 

private int getSequenceLength() { 
    return Sequence.length; 
} 

private boolean checkForPattern(int[] array) { 
    int half_point = array.length/2; 
    boolean return_boolean = true; 
    for (int i=0; i<half_point; i++){ 
     if (array[i]!=array[i+half_point]){ 
      return_boolean = false; 

      break; 
     } 
     else { 
      if (i==half_point-1) { 
       System.out.println(Arrays.toString(Arrays.copyOfRange(array, 0, half_point))); 
       System.out.println(Arrays.toString(Arrays.copyOfRange(array, half_point, array.length))); 
      } 
     } 
    } 
    if (array.length==120){ 
     System.out.println(Arrays.toString(Arrays.copyOfRange(array, 0, half_point))); 
     System.out.println(Arrays.toString(Arrays.copyOfRange(array, half_point, array.length))); 
    } 
    return return_boolean; 
} 

public int getPisanoPeriod(int n) { 
    int return_value = -1; 
    int max_index_counter=0; 
    boolean error = true; 
    while (error) { 
     try { 
      boolean pattern_reached = false; 
      int[] remainder_array = new int[0]; 
      int index_counter = 0; 
      while (!pattern_reached) { 
       if (index_counter>=max_index_counter) { 
        max_index_counter = index_counter; 
        System.out.println(max_index_counter); 
       } 
       int[] temp_array = new int[remainder_array.length+1]; 
       for (int i=0; i<remainder_array.length; i++) { 
        temp_array[i] = remainder_array[i]; 
       } 
       remainder_array = temp_array; 
       remainder_array[index_counter] = (int) (Sequence[index_counter]%n); 
       //System.out.println(Arrays.toString(Sequence)); 
       if (remainder_array.length%2==0 && index_counter>n) 
        pattern_reached = checkForPattern(remainder_array); 
       index_counter++; 
      } 
      return_value = remainder_array.length/2; 
      error = false; 
     } 
     catch (IndexOutOfBoundsException e) { 
      try { 
       throw tlnexception; 
      } catch (TooLittleNumbersException a) { 
       try { 
        //if (getSequenceLength()<50) 
        generate(getSequenceLength()+1); 
        /*else 
         error=false;*/ 
        //System.out.println(getSequenceLength()+10); 
       } catch (BadNumberException b) {} 
      } 
     } 
    } 
    return return_value; 
} 

public void generate(int n) throws BadNumberException { 

    if (n<=2) throw badnumexception; 
    double[] generated_array = new double[n]; 
    generated_array[0] = 1; 
    generated_array[1] = 1; 
    for (int i=2; i<n; i++) { 
     generated_array[i] = generated_array[i-1]+generated_array[i-2]; 
     //System.out.println(generated_array[i]); 
    } 
    Sequence = generated_array; 
} 
} 

Заранее спасибо за любые советы.

ответ

1

Проблема была, по-видимому с механизмом литья по линии remainder_array[index_counter] = (int) (Sequence[index_counter]%n);

Литой закругленные целое число вниз от двойной, так что остатки оказались различными в двух массивах. Я не мог долго использовать, так как у него не так много памяти. Поэтому вместо этого я использовал класс BigInteger для массива Sequence, и это решило проблему.

Смежные вопросы