很久前一个同学面试回来,他说面试官给他出了一道很让他费解的题。
题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
当时我听了,也傻了,怎么可以这样呀?觉得这个东西没有什么用呀,在一般写程序时都不会这样,觉得没有什么意义。后来并没有放在心上。
某天,在想知识点的结构树时候,遇到了一个组合模式,这个东西很好,可以建立一棵树。当完成构造这棵树,好像略有所感,觉得面向对象真的很不错的东西,就这样就可以不用if语句,有点妙。
突然,想到了这个搁置得有点尘的问题。如果这棵对每个父结点只有一个孩子,然后每个孩子只有一个孩子,这样在递归的跳出也就有了希望。越想觉得这个问题越有意思。这样就不用if的关键字。也就是说,对于递归的条件都满足了,而且还没有if等条件的关键字了。自然递归可以让循环的关键字消去。此时想到自然数的概念,其实想得真的很容易,一旦付之行动,做起来不容易。
package com.lr.test;
public interface INode {
int sum();
public void setNextNode(INode nextNode) ;
}
package com.lr.test;
public class Node implements INode {
private INode nextNode = null;
private int value = 0;
public Node(int value) {
this.value = value;
}
public INode getNextNode() {
return nextNode;
}
public void setNextNode(INode nextNode) {
this.nextNode = nextNode;
}
@Override
public int sum() {
return value + nextNode.sum();
}
}
package com.lr.test;
public class EndNode implements INode {
private int value = 0 ;
public EndNode(int value){this.value = value ;}
@Override
public int sum() {
// TODO Auto-generated method stub
return value;
}
@Override
public void setNextNode(INode nextNode) {}
}
package com.lr.test;
public class Test {
public static void main(String[] args) {
INode node3 = new Node(3) ;
INode node2 = new Node(2) ;
INode node1 = new Node(1) ;
INode node0 = new EndNode(0) ;
node3.setNextNode(node2);
node2.setNextNode(node1);
node1.setNextNode(node0);
int a = node3.sum() ;
System.out.println(a);
}
}
这样对于各个节点就得用for,创建了,如果一个一个对象创建,这个跟s=1+2,s+=3.没有区别。
这个思路就到这里了。
经过思考,一个很吸引我的竟是static这个关键字,瞬间有了想法。可以在类中用一个静态变量,当一个节点创造时就让里面变量相加,如果创建100这样的对象就达到了目的。想了就试试去做。
public class Node2 {
private static int value = 0;
private static int s = 0;
public Node2() {
value++;
s += value;
}
public static int sum() {
return s;
}
}
但有一点,我忽略了,这个该死的java虚拟机这里向内存申请了数组的空间,创建只是100个指针,并没有创建对像,如下如测试一下:
Node2[] node = new Node2[100] ;
System.out.println(node[0]);
有些时候,人很奇怪的,觉得不懂的东西越多了,越会觉得在未知的下一步会给我们一个很大的惊讶,事实也真是这样!
经过很多次看似完成了,但是还是没有完成。过了些天,在看操作优先级的时候,一个“||”,启发了我,这个东西很奇怪,如果第一个操作数为真了,后就不执行了,否则执行后面的。与“||”为兄弟还有一个“&&”。这个又满足了两上面所述的关系了。产生下面的一段代码:
public class testAdd {
boolean b = false;
int sum = 0;
int s = 0;
public int sum(int start, int end) {
b = (start < end) && (s != (sum = sum(start, end - 1)));
return end + sum;
}
public static void main(String[] args) {
System.out.println(new testAdd().sum(1, 3));
}
}
注意到,java中的布尔型与数值没有什么关系,不太像C与C++ 。
现在觉得面向对象思想淡了很多,还是用C吧。由最初的组合到现在的结构化,原来这个问题能让人有一个这样的飞越。
#include<stdio.h> int s = 0 ; int sum(int n) { n && sum(n-1); return s += n; } int main() { int n = 100; printf("%d",sum(n)) ; return 0; }
好了,到C,果然是一道很让人的思维发散的题目,这样可以用数字与布尔型的关系了,在C中,0就是表于false.非0表示true.这样就结合一下数组吧!如下的实现:
#include<stdio.h> int add1(int) ; int add2(int) ; typedef int (*p_func)(int); p_func p_add[2] ; int main(){ p_add[0] = add1 ;//跳出递归 p_add[1] = add2 ;//继续递归 printf("%d",sum(100)) ; return 0 ; } int add1(int a){ return sum(--a) ; } int add2(int a){ return a ; } int sum(int a){ return a + p_add[!a](a) ; }
思维,奔腾,光芒散发,无边无际。
跳出,框架,成就思维,不一般的畅游。
或者,未知的下一步更让人称妙!
生活与人生,或许……..