最近我参加了一次面试,他们让我写了一个如下的程序,
通过不断添加数字中的数字的平方来创建数字链 形成一个新的数字,直到它以前见过。
示例:
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.
答案 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个所有序列,确实包含您发布的两个示例,但遗憾的是它并不总是在1
或89
处终止。
答案 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));
}
}