那天小面试了吧,遇到这么个问题:输入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),运算尽可能一步直接输出,也就是使用更少的指令或者使用耗时更少的指令。

  1. IF-ELSE判断显然不可取,类似的方法如switch都不可取。
  2. table driven耗费的空间看起来很小,数据量比例可是很大!不可取。
  3. 位运算占用了额外的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: }

这最后一个方法,当时没想出来,愣住了,有点抓狂,这么简单的方式,而且容错性还不错(当然,这里的容错性也是种错误!)

 

我坚信,必然有其他方法的,只是现在还没有想到!