Java 循环从0到100的数字,并使用递归在不使用模函数的情况下每三个数字打印一次
前几天我接受了一次面试,我问了一个问题,循环从0到100的数字,每三个数字打印一次。如果你知道模函数是什么,这是一个非常简单的问题。因此我提出了解决方案(注意我使用的是Java):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
对于(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 );
}
}