菠菜

敏感而豁达

代数运算的判定

实验内容:

给定一个集合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); // 零元
	}
}

 

posted on 2012-06-25 09:19  ~菠菜~  阅读(2765)  评论(0)    收藏  举报

导航