这是一个LeetCode问题。 给定一个数字数组 nums,其中恰好有两个元素仅出现一次,而所有其他元素恰好出现两次。找到只出现一次的两个元素。
例如: 给定 nums = [1, 2, 1, 3, 2, 5],返回 [3, 5]。
我的代码是:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int axorb = 0;
for(auto i:nums)
axorb = axorb^i;
int differbit = (axorb&(axorb-1))^axorb;
int group3 = 0, group5 = 0;
for(auto i:nums)
if(differbit&i!=0) group5=group5^i;
else group3 = group3^i;
return vector<int>{group3, group5};
}
};
提交结果是错误答案。
Input: [0, 0, 1, 2]
Output: [3, 0]
Expected: [1, 2]
但是如果我只是将突出显示的部分更改为
if(differbit&i)
group5 = group5^i;
已接受。
我想了很多时间,还是没有任何想法。也许发生了一些类型转换?
这与运算符优先级有关。
因为在 C 早期,
&& and ||
运算符添加得很晚,所以它的优先级非常低,因此不会破坏遗留程序。
这个堆栈溢出问题对于原因有一个很好的答案:
来自此论坛:http://bytes.com/topic/c/answers/167377-operator-precedence
&& 和 ||后来由于其“短路”行为而添加了运算符。丹尼斯·里奇(Dennis Ritchie)回想起来承认,当添加逻辑运算符时,应该改变按位运算符的优先级。但由于当时存在数百千字节的 C 源代码以及三台计算机的安装基础,丹尼斯认为这对 C 语言来说变化太大了......
这里是表格显示运算符优先级。
显示
!=
的优先级高于 &
。
正如您所看到的,
bitwise &
低于桌子上的!=
,所以您的代码正在执行以下操作:
if ( differbit & (i!=0) )
而不是我认为你想做的事情:
if ( (differbit & i) != 0 )