2011-10-04 69 views
6

我已写了一码来计算长度的总和,由此创建一个有效的方式来总结

syra(1) = 1

syra(2) = n + syra(n/2) if n%2==0

syra(3) = n + (n*3) + 1

例如。

  • syra(1)将产生1
  • syra(2)将产生2 1
  • syra(3)将产生3 10 5 16 8 4 2 1
  • 长度(3)将所有syra(1),syra(2),syra的总和(3),其是11.

下面的代码:

public static int lengths(int n) throws IllegalArgumentException{ 
    int syra = n; 
    int count = 0;  
    int sum = 0; 
    if (syra < 1){ 
    throw new IllegalArgumentException("Value must be greater than 0"); 
    }else{ 
    for (int i=1; i<=syra; i++){ 
     count = i; 
     sum++; 
     while (count > 1){ 
     if ((count % 2) == 0){ 
      count = count/2; 
      sum++; 
     }else{ 
      count = (count * 3) + 1; 
      sum++; 
     } 
     } 
    } 
    } 
    return sum; 
} 

问题是,如果我用700000的大值爆炸这些长度,它将需要很长时间并且对于已经出现在syra(3)中的syra(10),syra(5)...重复步骤。

如何微调代码来存储重叠序列的一些临时(数组)?

好的,根据这些信息,这里是我的另一个带有数组的修改后的代码,为什么它会产生数组索引超出限制的错误?

public class SyraLengths{ 

public static void main (String[]args){ 
    lengths(3); 
} 

public static int lengths(int n) throws IllegalArgumentException{ 
    int syra = n; 
    int count = 0; 
    int sum = 0; 
    int [] array = new int [syra+1]; 
    array[0] = 0; 
    if (syra < 1){ 
     throw new IllegalArgumentException("Value must be greater than 0"); 
     }else{ 


       for (int i=1; i<=syra; i++){ 
        count = i; 
        sum++; 

        while (count > 1){ 

         if(array[count] !=0){sum = sum + array[count];} 

         else if ((count % 2) == 0){ 
          count = count/2; 
          array[count]=sum; 
          sum++; 
         }else{ 
          count = (count * 3) + 1; 
          array[count]=sum; 
          sum++; 

          } 
         } 
       } 
      }return sum; 
} 

}

+2

'syra(2)= n + syra(n/2)'中的'n'是什么? –

+0

@Hemal - 阅读代码。 –

+0

谢谢,@Ed。不是数学家,我不知道什么是Syra函数,并认为我会根据规范检查代码。 –

回答

3

使用HashMap<Integer, Integer>来存储你已经计算出的结果,并试图重新计算之前查找值存在。这种技术被称为memoization

+2

它需要是'HashMap '。 –

+0

@Kublai Khan:更正;谢谢。 (我主要用C#编码,所以我忘了这个...) –

+3

一个简单的int数组会更快,更容易,更小。 –

1

你想要做的技巧叫做memoization

您将需要在某些数据结构中存储那些较小调用的输出,然后使用它而不是一遍又一遍地计算。

考虑使用LinkedHashMap专用构造函数accessOrder=True并覆盖removeEldestEntry()方法。阅读javadoc LinkedHashMap。这里有很好的描述。这样做,你可以很容易地只保留那些最常用的值,并保持你的缓存合理的小(即大多数使用1000个元素)。

相关问题