实验内容:
给定一个集合A和该集合上的一个二元运算*,编写程序(集合和运算具有普遍性),验证该运算是否满足结合律、交换律、幂等律、消去律,并计算幺元、零元、幂等元、可消去元、逆元。
实验原理:
对于任意抽象的二元代数系统<A, *>,可以定义结合律、交换律、消去律、幂等律等运算定律和幺元、零元等特殊元素。
1.结合律
设“*”是集合A上的二元运算,<A, *>是代数系统,如果对任意的a, b, c ∈A,都有
(a * b) * c = a * (b * c),
则称“*”在A上是可结合的(Associative),或称“*”满足结合律(Associative Law)。
2.交换律
设“*”是集合A上的二元运算,<A, *>是一个代数系统,如果对任意的a, b∈A,都有
a * b = b * a,
则称“*”在A上是可交换的(Commutative),或称“*”满足交换律(Commutative Law)。
3.消去律
设“*”是集合A上的二元运算,<A, *>是代数系统,元素a∈A,
(1)对任意x, y∈A,都有
如果a * x = a * y,那么x = y,
则称a在A中关于“*”是左可消去元(Left Cancellative Element);
(2)对任意x, y∈A,都有
如果x * a = y * a,那么x = y,
则称a在A中关于“*”是右可消去元(Right Cancellative Element);
(3)如果a既是A左可消去元又是右可消去元,则称a是A的可消去元(Cancellative);
(4)若A中所有元素都是可消去元,则称“*”在A上是可消去的,或称“*”满足消去律(Cancellative Law)。
4.幂等律
设“*”是集合A上的二元运算,<A, *>是代数系统,若元素a∈A,满足
a*a = a,
则称a是A中关于“*”的一个幂等元(Idempotent Element),简称a为幂等元。若A中的每一个元素都是幂等元,则称“*”在A中是幂等的(Idempotent),或称“*”满足幂等律(Idempotent Law)。
5.幺元
设“*”是集合A上的二元运算,<A, *>是代数系统,若存在e∈A,对任意a∈A,都有
a * e = e * a = a,
则称e是A中关于运算“*”的一个幺元(Identity Element),或称单位元(Unit Element);
6.零元
设“*”是集合A上的二元运算,<A, *>是一个代数系统,若存在q∈A,使得对任意a∈A,都有
a *q = q* a =q,
则称θ是A中关于运算“*”的一个零元(Zero Element);
7.逆元
设“*”是集合A上的二元运算,<A, *>是一个代数系统,e是A中关于“*”的幺元,元素a∈A,若存在一个元素b∈A,使得:
a * b = b * a = e,
则称a是可逆的(Invertible),并称b是a的一个逆元(Inverse Element),记为a-1;
编程实现:
#include <string.h> #include <iostream> using namespace std; #define MAX 26 //最大允许的元素数量为26个,即26个小写英文字母’a’-‘z’ #define VALUE_UNSET 0xfcfcfcfc int otable[MAX][MAX]; //运算表 int oresult[MAX]; //判定结果 void Init() { int i; for(i = 0; i < MAX; i++) { memset(otable[i], VALUE_UNSET, MAX); } } /* 输入操作表 如果输入成功,返回集合大小,否则返回-1 */ int Input() { int count, i, j; char a, b, c; cout << "请输入集合大小:" << endl; cin >> count; if(count > 26 || count < 1) { cout << "输入大小不合法。" << endl; return -1; } cout << "现在假设各元素是:{"; for(i = 0; i < count; i++) { cout << (char)('a' + i) << " "; } cout << "}" << endl; cout << "现在请输入操作表:" << endl; for(i = 0; i < count; i++) { for(j = 0; j < count; j++) { cout << (char)('a' + i) << "*" << (char)('a' + j) << "="; cin >> c; otable[i][j] = c; } } return count; } /* 结合律的判定 (a*b)*c = a*(b*c) */ void Associative(int n) { int i, j, k; bool cond = true; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n; k++) { if(otable[otable[i][j] - 'a'][k] != otable[i][otable[j][k] - 'a']) // 存在一个不满足条件,即没有结合律 { cout << "结合律:NO" << endl; return; } } } } cout << "结合律:YES" << endl; } /* 交换律的判定 a*b = b*a */ void Commutative(int n) { int i, j; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if(otable[i][j] != otable[j][i]) // 存在一个不满足,即没有交换律 { cout << "交换律:NO" << endl; return; } } } cout << "交换律:YES" << endl; } /* 幂等元和幂等律的判定 如果a*a = a,那么a是幂等元 如果所有元素都是幂等元,则称×满足幂等律 */ void Idempotent(int n) { int i, j, k, count; for (i = 0; i < n; i++) { oresult[i] = 0; } count = 0; for (i = 0; i < n; i++) // 判断i是不是幂等元 { if(otable[i][i] == 'a' + i) { oresult[i] = 1; count++; } } if(count == n) { cout << "幂等律:YES" << endl; } else { cout << "幂等律:YES" << endl; if(count == 0) { cout << "幂等元:NO" << endl; } else { cout << "幂等元:"; for(i = 0; i < n; i++) { if(oresult[i] == 1) { cout << (char)('a' + i) << " "; } } cout << endl; } } } /* 可消去元和可消去律的判定。 如果a*x = a*y,那么x=y --> 左可消去元 如果x*a = y*a,那么x=y --> 右可消去元 如果a既是左可消去元又是右可消去元,则称a是可消去元 如果所有元素都是可消去元,则称×满足消去律 */ void Cancellative(int n) { int i, j, k, count; for (i = 0; i < n; i++) { oresult[i] = 1; } count = n; for (i = 0; i < n; i++) // 判断i是不是可消去元 { for (j = 0; j < n; j++) { for(k = 0; k < n && k != j; k++) // 这里直接把k != j作为判断条件是可以的,并因此减少了重复运算 { if(otable[i][j] == otable[i][k]) { oresult[i] = 0; count--; goto next; } } } next: continue; } if(count == n) { cout << "可消去律:YES" << endl; } else { cout << "可消去律:NO" << endl; if(count == 0) { cout << "可消去元:NO" << endl; } else { cout << "可消去元:"; for(i = 0; i < n; i++) { if(oresult[i] == 1) { cout << (char)('a' + i) << " "; } } cout << endl; } } } /* 幺元的判定。返回幺元下标 a*e = e*a = a */ int Identity(int n) { int i, j; for (i = 0; i < n; i++) // 判断i是不是幺元 { for (j = 0; j < n; j++) { if((otable[i][j] != 'a' + j) || (otable[j][i] != 'a' + j)) // e*a != a || a*e != a { goto next; // 存在某一个不满足条件,即可判定i不是幺元 } } cout << "幺元:" << (char)('a' + i) << endl; return i; next: continue; } cout << "幺元:无" << endl; return -1; } /* 逆元的判定。 返回可逆元数量。需要先求出幺元,才可以求逆元。第二个参数unit就是幺元 a*b = b*a = e */ int Invertible(int n, int unit) { int i, j; int elems = 0; int inverses[MAX][MAX]; if(unit == -1) { cout << "因为没有幺元,所以没有逆元。" << endl; return -1; } for (i = 0; i < n; i++) { oresult[i] = 0; } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { inverses[i][j] = 0; } } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if((otable[i][j] == 'a' + unit) && (otable[j][i] == 'a' + unit)) { oresult[i] = 1; inverses[i][j] = 1; // 为1时表示元素i的逆元为j } } if(oresult[i] == 1) { elems++; } } if(elems == 0) { cout << "逆元:NO" << endl; } else { cout << "逆元:"; for (i = 0; i < n; i++) { if(oresult[i] == 1) { cout << (char)('a' + i) << ":"; for (j = 0; j < n; j++) { if(inverses[i][j] == 1) { cout << (char)('a' + j) << " "; } } } } cout << endl; } return elems; } /* 零元的判定 返回零元的下标 a*s = s*a = s */ int ZeroElemet(int n) { int i, j; for (i = 0; i < n; i++) // 判断i是不是零元 { for (j = 0; j < n; j++) { if((otable[i][j] != 'a' + i) || (otable[j][i] != 'a' + i)) // s*a != s || a*s != s { goto next; // 存在某一个不满足条件,即可判定i不是零元 } } cout << "零元:" << (char)('a' + i) << endl; return i; next: continue; } cout << "零元:无" << endl; return -1; } int main() { Init(); int size = Input(); if(size > 0) { Associative(size); // 结合律 Commutative(size); // 交换律 Idempotent(size); // 幂等律和幂等元 Cancellative(size); // 消去律和可消去元 int yaoyuan = Identity(size); // 幺元 Invertible(size, yaoyuan); // 逆元 int lingyuan = ZeroElemet(size); // 零元 } }