循环遍历0到100之间的数字,并使用递归在没有模数函数的情况下打印每隔三个数字

时间:2016-01-30 21:42:28

标签: java algorithm recursion

前几天我接受了一次采访,提出问题,循环显示从0到100的数字并打印出每三个数字。如果您知道模数函数是什么,这是一个非常简单的问题。所以我提出了解决方案(注意我使用的是Java):

for (int i=0; i<100; i++) {
  if (i % 3 == 0) {
    System.out.println(i);
  }
}
然后他问,如果你不能使用除法或模函数,该怎么办?所以我不得不考虑这个约30秒,并提出了一个解决方案,我知道效率非常低,让他知道这是非常低效的,但是会起作用。

int x = 3;
for (int i=0; i<100; i++) {
  for (int j=0; j<33; j++) {
    if (x*j==i) {
      System.out.println(i);
      break;
    } 
  }
}

我可以在没有测试的情况下自由编写这个,所以它可能无法100%工作,但你知道我是如何解决这个问题的。他说他明白我要做的事情。然后他说使用递归函数还有另一种方法。他试图向我简单解释一下,但我不明白你如何使用递归函数来解决这个问题。任何人都可以使用递归提出解决方案吗?

编辑:

感谢所有答案!我并不认为这个问题会吸引尽可能多的关注,但我很欣赏所有答案。有些人并不明白你只能增加1.所以你必须循环遍历从0到100的每个自然数。

9 个答案:

答案 0 :(得分:4)

有一个cool trick to test if a number is divisible by three。如果所有数字的总和可以被3整除,那么原始数字可以被3整除。这可以递归应用:如果我有一个数字a,我可以将a的所有数字一起添加到b,并查看b是否可以被3整除。我怎么知道b是否可被3整除?将所有数字加在一起得到c,看看 c 是否可被3整除...

与所有递归一样,你必须在某个时刻停止。基本情况是当你有一个只有一位数的总和时 - 你可以有一个可被3整除的数字列表并检查这些数字。在代码中:

public boolean printDivisibleByThrees(){
    for(int i=0; i<100; i++){
        if(isDivisibleByThree(i)){
            System.out.println(i);
        }
    }
}

public boolean isDivisibleByThree(int i){
    if(i<0){
        i = -1*i; //we only care about the absolute value of i
    }
    if(Arrays.asList(0,3,6,9).contains(i)){
        return true;
    } else if(i<10){
        return false; //one digit number not divisible by three
    } else {
        int j = sumDigits(i);
        return isDivisibleByThree(j);
    }
}

public int sumDigits(int i){
    String iString = (new Integer(i)).toString();

    int sum = 0;
    for(char digit : iString.toCharArray()){
        sum += (new Integer(digit+"")).intValue();
    }

    return sum;
}

答案 1 :(得分:2)

使用第二个参数,如果数字是否为第三个

,将保留该参数
public class Rec
{

    public static void rec(int n, int t) {
        if(t==3) {
            System.out.println(n);
            t=0; // reset it
        }
        if(n!=100) {
            rec(++n, ++t);
        }
    }

    public static void main (String[] args)
    {
        rec(0, 3);
    }
}

答案 2 :(得分:2)

由于尚未选择答案,我想在这里加上我的两分钱。 由于技巧是使用递归而没有除法的模数函数(据我所知),这是我的解决方案:

public static void main(String[] args) {
    for ( int i = 1; i <=100; i++ ){
        if ( mod(i, 3) ){
            System.out.println(i);
        }
    }
}

public static boolean mod(int a, int b){
    if ( a < 0 ){
        return false;
    }else if (a==b){ 
        return true;
    }else{ 
        return mod( a-b, b );
    }
}

修改

此版本将在模数函数上处理0除以及负数:

public static boolean mod(int a, int b){
    if ( b < 0 ){
        b=b*-1;
    } 
    if ( a < 0 || b == 0){
        return false;
    }else if (a==b){ 
        return true;
    }else{ 
        return mod( a-b, b );
    }
}

答案 3 :(得分:1)

可以使用递归定义模运算符,如下所示:

// Assume a, b > 0
static int mod(a, b) {
  if (a < b) {
    return a;
  } else {
    return mod(a-b, b);
  }
}

那么你可以这样做:

for (int i=0; i<100; i++) {
  if (mod(i, 3) == 0) {
    System.out.println(i);
  }
}

答案 4 :(得分:1)

我想补充一个可能不寻常的答案,但每个范围都可以正常使用 代码是C ++(我来自移动设备,我只有一个C ++编译器),但它很容易理解并用Java重写。

#include <iostream>

void foo(int c, int n) {
    static int i = 0;

    if(c >= n) return;

    switch(i++) {
    case 1:
    case 2:
        foo(++c, n);
        break;
    case 0:
    case 3:
        std::cout << c << std::endl;
        i = 1;
        foo(++c, n);
    }
}

int main() {
    foo(0, 100);
}

答案 5 :(得分:1)

递归的另一种变体(JavaScript代码):

function f(m,i){
  if (i == 100){
    return;
  } else if (i == 3*m){
    console.log(i);
    f(m + 1,i + 1);
  } else {
    f(m,i + 1);
  }
}

f(0,0);

答案 6 :(得分:0)

为什么不这样做:

for (int i = 0; i < 100; i += 3) 
    System.out.println(i);

这样你就不必检查它是否是每隔三个数字,因为它每次都会增加3个。

答案 7 :(得分:0)

void printNth(int max, int n, int i, int sinceLastPrinted) {
    if (i>max) {
        return;
    }
    if (sinceLastPrinted == n-1) {
        System.out.println(i);
        sinceLastPrinted = -1;
    }
    printNth(max, n, i+1, sinceLastPrinted+1);
}

printNth(100, 3, 0, 0);

它还不是100%清楚是否应该包括最后一个数字(示例中为100)(如果是#34;第三个数字&#34;),具体取决于您可能需要修改的数字到:

    if (i>=max) {

并且还不太清楚从哪里开始&#34;每隔3&#34;? 0,3,6或2,5,8?我的功能的优点是可以通过传递i

的不同值来轻松修改它

答案 8 :(得分:-1)

这样可行。 !

public class Recursion {

 public static void main(String[] args) {
    myRecursiveMethod(0,1,100,3);
 }

 public static void myRecursiveMethod(int begin,int temp,int end,int n)  
 {  
    if(begin<=end)
    {
        if(temp==n)
        {
            System.out.println(begin);
            temp=0;
        }
        myRecursiveMethod(++begin,++temp,end,n);
    }

 }  

}