20140616問題1:G12是第6種12階羣,還是不構成羣?
20140616問題2:G16、X16是第15、16種16階羣,還是不構成羣?
// gap.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
#include <Windows.h>
#pragma comment(lib,"user32.lib")
std::vector<string> split( const std::string& str, const std::string& delims, unsigned int maxSplits = 0)
{
std::vector<string> ret;
unsigned int numSplits = 0;
// Use STL methods
size_t start, pos;
start = 0;
do
{
pos = str.find_first_of(delims, start);
if (pos == start)
{
// Do nothing
start = pos + 1;
}
else if (pos == std::string::npos || (maxSplits && numSplits == maxSplits))
{
// Copy the rest of the std::string
ret.push_back( str.substr(start) );
break;
}
else
{
// Copy up to delimiter
ret.push_back( str.substr(start, pos - start) );
start = pos + 1;
}
// parse up to next real data
start = str.find_first_not_of(delims, start);
++numSplits;
} while (pos != std::string::npos);
return ret;
}
vector<char> lof(const char *fn)
{
vector<char> ret;
FILE *fp;
int i=0;
char ch=0;
if((fp=fopen(fn, "rb"))!=NULL)
{
fseek(fp, 0, SEEK_SET);
while (ch!= EOF)
{
i++;
ch = fgetc(fp);
ret.push_back(ch);
};
fclose(fp);
}
if(ret.size()>0 && ret[ret.size()-1]==EOF)
ret.pop_back();
return ret;
//return (i-1);
}
vector<char> CharArrToNormal(const vector<char>& vec)
{
vector<char> ret;
int n=vec.size();
for(int i=0;i<n;i++)
{
#if 0
if(vec[i]==32)
{
if(ret.size()>0 && ret[ret.size()-1]!=',' && ret[ret.size()-1]!=';')
ret.push_back(',');
}
else if(vec[i]==13||vec[i]==10)
{
if(ret.size()>0 && ret[ret.size()-1]!=',' && ret[ret.size()-1]!=';')
ret.push_back(';');
}
#else
if(vec[i]==32||vec[i]==13||vec[i]==10)
{
if(ret.size()>0 && ret[ret.size()-1]!=',')
ret.push_back(',');
}
#endif
else
{
ret.push_back(vec[i]);
}
}
return ret;
}
string CharArrToStr(const vector<char>& vec)
{
string str;
int n=vec.size();
for(int i=0;i<n;i++)
{
str.push_back(vec[i]);
}
return str;
}
vector<vector<int>> atoTable(const char* strMtx)
{
vector<vector<int>> vvMtx;
vector<int> iAll;
if(strMtx!=0)
{
vector<string> All=split(strMtx,",");
for(int i=0;i<All.size();i++)
{
int iElem=atoi(All[i].c_str());
iAll.push_back(iElem);
}
}
int n=iAll.size();
int n1=(int)sqrtf(n);
if(n1*n1==n)
{
for(int i=0;i<n1;i++)
{
vector<int> iRow;
for(int j=0;j<n1;j++)
{
int iElem=iAll[i*n1+j];
iRow.push_back(iElem);
}
vvMtx.push_back(iRow);
}
}
return vvMtx;
}
vector<int> IsLegalMtx(const vector<vector<int>> &mtx)
{
vector<int> ret(3);
int illegal=-1;
ret[1]=mtx.size();
if(ret[1]==0)
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
ret[2]=mtx[0].size();
if(ret[2]==0)
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
for(int i=1;i<ret[1];i++)
{
if(mtx[i].size()!=ret[2])
{
ret[0]=illegal;//不是合法矩陣
return ret;
}
}
ret[0]=0;//是合法矩陣
return ret;
}
vector<vector<int>> ABmul(const vector<vector<int>> &A,const vector<vector<int>> &B)
{
vector<vector<int>> C;
vector<int> AFlag=IsLegalMtx(A);
if(AFlag[0]==-1)
return C;
vector<int> BFlag=IsLegalMtx(B);
if(BFlag[0]==-1)
return C;
int nB=BFlag[1];
int n=AFlag[1]*BFlag[1];
for(int a=0;a<n;a++)
{
vector<int> iRow;
for(int b=0;b<n;b++)
{
int aj=a%nB;
int ai=a/nB;
int bj=b%nB;
int bi=b/nB;
int i=A[ai][bi]-1;
int j=B[aj][bj]-1;
int c=nB*i+j+1;
iRow.push_back(c);
}
C.push_back(iRow);
}
return C;
}
bool SaveTable(const char *fn,const vector<vector<int>> &A)
{
vector<int> AFlag=IsLegalMtx(A);
if(AFlag[0]==-1)
return false;
FILE *fp;
if((fp=fopen(fn,"wb+"))!=NULL)
{
for(int i=0;i<AFlag[1];i++)
{
for(int j=0;j<AFlag[2];j++)
{
fprintf(fp,"%d ",A[i][j]);
}
fprintf(fp,"\r\n");
}
fclose(fp);
}
return true;
}
vector<int> Factors(int n)
{
vector<int> ret;
if(n<1)
return ret;
for(int i=1;i<=n;i++)
{
if(n%i==0)
{
ret.push_back(i);
}
}
return ret;
}
// 未知n階羣的羣元的階
int getGnEOrder(const vector<vector<int>> &A,int a)
{
vector<int> AFlag=IsLegalMtx(A);
if(AFlag[0]==-1)
return -1;
int n=AFlag[1];
if(a<0||a>=n)
return -1;
int t=0;
for(int i=1;i<=n;i++)
{
t=A[t][a]-1;
if(t==0)
return i;
}
return -1;
}
bool SaveGnEOrder(const char *srcfn,const char *Desfn,const char *DesGn=0)
{
vector<char> A=lof(srcfn);
string strA=CharArrToStr(CharArrToNormal(A));
vector<vector<int>> vvA=atoTable(strA.c_str());
vector<int> AFlag=IsLegalMtx(vvA);
if(AFlag[0]==-1||AFlag[1]!=AFlag[2])
return false;
ofstream fout(Desfn);
vector<int> vOrders=Factors(AFlag[1]);
vector<int> vCounts(AFlag[1]+1);
for(int i=0;i<AFlag[1];i++)
{
int ord=getGnEOrder(vvA,i);
printf("G%dElementToOrder(%d)=%d\n",AFlag[1],i,ord);
fout<<"G"<<AFlag[1]<<"ElementToOrder("<<i<<")="<<ord<<endl;
vCounts[ord]=vCounts[ord]+1;
}
string strF;
{
char sz[200]={0};
if(DesGn==0)
{
sprintf(sz,"G%d有",AFlag[1]);
}
else
{
sprintf(sz,"%s有",DesGn);
}
strF=sz;
}
for(int i=0;i<vOrders.size();i++)
{
char sz[200]={0};
sprintf(sz,"%d個%d階元,",vCounts[vOrders[i]],vOrders[i]);
strF+=sz;
}
if(strF.size()>2)
{
strF=strF.substr(0,strF.size()-2);
}
printf("%s\n",strF.c_str());
fout<<strF.c_str()<<endl;
fout.close();
return true;
}
vector<vector<int> > Arr2ToVec2(int *R,int N,int delt=1)
{
vector<vector<int> > vv(N);
for(int i=0;i<N;i++)
{
vector<int> v(N);
vv[i]=v;
}
for (int i=0; i<N; i++)
for (int j=0; j<N; j++)
{
vv[i][j]=*(R+i*N+j)+delt;
}
return vv;
}
// N次置換
bool IsPerN(vector<int> A,int N)
{
std::sort(A.begin(),A.end());//升序
for(int i=0;i<N;i++)
if(A[i]!=i+1)
return false;
return true;
}
// S_N中置換乘法m*n
vector<int> Mul(int N,const vector<int> & m,const vector<int> & n)
{
vector<int> tArr(N);
vector<int> aArr(N);
vector<int> taArr(N);
memcpy(&tArr[0],&m[0],sizeof(tArr[0])*N);
memcpy(&aArr[0],&n[0],sizeof(aArr[0])*N);
for(int i=0;i<N;i++)
taArr[i]=aArr[tArr[i]-1];
vector<int> ret(N);
memcpy(&ret[0],&taArr[0],sizeof(taArr[0])*N);
return ret;
}
vector<vector<int> > Order(int N,const vector<int> & m)
{
vector<vector<int> > ret;
vector<int> mi=m;
vector<int> m0(N);
for(int i=0;i<N;i++)
{
m0[i]=i+1;
}
while(memcmp(&mi[0],&m0[0],sizeof(int)*N)!=0)
{
ret.push_back(mi);
mi=Mul(N,mi,m);
}
ret.push_back(mi);
return ret;
}
// S_N中置換m的逆
vector<int> Inv(int N,const vector<int> & m)
{
vector<vector<int> >vv=Order(N,m);
int ord=vv.size();
return vv[ord-1];
}
int IsInFG(int N,const vector<vector<int> > FG,const vector<int> & m)
{
for(int i=0;i<FG.size();i++)
{
if(memcmp(&m[0],&FG[i][0],sizeof(int)*N)==0)
return i;
}
return -1;
}
// 二維數組是羣的凱萊表的充要條件
bool IsGroup(int *R,int N,int delt=1)
{
vector<vector<int> > vvA=Arr2ToVec2(R,N,delt);
vector<int> AFlag=IsLegalMtx(vvA);
if(AFlag[0]==-1||AFlag[1]!=AFlag[2])
return false;
for(int i=0;i<AFlag[1];i++)
{
bool isPerN=IsPerN(vvA[i],AFlag[1]);
if(!isPerN)
return false;
}
//E是乘法單位元
vector<int> E;
for(int i=0;i<N;i++)
{
E.push_back(i+1);
}
int bIn=IsInFG(N,vvA,E);
if(bIn==-1)
{
return false;
}
//乘法封閉性
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
vector<int> IJ=Mul(N,vvA[i],vvA[j]);
int bIn=IsInFG(N,vvA,IJ);
if(bIn==-1)
{
return false;
}
}
}
//有乘法逆元
for(int i=0;i<N;i++)
{
vector<int> inv=Inv(N,vvA[i]);
int bIn=IsInFG(N,vvA,inv);
if(bIn==-1)
{
return false;
}
}
return true;
}
//0是循環羣
//1是羣但不是循環羣
//2不是羣
int IsCircleGroup(int *R,int N,int delt=1)
{
if(!IsGroup(R,N,delt))
return 2;
vector<vector<int> > vvA=Arr2ToVec2(R,N,delt);
for(int i=0;i<N;i++)
{
vector<vector<int> >vv=Order(N,vvA[i]);
int ord=vv.size();
if(ord==N)
{
return 0;//vvA[i]是循環羣的一個生成元
}
}
return 1;
}
//0是Abel羣
//1是羣但不是Abel羣
//2不是羣
int IsAbelianGroup(int *R,int N,int delt=1)
{
if(!IsGroup(R,N,delt))
return 2;
vector<vector<int> > vvA=Arr2ToVec2(R,N,delt);
//乘法交換性
for(int i=0;i<N;i++)
{
for(int j=i+1;j<N;j++)
{
vector<int> ij=Mul(N,vvA[i],vvA[j]);
vector<int> ji=Mul(N,vvA[j],vvA[i]);
if(memcmp(&ij[0],&ji[0],sizeof(int)*N)==0)
continue;
else
return 1;
}
}
return 0;
}
int g_C4[]={
1,2,3,4,
2,1,4,3,
3,4,2,1,
4,3,1,2
};
int g_C2C2[]={
1,2,3,4,
2,1,4,3,
3,4,1,2,
4,3,2,1
};
int g_S3[]={
1,2,3,4,5,6,
2,1,4,3,6,5,
3,5,1,6,2,4,
4,6,2,5,1,3,
5,3,6,1,4,2,
6,4,5,2,3,1
};
int g_D4[]={
1,2,3,4,5,6,7,8,
2,1,4,3,6,5,8,7,
3,4,1,2,7,8,5,6,
4,3,2,1,8,7,6,5,
5,7,6,8,1,3,2,4,
6,8,5,7,2,4,1,3,
7,5,8,6,3,1,4,2,
8,6,7,5,4,2,3,1
};
int g_C9[]={
1,4,6,8,10,12,14,16,18,
4,6,8,10,12,14,16,18,1,
6,8,10,12,14,16,18,1,4,
8,10,12,14,16,18,1,4,6,
10,12,14,16,18,1,4,6,8,
12,14,16,18,1,4,6,8,10,
14,16,18,1,4,6,8,10,12,
16,18,1,4,6,8,10,12,14,
18,1,4,6,8,10,12,14,16
};
int g_G12[]={
1,2,3,4,5,6,7,8,9,10,11,12,
2,1,4,3,10,9,8,7,6,5,12,11,
3,4,1,2,11,12,9,10,7,8,5,6,
4,3,2,1,8,7,10,9,12,11,6,5,
5,6,7,8,9,10,11,12,1,2,3,4,
6,5,8,7,2,1,12,11,10,9,4,3,
7,8,5,6,3,4,1,2,11,12,9,10,
8,7,6,5,12,11,2,1,4,3,10,9,
9,10,11,12,1,2,3,4,5,6,7,8,
10,9,12,11,6,5,4,3,2,1,8,7,
11,12,9,10,7,8,5,6,3,4,1,2,
12,11,10,9,4,3,6,5,8,7,2,1
};
int g_G16[]={
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
2,1,4,3,14,13,8,7,10,9,12,11,6,5,16,15,
3,4,1,2,15,16,13,14,11,12,9,10,7,8,5,6,
4,3,2,1,8,7,14,13,12,11,10,9,16,15,6,5,
5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,
6,5,8,7,2,1,12,11,14,13,16,15,10,9,4,3,
7,8,5,6,3,4,1,2,15,16,13,14,11,12,9,10,
8,7,6,5,12,11,2,1,16,15,14,13,4,3,10,9,
9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,
10,9,12,11,6,5,16,15,2,1,4,3,14,13,8,7,
11,12,9,10,7,8,5,6,3,4,1,2,15,16,13,14,
12,11,10,9,16,15,6,5,4,3,2,1,8,7,14,13,
13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,
14,13,16,15,10,9,4,3,6,5,8,7,2,1,12,11,
15,16,13,14,11,12,9,10,7,8,5,6,3,4,1,2,
16,15,14,13,4,3,10,9,8,7,6,5,12,11,2,1
};
int g_X16[]={
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
2,1,4,3,8,7,6,5,12,11,10,9,16,15,14,13,
3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,
4,3,2,1,6,5,8,7,10,9,12,11,14,13,16,15,
5,6,7,8,3,4,1,2,15,16,13,14,9,10,11,12,
6,5,8,7,2,1,4,3,14,13,16,15,12,11,10,9,
7,8,5,6,1,2,3,4,13,14,15,16,11,12,9,10,
8,7,6,5,4,3,2,1,16,15,14,13,10,9,12,11,
9,10,11,12,13,14,15,16,3,4,1,2,7,8,5,6,
10,9,12,11,16,15,14,13,2,1,4,3,6,5,8,7,
11,12,9,10,15,16,13,14,1,2,3,4,5,6,7,8,
12,11,10,9,14,13,16,15,4,3,2,1,8,7,6,5,
13,14,15,16,11,12,9,10,5,6,7,8,3,4,1,2,
14,13,16,15,10,9,12,11,8,7,6,5,2,1,4,3,
15,16,13,14,9,10,11,12,7,8,5,6,1,2,3,4,
16,15,14,13,12,11,10,9,6,5,8,7,4,3,2,1
};
int g_F4Add[4][4]={
{0,1,2,3},
{1,0,3,2},
{2,3,0,1},
{3,2,1,0}
};
int g_F4Mul[4][4]={
{0,0,0,0},
{0,1,2,3},
{0,2,3,1},
{0,3,1,2}
};
int g_Z4AddError[4][4]={
{0,1,2,3},
{1,2,3,0},
{2,3,1,0},
{3,0,1,2}
};
int g_Z4Mul[4][4]={
{0,0,0,0},
{0,1,2,3},
{0,2,0,2},
{0,3,2,1}
};
int g_C8Mul[8][8]={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 0, 3, 2, 5, 4, 7, 6},
{2, 3, 1, 0, 6, 7, 5, 4},
{3, 2, 0, 1, 7, 6, 4, 5},
{4, 5, 6, 7, 2, 3, 1, 0},
{5, 4, 7, 6, 3, 2, 0, 1},
{6, 7, 5, 4, 1, 0, 3, 2},
{7, 6, 4, 5, 0, 1, 2, 3}
};
int g_C8Mul_2[8][8]={
{0,1,2,3,4,5,6,7},
{1,2,3,4,5,6,7,0},
{2,3,4,5,6,7,0,1},
{3,4,5,6,7,0,1,2},
{4,5,6,7,0,1,2,3},
{5,6,7,0,1,2,3,4},
{6,7,0,1,2,3,4,5},
{7,0,1,2,3,4,5,6}
};
int g_C2C4Mul[8][8]={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 0, 3, 2, 5, 4, 7, 6},
{2, 3, 0, 1, 6, 7, 4, 5},
{3, 2, 1, 0, 7, 6, 5, 4},
{4, 5, 6, 7, 1, 0, 3, 2},
{5, 4, 7, 6, 0, 1, 2, 3},
{6, 7, 4, 5, 3, 2, 1, 0},
{7, 6, 5, 4, 2, 3, 0, 1}
};
int g_C2C4Mul_2[8][8]={
{0,1,2,3,4,5,6,7},
{1,4,7,2,5,0,3,6},
{2,7,4,1,6,3,0,5},
{3,2,1,0,7,6,5,4},
{4,5,6,7,0,1,2,3},
{5,0,3,6,1,4,7,2},
{6,3,0,5,2,7,4,1},
{7,6,5,4,3,2,1,0}
};
int g_C2C2C2Mul[8][8]={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 0, 3, 2, 5, 4, 7, 6},
{2, 3, 0, 1, 6, 7, 4, 5},
{3, 2, 1, 0, 7, 6, 5, 4},
{4, 5, 6, 7, 0, 1, 2, 3},
{5, 4, 7, 6, 1, 0, 3, 2},
{6, 7, 4, 5, 2, 3, 0, 1},
{7, 6, 5, 4, 3, 2, 1, 0}
};
int g_D4Mul[8][8]={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 0, 3, 2, 5, 4, 7, 6},
{2, 3, 0, 1, 7, 6, 5, 4},
{3, 2, 1, 0, 6, 7, 4, 5},
{4, 5, 6, 7, 0, 1, 2, 3},
{5, 4, 7, 6, 1, 0, 3, 2},
{6, 7, 4, 5, 3, 2, 1, 0},
{7, 6, 5, 4, 2, 3, 0, 1}
};
int g_Q8Mul[8][8]={
{0, 1, 2, 3, 4, 5, 6, 7},
{1, 0, 3, 2, 5, 4, 7, 6},
{2, 3, 1, 0, 7, 6, 4, 5},
{3, 2, 0, 1, 6, 7, 5, 4},
{4, 5, 6, 7, 1, 0, 3, 2},
{5, 4, 7, 6, 0, 1, 2, 3},
{6, 7, 5, 4, 2, 3, 1, 0},
{7, 6, 4, 5, 3, 2, 0, 1}
};
int _tmain(int argc, _TCHAR* argv[])
{
{
int *G=g_C4;
int N=sqrt(sizeof(g_C4)/sizeof(g_C4[0]));
int iret=IsCircleGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是循環羣!":(iret==1?"G是非循環羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_C2C2;
int N=sqrt(sizeof(g_C2C2)/sizeof(g_C2C2[0]));
int iret=IsCircleGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是循環羣!":(iret==1?"G是非循環羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_C9;
int N=sqrt(sizeof(g_C9)/sizeof(g_C9[0]));
int iret=IsCircleGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是循環羣!":(iret==1?"G是非循環羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_S3;
int N=sqrt(sizeof(g_S3)/sizeof(g_S3[0]));
int iret=IsAbelianGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_D4;
int N=sqrt(sizeof(g_D4)/sizeof(g_D4[0]));
int iret=IsAbelianGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
#if 1
{
int *G=g_G12;
int N=sqrt(sizeof(g_G12)/sizeof(g_G12[0]));
int iret=IsAbelianGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_G16;
int N=sqrt(sizeof(g_G16)/sizeof(g_G16[0]));
int iret=IsAbelianGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=g_X16;
int N=sqrt(sizeof(g_X16)/sizeof(g_X16[0]));
int iret=IsAbelianGroup(G,N,0);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
#endif
{
int *G=&g_F4Add[0][0];
int N=sizeof(g_F4Add)/sizeof(g_F4Add[0]);
int iret=IsAbelianGroup(G,N);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=&g_F4Mul[0][0];
int N=sizeof(g_F4Mul)/sizeof(g_F4Mul[0]);
int iret=IsAbelianGroup(G,N);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=&g_Z4AddError[0][0];
int N=sizeof(g_Z4AddError)/sizeof(g_Z4AddError[0]);
int iret=IsAbelianGroup(G,N);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=&g_Z4Mul[0][0];
int N=sizeof(g_Z4Mul)/sizeof(g_Z4Mul[0]);
int iret=IsAbelianGroup(G,N);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
{
int *G=&g_C8Mul[0][0];
int N=sizeof(g_C8Mul)/sizeof(g_C8Mul[0]);
int iret=IsAbelianGroup(G,N);
MessageBoxA(NULL,iret==0?"G是交換羣!":(iret==1?"G是非交換羣":"G不是羣!"),"提示",MB_OK);
}
system("pause");
return 0;
}