XORの概要

XORプロパティ:同じは0、差は1(キャリー加算なし)

1. 0 ^ 0 = 0 0 ^ 1 = 1なので、0 ^任意の数=任意の数。

2. 1 ^ 0 = 1 1 ^ 1 = 0なので、1 ^任意の数=任意の数は逆になります。

3.任意の数^任意の数= 0。

4. 10100001の2番目と3番目のビットを反転するなど、特定のビットを反転するために使用すると、数値と00000110の間でビット単位のXOR演算を実行できます。

5.ビット単位のXOR演算により、一時変数を使用せずに2つの値を交換できます。

6. XOR演算の機能:同じ数のXORを2回(a = a ^ b ^ b)、元の値aのままにします。

7. XORは交換可能です:a ^ b = b ^ a。

例1:一時変数を使用せずにaとbの値を交換します。
a = 10100001
b = 00000111
a = a ^ b; // a = 10100110
//このステップでは、abの元の値の同じビットを0として記録し、異なるビットを1として記録します。//
そしてそれをaに保存します。bの値このステップに変更はありません。//1^
任意の数=任意の数が反転しているため0 ^任意の数=任意の数
b = b ^ a; // b = 1010001
// aは1を使用して、元の値の対応するビットが異なる部分
//排他的論理和演算は、(元のa)と同じ部分をbに保持し、//(元のa)の異なる部分を反転する
ことです//つまり、bを元のaにプログラムします
a = a ^ b // a = 00000111
//この時点でaは類似点と相違点を表すため、bは元のaを表します
//同様に、2番目のステップでは元のb値を取得し、それをaに割り当てて変換を実行できます

LeetCode-インタビューの質問16.01。交換番号

タイトルの説明:
一時変数を使用せずに関数を記述し、aとbの値をnumbers = [a、b]で直接交換します。

ヒント:
numbers.length == 2

例:
入力:numbers = [1,2]
出力:[2,1]

コードは次のように表示されます。

class Solution {
    
    
public:
    vector<int> swapNumbers(vector<int>& numbers) {
    
    
        numbers[0]=numbers[0]^numbers[1];
        numbers[1]=numbers[0]^numbers[1];
        numbers[0]=numbers[1]^numbers[0];
        return numbers;
    }
};

結果:
ここに画像の説明を挿入

例2:任意の数
排他的論理和はそれ自体が0に等しい。つまり、配列内の各数値を最初から最後までXORすると、2回出現する数値はすべて、XORでキャンセルされるため、最終結果は1回だけ出現する数値になります。

#include<iostream>
#include<vector>
using namespace std;
int main(){
    
    
	int res = 0;
	vector<int> v{
    
     1,2,2,3,1,8,8 };
	for (int i = 0; i < v.size() ; i++){
    
    
		res ^= v[i];
		cout << res << " ";
	}
	return 0;
}

例3:LeetCode-インタビューの質問17.04。不足している番号

タイトルの説明:
配列numsには、0からnまでのすべての整数が含まれていますが、1つが欠落しています。不足している整数を見つけるためのコードを記述してください。O(n)時間でできますか?
例1:
入力:[3,0,1]
出力:2
例2:
入力:[9,6,4,2,3,5,7,0,1]
出力:8
コードは次のとおりです。
方法1 :(機能6を使用してXORを使用)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int ans=0;
        for(int i=0;i<size;i++){
    
    
            ans^=i;
            ans^=nums[i];
        }
        ans^=size;
        return ans;
    }
};

方法2 :( 0からnの合計からnums配列の合計を引いたもの、つまり欠落している数)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int sum1=0,sum2=0;
        for(int i=0;i<size;i++){
    
    
            sum1+=nums[i];
            sum2+=i;
        }
        return sum2+size-sum1;
    }
};

方法3 :(欠落している数を直接見つけますが、参考のために、時間計算量はO(n)を超えています)

class Solution {
    
    
public:
    int missingNumber(vector<int>& nums) {
    
    
        int size=nums.size();
        int ans=-1;
        sort(nums.begin(),nums.end());
        for(int i=0;i<size;i++){
    
    
            if(nums[i]!=i){
    
    
                ans=i;
                break;
            }
        }
        if(ans==-1){
    
    
            return size;
        }
        return ans;
    }
};

実行結果:
ここに画像の説明を挿入
例4:LeetCode——389。違いを見つける

タイトルの説明:
2つの文字列sとtが与えられた場合、それらには小文字のみが含まれます。
文字列tは文字列sによってランダムに再配置され、文字がランダムな位置に追加されます。
tに追加された文字を見つけてください。

例1:
入力:s = "abcd"、t = "abcde"
出力: "e"
説明:「e」は追加された文字です。

例2:
入力:s = ""、t = "y"
出力: "y"

例3:
入力:s = "a"、t = "aa"
出力: "a"

例4:
入力:s = "ae"、t = "aea"
出力: "a"

コードは次のように表示されます。

class Solution {
    
    
public:
    char findTheDifference(string s, string t) {
    
    
        char ch=0;
        for(int i=0;i<s.size();i++){
    
    
            ch^=s[i];
        }
        for(int j=0;j<t.size();j++){
    
    
            ch^=t[j];
        }
        return ch;
    }
};

結果:
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/FYPPPP/article/details/110948903