自己写的,在网上其他地方找不到,嘿嘿,VS2017能运行。
#include <iostream>
#include <cstdlib>
using namespace std;
// 用于存储一个码片(1/-1),或者多个下标组合
class NumList {
public:
int data[9]; // 注意以后下标都从1开始
int length;
public:
NumList() {
length = 0;
}
NumList(int len, int in_data[]) {
length = len;
for (int i = 1; i <= len; i++) {
data[i] = in_data[i];
}
}
// 求反码
NumList reverse() const {
NumList e;
e.length = length;
for (int i = 1; i <= length; i++) {
e.data[i] = data[i] * -1;
}
return e;
}
// 增加元素
void add_elem(const int &e) {
data[++length] = e;
}
// 反转指定下标的单个元素
void rever_single(const int index) {
data[index] *= -1;
}
// 删除顶部元素
void pop_elem() {
length--;
}
// show
void show() {
for (int i = 1; i <= length; i++) {
cout << data[i] << " ";
}
cout << endl;
return;
}
// 重载==运算符
bool operator==(const NumList &b) {
if (length != b.length)
return false;
else {
for (int i = 1; i <= length; i++) {
if (data[i] != b.data[i])
return false;
}
}
return true;
}
};
// 用于存储码片集合
class ChipNode {
private:
NumList data;
ChipNode *next;
public:
ChipNode(const NumList &in_data, ChipNode *in_next) :data(in_data), next(in_next) {}
friend class ChipLink;
};
class ChipLink {
private:
ChipNode *H;
ChipNode *now;
public:
ChipLink() {
NumList t;
H = new ChipNode(t, NULL);
now = H;
}
void add_chip(const NumList &e) {
ChipNode *p = H;
while (p->next) {
ChipNode *t = p->next;
// 如果本身已经存在或其反码片已经存在
if (t->data == e || t->data == e.reverse())
return;
p = p->next;
}
ChipNode *new_node = new ChipNode(e, p->next); // p->next = NULL
p->next = new_node;
}
void show() {
ChipNode *p = H->next;
while (p) {
p->data.show();
p = p->next;
}
cout << endl;
return;
}
bool traverse(NumList &ret) {
if (now == H) now = H->next;
if (now == NULL) {
now = H;
return false;
}
else {
ret = now->data;
now = now->next;
return true;
}
}
};
// 算法所在类
class CDMAChipSet {
private:
NumList ini_chip;
ChipLink set;
// 获取指定个数的所有组合组成的链表
void get_index_comb(ChipLink &link, int len, NumList &stack, int num, int res_index) {
// 递归终点
if (num == 0) {
// 将stack复制一份加入链表
link.add_chip(stack);
}
// 向下递归
for (int i = res_index; i <= len; i++) {
stack.add_elem(i);
get_index_comb(link, len, stack, num - 1, i + 1);
stack.pop_elem();
}
return;
}
void get_orthogonal() {
int i;
// 先遍历ini码片,获取-1和1的个数和位置
NumList neg_loc, pos_loc; // 记录位置
int neg_num = 0, pos_num = 0; // 记录数量
for (i = 1; i <= ini_chip.length; i++) {
int val = ini_chip.data[i];
if (val == -1) {
neg_loc.add_elem(i);
neg_num++;
}
else{
pos_loc.add_elem(i);
pos_num++;
}
}
// 求反转数
int neg_rever_num = (neg_num - pos_num) / 2;
int pos_rever_num = (pos_num - neg_num) / 2;
if (neg_rever_num < 0)
neg_rever_num = 0;
else
pos_rever_num = 0;
int rever_time = (neg_loc.length > pos_loc.length) ? pos_loc.length : neg_loc.length;
// 对每种位数组合 求反转位置链表
for (i = 0; i <= rever_time; i++) {
ChipLink a, b;
NumList t_stack1;
get_index_comb(a, neg_loc.length, t_stack1, neg_rever_num + i, 1);
NumList t_stack2;
get_index_comb(b, pos_loc.length, t_stack2, pos_rever_num + i, 1);
// ab组合
NumList t1, t2; // 临时容器
int data[] = { 0, 1, 1, 1, 1, 1, 1, 1, 1 };
while (a.traverse(t1)) {
while (b.traverse(t2)) {
NumList e(8, data);
//生成正交码片
int j, index;
for (j = 1; j <= t1.length; j++) {
index = t1.data[j];
e.rever_single(neg_loc.data[index]);
}
for (j = 1; j <= t2.length; j++) {
index = t2.data[j];
e.rever_single(pos_loc.data[index]);
}
set.add_chip(e);
}
}
}
return;
}
public:
CDMAChipSet(const NumList &in_ini_chip) : ini_chip(in_ini_chip) {
get_orthogonal();
}
void showset() {
int i;
for (i = 1; i <= ini_chip.length; i++) {
cout << ((ini_chip.data[i] == 1) ? 1 : 0) << " ";
}
cout << endl << "的所有正交码片如下:" << endl;
int amount = 0;
NumList container;
while (set.traverse(container)) {
amount++;
for (i = 1; i <= container.length; i++) {
cout << ((container.data[i] == 1) ? 1 : 0) << " ";
}
cout << endl;
}
cout << "共 " << amount << " 个" << endl;
}
};
int main(void) {
NumList chips[5];
int i, j;
for (i = 0; i < 5; i++) {
for (j = 1; j <= 8; j++) {
chips[i].add_elem((rand() % 2 == 0) ? 1 : -1);
}
}
for (i = 0; i < 5; i++) {
CDMAChipSet set(chips[i]);
set.showset();
cout << endl;
}
system("pause");
return 0;
}