代数运算的判定
实验内容:
给定一个集合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); // 零元
}
}
浙公网安备 33010602011771号