a-b-problem &&/permutation-index&&count-1-in-binary

给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。

样例

如果 a=1 并且 b=2,返回3

注意

你不需要从输入流读入数据,只需要根据aplusb的两个参数a和b,计算他们的和并返回就行。

挑战
 1 class Solution {
 2     /*
 3      * param a: The first integer
 4      * param b: The second integer
 5      * return: The sum of a and b
 6      */
 7     public int aplusb(int a, int b) {
 8         // write your code here, try to do it without arithmetic operators.
 9         if(b==0) {
10             return a;
11         }else{
12             return aplusb(a^b,(a&b)<<1);//a^b是进行异或运算,再加上(a&b)<<1就实现了进位
13         }
14     }
15 };

 

显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?

排列序号

给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。

样例

例如,排列[1,2,4]是第1个排列。//这道题其实考察的是字典全排列,当然我的解法并不是正常的思路,常规的算法应该是将这个数字序列的所有字典全排列算出来,去看看所给的是第几个。

http://www.geekviewpoint.com/java/numbers/permutation_index 具体介绍见链接,

 1 public class Solution {
 2     /**
 3      * @param A an integer array
 4      * @return a long integer
 5      */
 6     public long permutationIndex(int[] A) {
 7         // Write your code here
 8        /* long index =0;
 9         long position = 2;
10         long facrtor=1;
11         for(int q = A.length-2;q >= 0; q --){
12             long number = 0;
13             for(int p = q+1;p<q;p++)
14         }*/
15          long index = 0;
16          long position = 2;
17          long factor = 1;
18          for (int p = A.length - 2; p >= 0; p--) {
19          long successors = 0;
20          for (int q = p + 1; q < A.length; q++) {
21                if (A[q] > A[p]) {
22                   number++;
23                 }
24             }
25             index += (number * factor);
26              factor *= position;
27             position++;
28         }
29        index = index + 1;
30        return index;
31     }
32 }

后续明天继续更新相关的字典排序问题

3、二进制中有多少个1

计算在一个 32 位的整数的二进制表式中有多少个 1.

这道题在最开始的我使用的算法是通过将这个数字从最低位逐位和1做与运算,然后计算得到位数。然而这种方法并没有通过平台的测试,在91%的数据就出现了超时,因为在遇到-1这样的数字(32个1),程序的运行时间就超时。

然后我就开始百度这道题,并且发现关于这道题的算法,编程之美也有专门的介绍。看似简单的一道题其实解法还是挺多的。

 1 class Solution {
 2 public:
 3     /**
 4      * @param num: an integer
 5      * @return: an integer, the number of ones in num
 6      */
 7     int countOnes(int num) {
 8         // write your code here
 9         int count = 0;
10     
11         while(num){
12             num =num&(num-1);
13             count++;
14         }
15         return count;
16     }
17 };

问题:求一个32位2进制整数中 1的个数

1. HAKMEM算法:

 1 int Count(unsigned x)
 2 {
 3     unsigned n;    
 4 
 5     n = (x >> 1) & 033333333333;    
 6     x = x - n;   
 7     n = (n >> 1) & 033333333333;   
 8     x = x - n;    
 9     x = (x + (x >> 3)) & 030707070707;   
10     x = modu(x, 63);  
11     return x;   
12 }  

 

说明:首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。

因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。

这个程序只需要十条左右指令,而且不访存,速度很快。

 

2.

1 int Count(unsigned x)
2 { 
3  x = x - ((x >> 1) & 0x55555555);
4  x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
5  x = (x + (x >> 4)) & 0x0F0F0F0F;
6  x = x + (x >> 8);
7  x = x + (x >> 16);
8  return x & 0x0000003F;
9 }

 

说明: 这里用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了

posted @ 2015-11-14 23:57  码代码的banana  阅读(176)  评论(0编辑  收藏  举报