位運算的應用:集合運算
阿新 • • 發佈:2019-01-05
問題:如何通過位運算求兩個集合的交集、並集、差以及對稱差呢?
執行截圖:
其實很簡單,步驟如下:
①將所有可能出現的元素從1~n編上號
這裡我們假設所有可能的元素為'0'~'9','A'~'Z','a'~'z'
則編號為'0'~'9':0~9 'A'~'Z':10~35 'a'~'z':36~61
②利用一個整數儲存一個集合的資訊
C++中long long型別佔有64個位元位,第i個位元位就表示了對應字元的有無:1代表有,0代表無
③利用兩個整數的位運算即可表示相應集合的運算
"集合的交" --- (a & b)
"集合的並" --- (a | b)
"集合的差" --- a & (~b)
"集合的對稱差" --- (a | b) & (~(a&b))
④根據整數的運算結果反寫出集合的運算結果即可
注意:系統預設只支援32位的移位運算,因此將1左移32位以上時:
1 << 40(×)
long long one = 1; one << 40; (√)
C++11程式碼如下:
/*C++11*/ #include <iostream> #include <string> #include <cctype> using namespace std; //改進1:將字元操作改為string操作 //'0'~'9':0~9 'A'~'Z':10~35 'a'~'z':36~61 char getKey(int i) { if (i <= 9) return '0' + i; else if (i <= 35) return 'A' + i - 10; else return 'a' + i - 36; } //從字串中得到64位的位元串 long long input() { string a; cin >> a; long long tmp = 0, one = 1; for (auto p : a) { //改進2:判斷'0'~'9'/'A'~'Z'/'a'~'z'時運用isnum(),isupper(),islower()函式 if (isdigit(p)) tmp |= one << (p - '0'); else if (isupper(p)) tmp |= one << (p - 'A' + 10); else if (islower(p)) tmp |= one << (p - 'a' + 36); } return tmp; } //相應的字元集合 string output(long long a) { string tmp = "{"; long long one = 1; for (int i = 0; i <= 61; ++i) { if (a & (one << i)) tmp = tmp + getKey(i) + ','; } if (*(tmp.end() - 1) == ',') *(tmp.end() - 1) = '}'; else tmp += '}'; return tmp+"\n"; } //笛卡兒積 string outputDsc(long long a, long long b) { string tmp; long long one = 1; for (int i = 0; i <= 61; ++i) for (int j = 0; j <= 61; ++j) if ((a&(one << i) && (b&(one << j)))) tmp = tmp + '<' + getKey(i) + ',' + getKey(j) + '>' + ','; if (!tmp.empty()) tmp.erase(tmp.end() - 1, tmp.end()); return '{'+tmp+"}\n"; } int main() { long long a = 0, b = 0; cout << "輸入集合A:"; a = input(); cout << "輸入集合B:"; b = input(); //改進3:使用位運算代替雙重for迴圈查詢 cout << "集合A:" << output(a); cout << "集合B:" << output(b); cout << "集合的交:" << output(a & b); cout << "集合的並:" << output(a | b); cout << "集合的差:" << output(a & (~b)); cout << "集合的對稱差:" << output((a | b) & (~(a&b))); cout << "集合的笛卡爾積:" << endl << outputDsc(a, b); system("pause"); return 0; }
謝謝觀看~