那天小面试了吧,遇到这么个问题:输入0则输出1,输入1则输出0,当时想出前三种,最近在思考到底有没有其他方法来解答。
1.最常见的IF-ELSE解法,最先进入脑海,当然,还有点傻傻的问HR,if-else判断算一种么?
1: #include <iostream>
2:
3: using namespace std;
4: int main()
5: {
6: int input;
7: cin >> input;
8: if (1 == input)
9: cout << 0;
10: else if (0 == input)
11: cout << 1;
12: else
13: cout << "invalid input";
14: cout << endl;
15: }
2.表驱动,这个也是瞬间进入脑海中,空间换时间。
1: #include <iostream>
2: #include <assert.h>
3:
4: using namespace std;
5: int main()
6: {
7: int invert_table[] = { 1, 0};
8: int input;
9:
10: cin >> input;
11: //Well, Test the input if the valid index!!!
12: //I ignored & just use the assert macro
13: assert(input==0 || input ==1);
14: cout << invert_table[input] << endl;
15: }
3.位运算,这个也是很容易想到,用一个合适的位运算符和相应的bit mask操作即可。
1: #include <iostream>
2: #include <assert.h>
3:
4: using namespace std;
5: int main()
6: {
7: int mask_num = 0x1;
8: int input;
9: cin >> input;
10: assert(0==input || 1 == input);
11: cout << (input^mask_num) << endl;
12: }
说是回来好好思考有没有其他方法的,结果一放就到今天,自己太懒!
思考的目的无非是尽可能使用最小的空间和最短的时间。显然,输入输出用byte来存储(上面的代码用了int;好吧,我还没苛刻到用1bit),运算尽可能一步直接输出,也就是使用更少的指令或者使用耗时更少的指令。
- IF-ELSE判断显然不可取,类似的方法如switch都不可取。
- table driven耗费的空间看起来很小,数据量比例可是很大!不可取。
- 位运算占用了额外的1个字节,然后通过异或,似乎还可以,但是仍然有很多不必要的操作。
这个问题很简单,推敲下,1和0的区别就是最小的一个bit位不同。最理想的方式是:输入到最小的bit位,然后最小的bit位取反。
又想:其实最快的就是编译器间就知道答案,元编程,可惜自己这方面所知甚少,而且用户输入到底是1还是0,编译期间无法知道。
其实用户输入0或者1,可以看作一个概率事件,理论上是0和1的概率都是1/2(忽略其他情况),但实际上不是。这条路有点远了。
又想:如果1和一个object,0是另外一个object,共同继承一个抽象基类,然后根据他们动态绑定输出结果不也不错么,呃,想得太离谱。
还是进入正路,之前我一直把1和0看作“数”。其实他们本身也是TRUE和FALSE。如果从这个角度来说,也有个比较好的解决方法。
1: #include <iostream>
2: #include <assert.h>
3:
4: using namespace std;
5:
6: int main()
7: {
8: bool input;
9: cin >> input;
10: cout << !input << endl;
11: }
这最后一个方法,当时没想出来,愣住了,有点抓狂,这么简单的方式,而且容错性还不错(当然,这里的容错性也是种错误!)
我坚信,必然有其他方法的,只是现在还没有想到!