一、功能及运行结果如下:
二、代码说明
1、关系即为序偶的集合:{ <a, b> , <b, c> , ... },这里采用了set<Order>来表示关系,其中Struct Order是序偶。
2、在Order内部重载"<",定义序偶的大小,保证set容器能插入、查找特定序偶。
三、代码知识点
set容器:embrace操作
结构体:重载"<",含参构造函数,可以作为返回值
四、C++11代码
#include <iostream>
#include <cctype>
#include <set>
#include <map>
#include <cstring>
#include <iomanip>
#define N 30
using namespace std;
//序偶,重载了"<"
struct Order {
char left, right;
Order(char u, char v)
{
left = u;
right = v;
}
bool operator < (const Order& t) const
{
if (left != t.left) return left < t.left;
return right < t.right;
}
};
//改写:int printYsh(char a[]) 输入集合A
void inputSet(set<char>& a) {
string str;
cin >> str;
for (auto p : str)
if (isalnum(p)) a.insert(p);
}
//改写:int inputRelaYsh(char a[][3]) 输入关系序列
void inputRela(set<Order>& r) {
string str;
cin >> str;
for (size_t i = 0; i < str.size(); ++i)
{
if (isalnum(str[i]))
{
for (size_t j = i + 1; j < str.size(); ++j)
{
if (isalnum(str[j]))
{
r.emplace(str[i], str[j]);
i = j;
break;
}
}
}
}
}
//改写:int printYsh(char a[]) 打印集合A
void printSet(const set<char>& a) {
size_t count = 0;
for (auto p : a)
{
++count;
cout << p;
if (count != a.size()) cout << ",";
}
cout << endl;
}
//改写:int printRelaYsh(char a[][3], int n) 打印关系序列
void printRela(const set<Order>& r) {
int count = 0;
for (auto p : r)
{
++count;
cout << "<" << p.left << "," << p.right << ">";
if (count != r.size()) cout << ",";
}
cout << endl;
}
//改写:int printRelaMatrix(int M[][N], int n) 打印关系矩阵
void printMatrix(bool m[][N], int n) {
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
cout << setw(4) << m[i][j];
cout << endl;
}
}
//改写:void matrixmulti(int M[][100], int R[][N], int T[][N], int n) 矩阵乘法 M *= R
void matrixMulti(bool M[][N], bool R[][N], int rank) {
bool T[N][N] = { 0 };
for (int i = 0; i < rank; ++i)
for (int j = 0; j < rank; ++j)
for (int k = 0; k < rank; ++k)
T[i][j] |= (M[i][k] & R[k][j]);
memcpy(M, T, sizeof(T));
}
//改写:int rPower(char R[][3], char T[][3], int nR, int n, int np) 矩阵的幂次运算
void matrixPow(bool base[][N], int n, int rank, bool res[][N]) {
memset(res, 0, sizeof(bool) * N * N);
for (int i = 0; i < rank; ++i)
res[i][i] = 1;
while (n)
{
if (n & 1) matrixMulti(res, base, rank);
matrixMulti(base, base, rank);
n >>= 1;
}
}
//改写:void rela2matrix(char a[], char R[][3], int nR, int M[][N]) 关系转化为邻接矩阵
void toMatrix(const set<Order>& r, bool m[][N], const set<char>& a) {
map<char, int> Am;
int count = 0;
for (auto p : a)
Am[p] = count++;
memset(m, 0, sizeof(bool) * N * N);
for (auto p : r)
m[Am[p.left]][Am[p.right]] = 1;
}
//改写:int matrix2rela(char a[], char R[][3], int M[][N]) 邻接矩阵转化为关系
set<Order> toRela(bool m[][N], const set<char>& a) {
set<Order> r;
char As[N];
int count = 0;
for (auto p : a)
As[count++] = p;
for (int i = 0; i < a.size(); ++i)
for (int j = 0; j < a.size(); ++j)
if (m[i][j] == 1) r.emplace(As[i], As[j]);
return r;
}
//改写:int relaCompose(char R[][3], char S[][3], char T[][3], int nR, int nS) 关系的复合
set<Order> relaCompose(const set<Order>& r1, const set<Order>& r2) {
set<Order> tmp;
for (auto p : r1)
{
for (auto q : r2)
{
if (p.right == q.left)
tmp.emplace(p.left, q.right);
else if (q.left > p.right)
break;
}
}
return tmp;
}
//改写:int relaSelf(char a[], char R[][3], int nR, char T[][3]) 自反闭包
set<Order> relaSelf(const set<Order>& r, const set<char>& A) {
set<Order> tmp(r);
for (auto p : A)
tmp.emplace(p, p);
return tmp;
}
//改写:int relaSym(char R[][3], char T[][3], int nR) 对称闭包
set<Order> relaSym(const set<Order>& r, const set<char>& A) {
set<Order> tmp(r);
for (auto p : r)
if(p.left!=p.right)
tmp.emplace(p.right, p.left);
return tmp;
}
//改写:int trorder(char R[][3], char RM[][3], int nR, int n) 传递闭包
void relaTran(set<Order> tmp, const set<char> a) {
bool res[N][N];
bool rn[N][N];
bool r1[N][N];
toMatrix(tmp, r1, a);
memcpy(rn, r1, sizeof(r1));
memcpy(res, r1, sizeof(r1));
for (int c = 1; c < a.size(); ++c)
{
printRela(toRela(rn, a));
matrixMulti(rn, r1, a.size());
for (int i = 0; i < a.size(); ++i)
for (int j = 0; j < a.size(); ++j)
res[i][j] |= rn[i][j];
}
printRela(toRela(res, a));
}
//改写:int trmatrix(int R[][N], int n) warshall算法求传递闭包
void warShall(bool R[][N], int n) {
for (int j = 0; j < n; ++j)
{
for (int i = 0; i < n; ++i)
{
if (R[i][j])
{
for (int k = 0; k < n; ++k)
R[i][k] |= R[j][k];
}
}
}
}
int main()
{
set<Order> R1;
set<Order> R2;
set<char> A;
bool matrix1[N][N];
bool matrix2[N][N];
int nChoice;
int n;
while (true)
{
printf("\n========================\n");
printf("1...输入相关元素值\n");
printf("2...R1*R2关系的复合\n");
printf("3...自反闭包\n");
printf("4...对称闭包\n");
printf("5...序偶形式的关系转关系矩阵\n");
printf("6...利用矩阵求关系的复合\n");
printf("7...利用序偶形式的复合求传递闭包\n");
printf("8...利用warshall算法的求传递闭包\n");
printf("9...R2*R1关系的复合\n");
printf("10..R1的任意次方\n");
printf("11..R2的任意次方\n");
printf("0...退出\n");
printf("========================\n您的选择: ");
cin >> nChoice;
if (nChoice == 0) break;
if (nChoice == 1)
{
printf("输入集合A:");
inputSet(A);
printf("输入关系R1:");
inputRela(R1);
printf("输入关系R2:");
inputRela(R2);
printf("A:");
printSet(A);
printf("关系R1:");
printRela(R1);
printf("关系R2:");
printRela(R2);
}
else if (nChoice == 2)
{
printf("R1@R2:");
printRela(relaCompose(R1, R2));
}
else if (nChoice == 9)
{
printf("R2@R1:");
printRela(relaCompose(R2, R1));
}
else if (nChoice == 3)
{
cout << "R1的自反闭包:";
printRela(relaSelf(R1, A));
}
else if (nChoice == 4)
{
printf("R1的对称闭包:");
printRela(relaSym(R1, A));
}
else if (nChoice == 5)
{
printf("R1关系的序偶");
printRela(R1);
printf("R1关系的矩阵\n");
toMatrix(R1, matrix1, A);
printMatrix(matrix1, A.size());
}
else if (nChoice == 6)
{
printf("R1关系的矩阵\n");
toMatrix(R1, matrix1, A);
printMatrix(matrix1, A.size());
printf("R2关系的矩阵\n");
toMatrix(R2, matrix2, A);
printMatrix(matrix2, A.size());
printf("复合后的矩阵\n");
matrixMulti(matrix1, matrix2, A.size());
printMatrix(matrix1, A.size());
printf("\n复合后的序偶");
printRela(toRela(matrix1, A));
}
else if (nChoice == 7)
relaTran(R1, A);
else if (nChoice == 8)
{
printf("R1关系的序偶");
printRela(R1);
printf("R1关系中的矩阵\n");
toMatrix(R1, matrix1, A);
printMatrix(matrix1, A.size());
printf("warshall后的矩阵\n");
warShall(matrix1, A.size());
printMatrix(matrix1,A.size());
printf("\n序偶");
printRela(toRela(matrix1, A));
}
else if (nChoice == 10)
{
printf("输入n:");
cin >> n;
toMatrix(R1, matrix1, A);
matrixPow(matrix1, n, A.size(), matrix2);
printf("R1的%d次方:\n", n);
printMatrix(matrix2, A.size());
printf("\n转化为序偶\n");
printRela(toRela(matrix2, A));
}
else if (nChoice == 11)
{
printf("输入n:");
cin >> n;
toMatrix(R2, matrix1, A);
matrixPow(matrix1, n, A.size(), matrix2);
printf("R2的%d次方:\n", n);
printMatrix(matrix2, A.size());
printf("\n序偶转换为数组\n");
printRela(toRela(matrix2, A));
}
}
system("pause");
return 0;
}