前几天我接受了一次采访,提出问题,循环显示从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的每个自然数。
答案 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);
}
}
}