# Quine-McCluskey I hate this.cpp: ```=cpp #include <iostream> #include <vector> #include <sstream> #include <algorithm> #include <set> #include <bitset> using namespace std; int n; void generateNumbers(const string& input, vector<int>& output) { int count = 0; for (char ch:input) if (ch == '-') count++; int poss = pow(2, count); for (int i=0; i<poss; i++) { string binary = bitset<32>(i).to_string().substr(32 - count); string result = input; int binaryIndex = 0; for (char& ch:result) { if (ch == '-') { ch = binary[binaryIndex]; binaryIndex++; } } output.push_back(std::stoi(result, nullptr, 2)); } } bool cmp2(string a, string b) // hard to identify whether the answer is correct, not necessary { int size = min(a.size(), b.size()); for (int i = 0; i < size; i++) { if (a[i] != b[i]) { if (a[i] == '\'') return false; if (b[i] == '\'') return true; return a[i] < b[i]; } } return a.size() < b.size(); } bool cmp(string a, string b) // sort the list, but kinda useless { int cnta = count(a.begin(), a.end(), '1'); int cntb = count(b.begin(), b.end(), '1'); if (cnta != cntb) return cnta < cntb; return a < b; } string toBinary(string enter) // convert number to binary form { string binary; int cur = stoi(enter); while(cur) { binary += to_string(cur%2); cur/=2; } while(binary.size()!=n) { binary += "0"; } reverse(binary.begin(),binary.end()); //cout << binary << endl; return binary; } int main(void) { bool DontCare = false; string enter; cout << "Please Enter varible amount: "; cin >> n; vector<string> minterm, table, temp; set<string> res; cin.ignore(); cout << "Please Enter minterm: "; getline(cin,enter); stringstream ss(enter); while(ss >> enter) { if(enter == "d") DontCare = true; // dontcare's switch on else if(DontCare == true) { minterm.push_back(toBinary(enter)); } else { minterm.push_back(toBinary(enter)); table.push_back(enter); // for prime implicant table } } sort(minterm.begin(), minterm.end(),cmp); int Mergetime = -1; while(Mergetime != 0) // find prime implicant { Mergetime = 0; vector<bool> usedlist(minterm.size(), false); for(int i=0;i<minterm.size();i++) { for(int j=i+1;j<minterm.size();j++) { int diff = 0; string cur = minterm[i]; for(int index=0;index<n;index++) { //cout << minterm[i][index] << " vs " << minterm[i][index] if(minterm[i][index] != minterm[j][index]) { diff++; cur[index] = '-'; } if(diff >= 2) break; } if(diff == 1) { usedlist[i] = usedlist[j]= true; //cout << "Merge!!!" << endl; //cout << cur << endl; Mergetime++; temp.push_back(cur); } } } for(int check = 0;check < usedlist.size();check++) { if(usedlist[check] == false) res.insert(minterm[check]); } //for(auto cur: usedlist) cout << cur << endl; //for(auto cur: temp) cout << cur << endl; minterm.clear(); for(auto cur: temp) minterm.push_back(cur); temp.clear(); } /* for(auto it = res.begin();it != res.end();it++) { cout << *it << endl; } */ vector<vector<bool>> list(res.size(),vector<bool>(table.size(),0)); int cnt = 0; for(auto it=res.begin();it!=res.end();it++,cnt++) { string cur = *it; //cout << "cur: " << cur << " "; vector<int> output; generateNumbers(cur, output); //for(int i=0;i<output.size();i++) cout << to_string(output[i]) << endl; //for(int j=0;j<table.size();j++) cout << table[j] << endl; for(int i=0;i<output.size();i++) { for(int j=0;j<table.size();j++) { if(to_string(output[i]) == table[j]) { list[cnt][j] = true; } } } output.clear(); } /* cout << "Before:\n"; for(int i=0;i<res.size();i++) { for(int j=0;j<table.size();j++) { if(list[i][j]) { cout << "X" << " "; } else cout << list[i][j] << " "; } cout << endl; } */ vector<int> spot; for(int i=0;i<list[0].size();i++) { int c=0; for(int j=0;j<list.size();j++) { if(list[j][i] == 1) c++; } if(c == 1) { for(int x=0;x<list.size();x++) { if(list[x][i] == 1) // find the one in the count list { spot.push_back(x); for(int y=0;y<list[0].size();y++) // delete the column that this one include { if(list[x][y] == 1) // if included { for(int reset=0;reset<list.size();reset++) { if(y != i) list[reset][y] = false; } } } } } for(int reset = 0;reset<list.size();reset++) // must be the last one deleted { list[reset][i] = false; } } } cout << "Essential Prime Implicant: " << endl; if(!spot.empty()) { sort(spot.begin(),spot.end()); int x = 0,y = 0; vector<string> sortedans; for(auto it = res.begin();it != res.end();it++,x++) { string cur = *it; //cout << "x = " << x << ", cur = " << cur << endl; if(x == spot[y]) { //cout << "x = " << x << ", getting spot" << endl; y++; string ans; for(int i=0;i<n;i++) { if(cur[i] != '-')ans+=char('a'+i);//cout << char('a'+i); if(cur[i] == '0') ans+="\'";//cout << "\'"; } if (ans.empty()) ans = "1"; sortedans.push_back(ans); } } sort(sortedans.begin(),sortedans.end(),cmp2); for(auto cur: sortedans) cout << cur << ", "[cur == sortedans[sortedans.size()-1]]; cout << endl; } else cout << "None" << endl; bool stop = false; int round = 1; vector<int> spot2; while(!stop) { round++; //cout << "Round = " << round << endl; //cout << endl; int mx = 0; for(int i=0;i<list.size();i++) // = res.size() { int c=0; for(int j=0;j<list[0].size();j++)// = table.size() { if(list[i][j] == 1) c++; } if(c >= mx) { mx = max(mx,c); if(!spot2.empty()) spot2.pop_back(); spot2.push_back(i); } } spot.push_back(spot2[0]); int i = spot2[spot2.size()-1]; for(int j=0;j<list[0].size();j++) { if(list[i][j] == 1) { list[i][j] = 0; for(int x=0;x<list.size();x++) { list[x][j] = false; } } } stop = true; for(int i=0;i<res.size();i++) { for(int j=0;j<table.size();j++) { if(list[i][j]) { //cout << "X" << " "; stop = false; } //else cout << list[i][j] << " "; } //cout << endl; } //cout << endl; if(round >= res.size()) stop = true; /* cout << "CurrentAns: " << endl; for(auto cur: spot) cout << cur << endl; for(auto cur: spot2) cout << cur << endl; */ } cout << "Ans: " << endl; sort(spot.begin(),spot.end()); //for(auto cur: spot) cout << cur << endl; int x = 0,y = 0; vector<string> sortedans; for(auto it = res.begin();it != res.end();it++,x++) { string cur = *it; //cout << "x = " << x << ", cur = " << cur << endl; if(x == spot[y]) { //cout << "x = " << x << ", getting spot" << endl; y++; string ans; for(int i=0;i<n;i++) { if(cur[i] != '-')ans+=char('a'+i);//cout << char('a'+i); if(cur[i] == '0') ans+="\'";//cout << "\'"; } if (ans.empty()) ans = "1"; sortedans.push_back(ans); } } sort(sortedans.begin(),sortedans.end(),cmp2); for(auto cur: sortedans) cout << cur << " + "[cur != sortedans[sortedans.size()-1]]; //cout << endl; //for(auto cur: dontcare) cout << cur << endl; } /* 4 0 1 2 5 6 7 8 9 10 14 Essential Prime Implicant: b'c',cd' Ans: a'bd+b'c'+cd' 3 0 1 2 5 6 7 Essential Prime Implicant: None Ans: ab+ac+a'b'+a'c'(有三項的更簡解,但要使用 Petrick's Method) 4 2 3 7 9 11 13 d 1 10 15 Essential Prime Implicant: ad,b'c,cd Ans: ad+b'c+cd */ ```