在java中添加数字的平方

时间:2015-06-30 12:14:34

标签: java

最近我参加了一次面试,他们让我写了一个如下的程序,

通过不断添加数字中的数字的平方来创建数字链 形成一个新的数字,直到它以前见过。

示例:

44 - > 32 - > 13-> 10→ 1

85-> 89-> 145-> 42-> 20-> 4-> 16-> 37-> 58-> 89

因此,任何到达1或89的链都将陷入无限循环。 最令人惊讶的是,每个起始号码最终都会达到1或89。 写一个程序来计算10000以下的起始数将到达89?

我写了下面的程序,

int num =44;
        int array[] = new int[100];
        int power=0;
        while(num > 0)
        {
            int mod = num % 10;
            int div = num /10;
            int sum =(mod * mod) + (div * div);

            num =sum;

            System.out.print(" => "+sum);

            if(array.equals(sum)) 
                // should not use any functions like Arrays.asList(array).contains(sum);
                return; 
            else
            {
                //System.out.println("else");
                array[power++] =sum;
            }

        }

我知道上面的程序不能满足他们的要求。有人告诉我好的代码片段以使代码满意(如果将来有同样的问题)。?

注意should not use any function or import. Only logic is need.

5 个答案:

答案 0 :(得分:1)

  

维护已计算数字的缓存。这将减少已经计算的不必要的迭代次数。

Let's do some math
From you example
44 -> 32 -> 13-> 10-> 1

85->89->145->42->20->4->16->37->58->89 

You already know that the numbers 85, 89, 145, 42, 20, 4, 16, 37, 58 lead to 89 and 44, 32,13, 10, 1 don't.

In some case say calculating it for 11.

11 - 2 - 4

Now we already know 4 leads to 89 and so we skip all the other unnecessary iteration from 
4 - 16 - 37 - 58 - 89 and also we now know that 11, 2also lead to 89. 

所以没有算法:

while(num > 0)
{
    if(calculate[i] == 1)//which mean leads to 89
    {
    //   dont calculate again
    }
    else
    {
     // num =  // your squares logic
    }
}

答案 1 :(得分:0)

如果要生成序列,则使用Iterable

是有意义的
public static class SquaredDigitsSequence implements Iterable<Integer> {

    int start;

    SquaredDigitsSequence(int start) {
        this.start = start;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new SquaredDigitsIterator(start);
    }

    static class SquaredDigitsIterator implements Iterator<Integer> {

        int last;
        Set<Integer> seen = new HashSet<>();

        SquaredDigitsIterator(int start) {
            last = start;
            seen.add(last);
        }

        @Override
        public boolean hasNext() {
            return !seen.contains(step());
        }

        @Override
        public Integer next() {
            last = step();
            seen.add(last);
            return last;
        }

        int step() {
            int next = 0;
            for (int x = last; x != 0; x /= 10) {
                next += (x % 10) * (x % 10);
            }
            return next;
        }
    }
}

public void test() {
    for (int i = 0; i < 100; i++) {
        System.out.print(i + " ");
        for (int x : new SquaredDigitsSequence(i)) {
            System.out.print(x + " ");
        }
        System.out.println();
    }
}

这会打印最多100个所有序列,确实包含您发布的两个示例,但遗憾的是它并不总是在189处终止。

答案 2 :(得分:0)

我将此视为递归问题。我假设您只想知道达到1或89之前的步数。

辅助方法getDigits()只是为了简单起见。转换为String在技术上并不是必需的,但它使代码变得简单。

public static void main(String[] args) {
    int v = 9843;
    int[] count = {0};

    System.out.println("Number of steps: " + countSteps(v,count)[0]);
}

private static  int[] countSteps(int initialValue, int[] count){
    if(initialValue == 1 || initialValue == 89){
        return count;
    }
    count[0]++;
    int[] digits = getDigits(initialValue);
    initialValue = 0;
    for (int k : digits) {
        initialValue += k * k;
    }

    countSteps(initialValue,count);

    return count;
}

private static int[] getDigits(int i){
    String s = Integer.toString(i);
    int[] digits = new int[s.length()];
    for(int j=0;j<s.length();j++){
        digits[j] = s.charAt(j) - '0';
    }
    return digits;
}

答案 3 :(得分:0)

class SquareDigits{
   public static void main(String[] args){
      System.out.println("Amount of numbers ending on 89: " + loop(10000));
   }

   public static int loop(int limit){
      int cnt = 0;
      for(int i = 1; i < limit; i++){
         if(arriveAt89(i))
            cnt++;
      }
      return cnt;
   }

   public static boolean arriveAt89(int num){
      while(num != 89 && num != 1){
         num = addSquares(num);
      }
      if(num == 89)
         return true;
      return false;
   }

   public static int addSquares(int n){
      int sum = 0;
      for(Character c : ("" + n).toCharArray()){
         sum += Character.getNumericValue(c)*Character.getNumericValue(c);
      }
      return sum;
   }

}

Assuming you're just after the amount of numbers that ends with 89.

答案 4 :(得分:0)

This prints all numbers that end up in 89 below 89.

//array =  boolean array to hold cache 
//arr= list to store numbers in the chain that goes up to 89 used in setting cache

public static void main(String args[]) {   
    Boolean[] array = new Boolean[100];
    Arrays.fill(array, Boolean.FALSE);
    for(int i=2;i<89;i++){
      checkChain(i,array);
    }
    for(int k=0;k<89;k++){
      if(array[k]){System.out.println(k);}
    }
}

  private static void checkChain(int num,Boolean[] array) {
   List<Integer> arr= new ArrayList<Integer>();
    int initial = num;
    int next;
do{
  next=0;
  arr.add(num);
    while(num>0){     
      if(array[num] || num==89){
        for(Integer j:arr){
          array[j]=true;
        }
        break;
      }
      next = next+(num%10)*(num%10);
      num=num/10;
    }
    num=next;
    if(next<initial && array[next]){
      array[initial]=true;
      break;
    }
    }while((next>initial));

  }
}