網站首頁 編程語言 正文
ADT
集合
template//集合的元素類型 class Set{ //集合ADT int size; //基數 vector p; public: Set():size(0){} Set(int s):size(s){ p.resize(s); //重置大小 } int getSize()const{ return size; } void push(Type e){ //添加元素 size++; p.push_back(e); void set(int pos,Type e){ //設置元素值 p[pos]=e; Type operator[](int i){ return p[i]; } //下標讀取 int findElem(Type e){ //返回指定元素的下標 for(int i=0;i
關系
templateclass Relation{ Set dom; //定義域 Set ran; //值域 public: Relation():dom(),ran(){} //無規模的初始化 Relation(int r_,int c_):dom(r_),ran(c_){} //有規模的初始化 int getR()const { return dom.getSize(); } //返回行,基類私有成員只可調用基類非私有函數獲得 int getC()const { return ran.getSize(); } //返回列 Set getDom()const { return dom; } //返回定義域 Set getRan()const { return ran; } //返回值域 void pushDom(Type e){ dom.push(e); } //給定義域添加元素 void pushRan(Type e){ ran.push(e); } //給值域添加元素 int findDom(Type e){ //尋找定義域中元素的位置 return dom.findElem(e); } int findRan(Type e){ //尋找值域中元素的位置 return ran.findElem(e); };
關系矩陣
templateclass RMatrix:public Relation { vector< vector > m; //二維矩陣用vector實現,注意不能使用bool類型,它有很高的特殊性 public: RMatrix(int r_,int c_):Relation (r_,c_){ for(int i=0;i v(c_,0); m.push_back(v); //推入r_個長度為c_的vector數組構成一個r*c的二維數組 } } RMatrix():Relation (){ //不輸入矩陣大小時 for(int i=0;i v(MAX_NUM,0); m.push_back(v); } } RMatrix(const RMatrix &M){ //復制構造函數 // printf("here!"); Set Dom=M.getDom(),Ran=M.getRan(); int k1=Dom.getSize(),k2=Ran.getSize(); for(int i=0;i ::pushDom(Dom[i]); } for(int i=0;i ::pushRan(Ran[i]); } m.resize(k1); for(int i=0;i ::getDom().getSize(); //在子類中調用基類函數需要制定基類 int col=Relation ::getRan().getSize(); // printf("row=%d,col=%d",row,col); m.resize(row); for(int i=0;i operator[](int p1)const { return m[p1]; } //可以直接雙括號使用! void set(int p1,int p2,short e){ //設置矩陣值 m[p1][p2]=e; } void push(vector
v){ //添加矩陣的行 m.push_back(v); } /* 將兩個關系矩陣合成,括號內的在右 */ RMatrix matrixSynthesis(const RMatrix &M1)const { RMatrix M; //此處的M是臨時變量,必定被銷毀,無法作為引用被返回 ( d=Relation ::getDom(),r=M1.getRan(); //矩陣合成的行列關系差點弄錯! int k1=d.getSize(),k2=r.getSize(),k3=M1.getR(); for(int i=0;i ::getR(),c=Relation ::getC(); for(int i=0;i ::getR(); for(int i=0;i ::getR(); for(int i=0;i ::getR(); for(int i=0;i ::getR(); for(int i=0;i M_=matrixSynthesis(*this); //const函數只能調用const函數 ::getR(); for(int i=0;i
- ' as 'this' argument discards qualifiers",原因是當時我只將 isPassing 函數設為const,卻沒把其中調用的 matrixSynthesis 函數設為const。
功能實現
關系的矩陣表示
根據關系輸出矩陣:
void inputRelation(RMatrix&M1){ //輸入關系 printf("請輸入集合A的元素:\n"); string str; // cin.get(); //這里不能直接這樣寫,因為前面有可能是沒有換行符的,那你就會少讀一個字符,所以只能靈活加 getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); M1.pushRan(inp); } /* printf("請輸入集合B的元素:\n"); stringstream ss2(str); while(ss2>>inp){ int k1=M1.getR(),k2=M1.getC(); Set A=M1.getDom(),B=M1.getRan(); */ M1.updateSize(); printf("請輸入關系R:(格式為\'a,b\'并用空格分割)\n"); stringstream ss(str); int a,b; int isA=1; while(ss>>inp){ //使用">>"流輸入字符類型會自動忽略空格...抽象了,printf是讀取空格的 // printf("%c",inp); if(inp==',') isA=0; else{ if(isA) a=M1.findDom(inp); else{ b=M1.findRan(inp); isA=1; M1.set(a,b,1); } } printf("\n"); return; } void outputMatrix(const RMatrix &M1){ //格式化輸出矩陣,要定義常量成員函數 Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系矩陣如下:\n"); for(int i=0;i<=k1;i++){ // printf("here?"); //手動斷點 for(int j=0;j<=k2;j++){ if(i==0 && j==0) printf(" "); else if(j==0) printf("%c ",Dom[i-1]); else if(i==0) printf("%c ",Ran[j-1]); else{ printf("%d ",M1[i-1][j-1]); } printf("\n"); int main(){ RMatrix M1; //設置集合的元素為字符類型 inputRelation(M1); outputMatrix(M1); return 0;
根據矩陣輸出關系序偶:
void inputMatrix(RMatrix&M1){ //輸入矩陣 printf("請輸入集合A的元素:\n"); string str; getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); M1.pushRan(inp); } /* printf("請輸入集合B的元素:\n"); getline(cin,str); stringstream ss2(str); while(ss2>>inp){ M1.pushRan(inp); } int k1=M1.getR(),k2=M1.getC(); Set A=M1.getDom(),B=M1.getRan(); */ M1.updateSize(); printf("請輸入關系矩陣:(空格分隔)\n"); int k=M1.getC(),tmp; for(int i=0;i &M1){ //格式化輸出序偶,記得定義常量成員函數 int k1=M1.getR(),k2=M1.getC(); Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系序偶如下:\n"); for(int i=0;i ",i,j); printf("(%c,%c) ",Dom[i],Ran[j]); } } printf("\n"); } } int main(){ RMatrix M1; //設置集合的元素為字符類型 inputMatrix(M1); outputRelation(M1); return 0; }
關系的性質判斷
I. 輸入一個包含n個元素的集合A,要求隨機產生3個定義在集合A上的不同的關系R1,R2,R3,其中,R1和R2是自反且對稱的,R3是反對稱的,并顯示R1,R2,R3的關系矩陣表示。
先上一個嘗試用偽隨機實現的算法
void inputSet(RMatrix&M1){ //輸入集合 printf("請輸入集合A的元素:\n"); string str; getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); M1.pushRan(inp); } /* printf("請輸入集合B的元素:\n"); stringstream ss2(str); while(ss2>>inp){ int k1=M1.getR(),k2=M1.getC(); Set A=M1.getDom(),B=M1.getRan(); */ M1.updateSize(); printf("\n"); return; } void outputMatrix(const RMatrix &M1){ //格式化輸出矩陣,要定義常量成員函數 Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系矩陣如下:\n"); for(int i=0;i<=k1;i++){ // printf("here?"); //手動斷點 for(int j=0;j<=k2;j++){ if(i==0 && j==0) printf(" "); else if(j==0) printf("%c ",Dom[i-1]); else if(i==0) printf("%c ",Ran[j-1]); else{ printf("%d ",M1[i-1][j-1]); } } printf("\n"); void getRandom(RMatrix &M,bool isSelf,bool isSymmetric,bool antiSymmetric){ //后三個參數標記函數性質,分別為自反性,對稱性,反對稱性 while(1){ M.randomRelation(); if(M.isSelf()==isSelf && M.isSymmetric()==isSymmetric && M.antiSymmetric()==antiSymmetric) return; int main(){ RMatrix M1; //設置集合的元素為字符類型 inputSet(M1); RMatrix M2(M1),M3(M1); getRandom(M1,1,1,0); getRandom(M2,1,1,0); getRandom(M3,0,0,1); outputMatrix(M1); outputMatrix(M2); outputMatrix(M3); return 0;
構想是挺美好的,但是偽隨機的效果讓這個方法行不通,因為隨機的效率太低,是按秒變化的,除非直接寫在成員函數中根據一個seed一直隨機,否則程序不可能通暢,但寫在成員函數也不好,太特殊。
以下是后手加工版本:
void inputSet(RMatrix&M1){ //輸入集合 printf("請輸入集合A的元素:\n"); string str; getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); M1.pushRan(inp); } /* printf("請輸入集合B的元素:\n"); getline(cin,str); stringstream ss2(str); while(ss2>>inp){ M1.pushRan(inp); } int k1=M1.getR(),k2=M1.getC(); Set A=M1.getDom(),B=M1.getRan(); */ M1.updateSize(); printf("\n"); return; } void outputMatrix(const RMatrix &M1,string str=""){ //格式化輸出矩陣,要定義常量成員函數 int k1=M1.getR(),k2=M1.getC(); Set Dom=M1.getDom(),Ran=M1.getRan(); str=str+"關系矩陣如下:\n"; //連接矩陣名稱 printf("%s",str.c_str()); for(int i=0;i<=k1;i++){ // printf("here?"); //手動斷點 for(int j=0;j<=k2;j++){ if(i==0 && j==0) printf(" "); else if(j==0) printf("%c ",Dom[i-1]); else if(i==0) printf("%c ",Ran[j-1]); else{ printf("%d ",M1[i-1][j-1]); } } printf("\n"); } } void getRandom(RMatrix &M,bool isSelf,bool isSymmetric,bool antiSymmetric){ //后三個參數標記函數性質,分別為自反性,對稱性,反對稱性 M.randomRelation(); //先基礎隨機化處理 int r=M.getC(); if(isSelf){ //補足自反性 if(!M.isSelf()){ for(int i=0;i M1; //設置集合的元素為字符類型 inputSet(M1); RMatrix M2(M1),M3(M1); getRandom(M1,1,1,0); getRandom(M2,1,1,0); getRandom(M3,0,0,1); outputMatrix(M1,"R1"); outputMatrix(M2,"R2"); outputMatrix(M3,"R3"); return 0; }
輸出函數優化了一下,可以輸出矩陣名稱了。
II.給定一個矩陣判斷其性質,并輸出結果
void inputMatrix(RMatrix&M1){ //輸入矩陣 for(int i=0;i<6;i++){ M1.setDom(i,' '); M1.setRan(i,' '); } printf("請輸入關系矩陣:(空格分隔)\n"); int k=6,tmp; for(int i=0;i &M1){ if(M1.isSelf()) printf("具有自反性\n"); if(M1.isSymmetric()) printf("具有對稱性\n"); if(M1.antiSymmetric()) printf("具有反對稱性\n"); if(M1.isPassing()) printf("具有傳遞性\n"); } int main(){ RMatrix M1(6,6); inputMatrix(M1); judgeMatrix(M1); return 0; }
關系的合成
關系合成運算:
void outputMatrix(const RMatrix&M1){ //格式化輸出矩陣,要定義常量成員函數 int k1=M1.getR(),k2=M1.getC(); Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系矩陣如下:\n"); for(int i=0;i<=k1;i++){ // printf("here?"); //手動斷點 for(int j=0;j<=k2;j++){ if(i==0 && j==0) printf(" "); else if(j==0) printf("%c ",Dom[i-1]); else if(i==0) printf("%c ",Ran[j-1]); else{ printf("%d ",M1[i-1][j-1]); } } printf("\n"); } } void inputRelation(RMatrix &M1,RMatrix &M2){ //輸入關系 printf("請輸入集合A的元素:\n"); string str; getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); } printf("請輸入集合B的元素:\n"); getline(cin,str); stringstream ss2(str); while(ss2>>inp){ M1.pushRan(inp); M2.pushDom(inp); } printf("請輸入集合C的元素:\n"); getline(cin,str); stringstream ss3(str); while(ss3>>inp){ M2.pushRan(inp); } M1.updateSize(); M2.updateSize(); printf("請輸入關系R1:(格式為\'a,b\'并用空格分割)\n"); getline(cin,str); stringstream ss(str); int a,b; int isA=1; while(ss>>inp){ //使用">>"流輸入字符類型會自動忽略空格...抽象了,printf是讀取空格的 // printf("%c",inp); if(inp==',') isA=0; else{ if(isA) a=M1.findDom(inp); else{ b=M1.findRan(inp); isA=1; M1.set(a,b,1); } } } printf("R1"); outputMatrix(M1); printf("請輸入關系R2:(格式為\'a,b\'并用空格分割)\n"); getline(cin,str); stringstream ss_(str); isA=1; while(ss_>>inp){ //使用">>"流輸入字符類型會自動忽略空格...抽象了,printf是讀取空格的 // printf("%c",inp); if(inp==',') isA=0; else{ if(isA) a=M2.findDom(inp); else{ b=M2.findRan(inp); isA=1; M2.set(a,b,1); } } } printf("R2"); outputMatrix(M2); printf("\n"); return; } RMatrix multiplyMatrix(const RMatrix &M1,const RMatrix &M2){ //默認集合元素就是char類型~ RMatrix M; Set d=M1.getDom(),r=M2.getRan(); int k1=d.getSize(),k2=r.getSize(),k3=M2.getR(); for(int i=0;i &M1){ //格式化輸出序偶,記得定義常量成員函數 int k1=M1.getR(),k2=M1.getC(); Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系序偶如下:\n"); for(int i=0;i ",i,j); printf("(%c,%c) ",Dom[i],Ran[j]); } } printf("\n"); } } void getCalculate(const RMatrix &M1,const RMatrix &M2){ RMatrix M=M1.matrixSynthesis(M2); //布爾積運算 printf("布爾積運算所得的"); outputMatrix(M); //輸出布爾積結果 RMatrix M_=multiplyMatrix(M1,M2); //矩陣乘積運算 printf("矩陣乘積所得的"); outputMatrix(M_); outputRelation(M); return; } int main(){ RMatrix M1,M2; //設置集合的元素為字符類型 inputRelation(M1,M2); getCalculate(M1,M2); return 0; }
縫合并優化了幾個函數。
關系的n次運算:
void outputMatrix(const RMatrix&M1){ //格式化輸出矩陣,要定義常量成員函數 int k1=M1.getR(),k2=M1.getC(); Set Dom=M1.getDom(),Ran=M1.getRan(); printf("關系矩陣如下:\n"); for(int i=0;i<=k1;i++){ // printf("here?"); //手動斷點 for(int j=0;j<=k2;j++){ if(i==0 && j==0) printf(" "); else if(j==0) printf("%c ",Dom[i-1]); else if(i==0) printf("%c ",Ran[j-1]); else{ printf("%d ",M1[i-1][j-1]); } } printf("\n"); } } void inputRelation(RMatrix &M1){ //輸入關系 printf("請輸入集合A的元素:\n"); string str; // cin.get(); //這里不能直接這樣寫,因為前面有可能是沒有換行符的,那你就會少讀一個字符,所以只能靈活加 getline(cin,str); stringstream ss1(str); char inp; while(ss1>>inp){ M1.pushDom(inp); M1.pushRan(inp); } M1.updateSize(); printf("請輸入關系R:(格式為\'a,b\'并用空格分割)\n"); getline(cin,str); stringstream ss(str); int a,b; int isA=1; while(ss>>inp){ //使用">>"流輸入字符類型會自動忽略空格...抽象了,printf是讀取空格的 // printf("%c",inp); if(inp==',') isA=0; else{ if(isA) a=M1.findDom(inp); else{ b=M1.findRan(inp); isA=1; M1.set(a,b,1); } } } printf("已知R"); outputMatrix(M1); return; } void nR(const RMatrix &M1,int n){ RMatrix M(M1); int n_=n; n--; while(n--) M=M.matrixSynthesis(M); printf("得出 R^%d",n_); outputMatrix(M); return; } int main(){ RMatrix M1; //設置集合的元素為字符類型 inputRelation(M1); int n; printf("請輸入n:"); scanf("%d",&n); nR(M1,n); return 0; }
參考:
知乎-vector
新世紀debug戰士-C++實現偽隨機
原文鏈接:https://www.cnblogs.com/Forest-set-you/p/16098277.html
相關推薦
- 2022-05-28 C#調用WebService的方法介紹_C#教程
- 2022-11-14 python流程控制語句
- 2022-10-21 golang?一次性定時器Timer用法及實現原理詳解_Golang
- 2022-07-19 Python數據分析之?Matplotlib?餅圖繪制_python
- 2022-04-23 uniapp文件上傳(任意文件,多文件上傳)
- 2022-05-05 詳解C語言結構體中的char數組如何賦值_C 語言
- 2022-08-12 Qt實現拖動單個控件移動的示例代碼_C 語言
- 2022-01-17 滑動列表數據按照A-Z首字母排列,右邊A-Z能動態定位到相應字母位置
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支