Java 循环从0到100的数字,并使用递归在不使用模函数的情况下每三个数字打印一次

Java 循环从0到100的数字,并使用递归在不使用模函数的情况下每三个数字打印一次,java,algorithm,recursion,Java,Algorithm,Recursion,前几天我接受了一次面试,我问了一个问题,循环从0到100的数字,每三个数字打印一次。如果你知道模函数是什么,这是一个非常简单的问题。因此我提出了解决方案(注意我使用的是Java): 对于(int i=0;i可以使用递归定义模运算符,如下所示: // Assume a, b > 0 static int mod(a, b) { if (a < b) { return a; } else { return mod(a-b, b); } } //假设a,b>0

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


对于(int i=0;i可以使用递归定义模运算符,如下所示:

// Assume a, b > 0
static int mod(a, b) {
  if (a < b) {
    return a;
  } else {
    return mod(a-b, b);
  }
}
//假设a,b>0
静态整数模(a,b){
if(a
那么你可以做:

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

for (int i = 0; i < 100; i += 3) 
    System.out.println(i);
for(int i=0;i<100;i+=3)
系统输出打印LN(i);

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

使用第二个参数,如果该数字是否是第三个,则该参数将保持不变

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);
    }
}
最后一个数字(本例中为100)是否应包括在内(如果是“第三个数字”),也不是100%清楚,这取决于您可能需要修改为:

    if (i>=max) {
而且也不太清楚“每隔3次”从何处开始?0、3、6或2、5、8?我的函数的优点是,可以通过为
i
传递不同的值来轻松修改它。这将起作用

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);
    }

 }  

}
公共类递归{
公共静态void main(字符串[]args){
myRecursiveMethod(0,1100,3);
}
公共静态void myRecursiveMethod(int begin、int temp、int end、int n)
{  

如果(begin我想再添加一个可能不寻常的答案,但适用于每个范围。
代码是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);
}
#包括
无效foo(内部c,内部n){
静态int i=0;
如果(c>=n)返回;
开关(i++){
案例1:
案例2:
foo(++c,n);
打破
案例0:
案例3:
std::cout有a。如果它的所有数字之和都可以被3整除,那么原始的数字就可以被3整除。这可以递归地应用:如果我有一个数字
a
,我可以把
a
的所有数字加在一起,得到
b
,看看
b
是否可以被3整除。我如何知道
b
是否可以被3整除e除以3?将它的所有数字相加得到
c
,看看
c
是否可以被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;
}
public boolean printDivisibleByThrees(){

对于(int i=0;i,因为还没有选择答案,所以我想在这里加上我的两分钱。 由于技巧是使用递归和无除法(据我所知)来实现模函数,因此我的解决方案如下:

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 );
    }
}
publicstaticvoidmain(字符串[]args){

对于(inti=1;i递归的另一个变体(JavaScript代码):

函数f(m,i){
如果(i==100){
返回;
}否则如果(i==3*m){
控制台日志(i);
f(m+1,i+1);
}否则{
f(m,i+1);
}
}
f(0,0);


我不想破坏你对heureka的感觉,所以我不会发布实际的代码,但是,他暗示要使用递归!!!尝试发布一些使用递归的代码,然后我们可能会对其进行优化/修复。提示:在递归中传递一个参数自上次打印以来已经执行了多少步;)不错,但下一个问题可能是:如果你有一个迭代器怎么办?他写道,循环0到100是一个要求,通常你必须在测试场景中坚持这一点他还写道“使用递归”是的,你必须循环每一个数字,一次一个。你不能用3.2、5、8等的增量除以3,所有的数字都有一个余数。这是行不通的。
如果(mod(i+1,3)==0)
可能行得通。@JasonHeddle,从问题中不清楚什么是“每三个”,我会接受这一点,但如果我在面试,我也会寻找一位候选人,他会就此(以及)提出一个澄清问题。这与@JasonHeddle关于+=3用法的回答相同,+添加了一些递归,如果你能做+=3,则不需要这些递归:)@Gavriel这是一个循环,这是递归。我想这个解决方案非常满足这个问题。这是一个尾部递归,在这种情况下,IMHO没有任何意义,事实上,它只表明候选者不熟悉递归。这不起作用。至少,它必须是
rec(++n,+++t);
而不是
rec(n++,t++)
System.out.println(n);
而不是
t
。事实上,它是错误的。这将打印:3,6,但它在beginning@skypjack:谢谢-没有编译代码就写了。现在修复。为什么需要
sum+=(新整数(数字+)。intValue();
?为什么不够:
sum+=digit-48;
?还有一个优化:拉出
数组。asList(0,3,6,9)
,GC在每次调用中都这样做是浪费时间的。让它成为一个常数。我在这里不是为了效率,我是为了清晰!此外,使用ASCII码可能会减少一些时钟周期,但会降低算法的复杂性。数组的事情也不会增加复杂性,而且可能会由co优化到一个常数mpiler无论如何。
b=b*-1
=>
b=-b
,但无论如何都太复杂了。我会选择:
if(a>b)返回mod(a-b,b)else if(a==b)返回true,否则返回false;
这对眼睛来说可能很复杂,但对于编译器来说,这将是较小的步骤,因为最终条件首先出现。不过,竖起大拇指看
b=-b
。这将打印:100100100,就像您总是打印n一样,也许您指的是c?
#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);
}
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;
}
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 );
    }
}
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 );
    }
}