RFID二进制树形搜索算法模拟实现C++

二进制树形搜索算法的基本思想是将处于冲突的标签分成左右两个子集0和1,先查询子集0,若没有冲突,则正确识别标签,若仍有冲突则再分裂,把子集0分成00和01两个子集,直到识别出子集0中的所有标签,再按此步骤查询子集1.

算法实列:
电子标签1: 10110010
电子标签2: 10100011
电子标签3: 10110011
电子标签4: 11100011
①读写器第一次发送REQUEST(<=11111111)命令。序列号11111111是本例中系统最大可能的8位序列号,因此读写器作用范围内的所有电子标签都对该命令做出应答。由于序列号的0,4,6位重叠响应而造成了冲突(1X1X001X)

②第六位最高是X位,因此在该位上出现了冲突,意味着不仅在序列号(>=11000000)的范围内,而且在序列号(<=10111111)的范围内,至少各有1个电子标签存在。为了能选择到一个单独的电子标签,必须根据已有的信息来限制下一次迭代的搜索范围。例如,在<=10111111的范围内进一步搜索。为此,将第6位置0(有冲突位的最高位),将所有低位置1,暂时对所有低位的值不予处理
(一会在程序实现的时候就相当于不判断低位,只判断冲突位之前的位数)。

③若在第二次迭代的过程中还发现有冲突,则进一步缩小范围,方法类似②步骤

RFID二进制树形搜索算法模拟实现C++_第1张图片

#include 
#include 
#include 
using namespace std;

struct card
{
	string code;  //序列号
	bool is_correct;  //卡是否能读取(错误卡或已读的卡不能读)
	card(){}
	card(string code)
		:code(code)
		, is_correct(true)
	{}
};

class RFID_Read
{
public:
	//找出冲突位 arr代表一组卡 ,max_code代表最大序列号, conflict_bit用于存储冲突位
	void first_request(vector& arr, string& max_code, vector& conflict_bit)
	{
		int max_code_length = max_code.size();
		int arr_length = arr.size();
		for (int i = 0; i < arr_length; ++i) {     //标记非法卡,一会搜索时就忽略它
			if (arr[i].code.size() != max_code_length) {
				arr[i].is_correct = false;
			}
			else {
				cout << arr[i].code << endl;  //打印所有正确的卡
			}
		}
		int k = 0;
		for (int i = 0; i < arr_length; ++i) {  //找出第一张正确的卡
			if (arr[i].is_correct == true) {
				k = i;
				break;
			}
		}
		for (int i = 0; i < max_code_length; ++i) {  //找冲突位
			max_code[i] = arr[k].code[i];            //将第一张正确卡的序列号赋给max_code
			for (int j = 0; j < arr_length; ++j) {
				if (arr[k].code[i] != arr[j].code[i] && arr[j].is_correct == true) { //遇到冲突位时
					conflict_bit.push_back(i);                       //将冲突位的位数记录
					max_code[i] = 'X';                              //并将冲突位标记位X后退出判断下一位
					break;
				}
			}
		}
	}
	//找出某一张卡
	void find_card(vector& arr, vector& conflict_bit, string& s)
	{
		request(arr, conflict_bit, 0, '0', s);
		request(arr, conflict_bit, 0, '1', s);
	}

private:
	//二进制树型搜索算法   k代表conflict_bit数组的第k位, flag代表冲突位将被置位0或1, s代表当前读写器发出的序列号
	void request(vector& arr, vector& conflict_bit,int k, char flag, string& s)
	{
		int count = 0;
		s[conflict_bit[k]] = flag;  //将最高冲突位置为0或1
		for (int i = 0; i < arr.size(); ++i) {
			if (arr[i].code[conflict_bit[k]] == flag && arr[i].is_correct == true) { //找出与冲突位相同的序列号,count++
				++count;
				for (int j = 0; j <= conflict_bit[k]; ++j) {          //找出与当前冲突位之前位数不相同的序列号,count--
					if (arr[i].code[j] != s[j]) {                  
						--count;
						break;
					}
				}
			}
		}
		if (count < 2) {                                   //当找到的卡的数量等于1或0时,就打印该序列号并将该卡置为不可读,后退出循环
			int f = 0;
			for (int i = 0; i < arr.size(); ++i){
				if (arr[i].code[conflict_bit[k]] == flag && arr[i].is_correct == true) {
					for (int j = 0; j <= conflict_bit[k]; ++j) {
						if (arr[i].code[j] != s[j]) {
							break;
						}
						f = j;
					}
					if (f == conflict_bit[k]) {  
						arr[i].is_correct = false;
						cout << "第 " << i + 1 << " 个标签: " << arr[i].code << endl;
					}
				}
			}
			return;
		}
		else {  //继续下一个冲突位的判断
			request(arr, conflict_bit, k + 1, '0', s);
			request(arr, conflict_bit, k + 1, '1', s);
		}
	}
};

int main()
{
	RFID_Read r;
	vector arr;
	string str;
	int k;
	cout << "请输入标签个数:" << endl;
	cin >> k;
	for (int i = 0; i < k; ++i) {
		cin >> str;
		arr.push_back({ str });
	}
	string s = "11111111";
	vector conflict_bit;
	r.first_request(arr, s, conflict_bit);
	r.find_card(arr, conflict_bit, s);
	return 0;
}

你可能感兴趣的:(算法)