【数电】奎恩-麦克拉斯基化简法(Q-M法)C++实现

暑假复习,看B站那个清华的数电视频,简单写一下QM的算法,例子就是阎石书上的题目,还有很多优化的地方,比如图形化等等未来有空再写吧.

加油!

#include<iostream>
#include<vector>
#include<string>
#include<queue>

using namespace std;

//逻辑最小项单元
class LogUnit
{
public:
	LogUnit(){};
	LogUnit(int val_t)
	{
		isMerged = false;
		val = val_t;
		val_str = to_BinStr(val_t, N);
	}
	//将一个数转换成最小项编码
	string to_BinStr(int t, int n)
	{
		int max_num = 1;
		max_num <<= n;
		if (t >= max_num)
		{
			cout << "aim_num = " << t << " Max_num = " << max_num << endl;
			return "ERROR";
		}
		string res(n, '0');
		for (int i = 0; i < n; i++)
		{
			int jud = 1;
			jud <<= i;
			int test = (t / jud) % 2;
			if (test)
			{
				res[i] = '1';
			}
		}
		return string(res.rbegin(),res.rend());
	}
	string get_str_unit()
	{
		return val_str;
	}
	//判断是否可以合并
	bool can_merge(LogUnit& lu)
	{
		bool can_merge_flag = false;
		for (int i = 0; i < N; i++)
		{
			if (this->val_str[i] == lu.val_str[i])
			{
				continue;
			}
			else
			{
				if (can_merge_flag)
				{
					can_merge_flag = false;
					break;
				}
				else
				{
					can_merge_flag = true;
				}
			}
		}
		if (can_merge_flag)
		{
			lu.isMerged = true;
			this->isMerged = true;
		}
		return can_merge_flag;
	}
	//返回一个合并的单元
	LogUnit merge2units(LogUnit& lu)
	{
		LogUnit lut(lu);
		lut.isMerged = false;
		for (int i = 0; i < N; i++)
		{
			if (lut.val_str[i] != this->val_str[i])
				lut.val_str[i] = '-';
		}

		return lut;
	}
	bool operator==(LogUnit &lu)
	{
		if (this->val_str == lu.val_str)
			return true;
		else
			return false;
	}
	~LogUnit()
	{

	}
	static int N;
	int val;
	bool isMerged;
	string val_str;

};
//这里设置总阶数,N个变量
int LogUnit::N = 5;

int main()
{
	//待化简项 填最小项编号
	vector<int> tmp = { 0,2,3,8,10,14,15,22,24,27,31 };

	vector<LogUnit> log_units_v;
	for (auto i : tmp)
	{
		LogUnit t(i);
		cout << t.get_str_unit() << "   length:" << t.get_str_unit().length() << endl;
		log_units_v.push_back(t);
	}
	cout << endl;

	vector<LogUnit> ans;
	queue<vector<LogUnit>> que;
	que.push(log_units_v);

	//不断归并前进
	while (!que.empty())
	{
		vector<LogUnit>ans_tmp;
		vector<LogUnit>& ut = que.front();//取队头
		//int ut_si = ut.size();

		for (int i = 0; i < ut.size(); i++)
		{
			for (int j = i+ 1; j < ut.size(); j++)
			{
				//删除重复元素
				if (ut[i] == ut[j])
				{
					ut.erase(ut.begin() + j);
					//cout << "Erase Successfully!" << endl;
					continue;
					//ut_si--;
				}
				//合并,产生新值
				if (ut[i].can_merge(ut[j]))
				{
					ans_tmp.push_back(ut[i].merge2units(ut[j]));
				}
				
			}
			//一次循环仍然未找到可合并元素,并入最终解集
			if (!ut[i].isMerged)
			{
				ans.push_back(ut[i]);
			}
		}
		que.pop();
		if (!ans_tmp.empty())
		{
			que.push(ans_tmp);
		}

	}
	//-----------     while end      -------//
	//输出结果
	cout << "----答案如下----" << endl;
	for (auto i : ans)
	{
		cout << i.val_str << endl;
	}


	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值