1.不用加减乘除做加法
写一个函数求两个整数之和,要求函数体内不得使用四则运算符号。
思路:利用位运算。第一步不考虑进位对每一位相加,可以利用异或符号;第二位考虑进位,只有1+1的时候才会产生一个进位,此时可以想象两个数先做位与运算,然后再向左移动一位。第三步把前面两个步骤的结果相加(相加即仍然重复上述两步,知道没有进位为止)。
class Solution { public: int Add(int num1, int num2) { /* 首先看十进制是如何做的: 5+7=12,三步走 第一步:相加各位的值,不算进位,得到2。 第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。 第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12。 同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111 第一步:相加各位的值,不算进位, 得到010,二进制每位相加就相当于各位做异或操作,101^111。 第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得 到1010,(101&111)<<1。 第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010)<<1。 继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果 */ int sum,carry; do { sum=num1^num2; carry=(num1&num2)<<1; num1=sum; num2=carry; } while(num2!=0); return num1; } };
2.构建乘积数组
给定一个A数组,构建一个B数组,其中B[i]=A[0]×A[1]×...×A[i-1]×A[i+1]×...×A[n-1],不能用除法。
思路:分成两部分,一部分是A[0]×A[1]×...×A[i-1],另一部分是A[i+1]×...×A[n-1]。令C[i]=A[0]×A[1]×...×A[i-1],C[i]=C[i-1]*A[i-1];令D[i]=A[i+1]×...×A[n-1],D[i]=D[i+1]×A[i+1]
class Solution { public: vector<int> multiply(const vector<int>& A) { int len=A.size(); vector<int> B(len,1); for(int i=1;i<len;i++) { B[i]=B[i-1]*A[i-1];//左面部分 } int temp=1; for(int i=len-2;i>=0;i--) { temp*=A[i+1]; B[i]*=temp;//右面部分 } return B; } };