這篇博文在上篇博文的基礎上做了些修改,定義了一個有限環的抽象基類,程序運行結果是一樣的,但去除了重複的代碼。
using System;
using System.Collections.Generic;
namespace gap
{
class util
{
public static void printRing(IRing r)
{
int n=r.size();
Console.Write("[R{0}Add]\n",n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int ij=r.add(i,j);
Console.Write("{0} ",ij+1);
}
Console.Write("\n");
}
Console.Write("[R{0}Mul]\n",n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int ij=r.mul(i,j);
Console.Write("{0} ",ij+1);
}
Console.Write("\n");
}
}
}
abstract class IRing
{
public abstract void printTable();
public abstract int add(int a,int b);
public abstract int mul(int a,int b);
public abstract int size();
};
class F8:IRing
{
int[,] m_add;
int[,] m_mul;
public F8()
{
m_add=new int[,]{
{0,1,2,3,4,5,6,7},
{1,0,4,7,2,6,5,3},
{2,4,0,5,1,3,7,6},
{3,7,5,0,6,2,4,1},
{4,2,1,6,0,7,3,5},
{5,6,3,2,7,0,1,4},
{6,5,7,4,3,1,0,2},
{7,3,6,1,5,4,2,0}
};
m_mul=new int[,]{
{0,0,0,0,0,0,0,0},
{0,1,2,3,4,5,6,7},
{0,2,3,4,5,6,7,1},
{0,3,4,5,6,7,1,2},
{0,4,5,6,7,1,2,3},
{0,5,6,7,1,2,3,4},
{0,6,7,1,2,3,4,5},
{0,7,1,2,3,4,5,6}
};
}
public override void printTable()
{
util.printRing(this);
}
public override int add(int a,int b)
{
return m_add[a,b];
}
public override int mul(int a,int b)
{
return m_mul[a,b];
}
public override int size()
{
//return m_add.Length;
return m_add.GetLength(0);
}
}
// 有限循環環mZ/nZ,這裏不要求m|n
class ZmodnZ:IRing
{
int m_m,m_n;
List<ZnElement> m_Set;
public ZmodnZ(int m,int n)
{
this.m_m = m;
this.m_n = n;
ZnElement a=new ZnElement(m,n);
m_Set=ZnElement.Order(a);
}
public int getidx(ZnElement a)
{
for(int i=0;i<m_Set.Count;i++)
if(m_Set[i]==a)
return i;
return -1;
}
public override void printTable()
{
util.printRing(this);
}
public override int add(int a,int b)
{
ZnElement C=m_Set[a]+m_Set[b];
int c=getidx(C);
return c;
}
public override int mul(int a,int b)
{
ZnElement C=m_Set[a]*m_Set[b];
int c=getidx(C);
return c;
}
public override int size()
{
return m_Set.Count;
}
}
class ZnElement
{
int m_k,m_mod;
public ZnElement(int k,int mod)
{
this.m_k = k;
this.m_mod = mod;
}
public static bool operator==(ZnElement a, ZnElement b)
{
return (b.m_k==a.m_k && b.m_mod==a.m_mod);
}
public static bool operator!=(ZnElement a, ZnElement b)
{
return (b.m_k!=a.m_k || b.m_mod!=a.m_mod);
}
// overload operator +
public static ZnElement operator +(ZnElement a, ZnElement b)
{
return new ZnElement((a.m_k + b.m_k)%a.m_mod, a.m_mod);
}
// overload operator *
public static ZnElement operator *(ZnElement a, ZnElement b)
{
return new ZnElement((a.m_k * b.m_k)%a.m_mod, a.m_mod);
}
public static List<ZnElement> Order(ZnElement a)
{
List<ZnElement> L=new List<ZnElement>();
ZnElement mi=a;
ZnElement m0=new ZnElement(0,a.m_mod);
L.Add(m0);
while(mi!=m0)
{
L.Add(mi);
mi=mi+a;
}
return L;
}
// define operator int
public static implicit operator int(ZnElement a)
{
List<ZnElement> L=Order(a);
return L.Count;
}
}
/// <summary>
/// Summary description for Test.
/// </summary>
class Test
{
static void Main(string[] args)
{
ZnElement a=new ZnElement(2,16);
Console.WriteLine((int)a);
ZmodnZ r8_2=new ZmodnZ(2,16);
Console.WriteLine(r8_2.size());
r8_2.printTable();
F8 r8_52=new F8();
Console.WriteLine(r8_52.size());
r8_52.printTable();
}
}
}