C++实现关系与关系矩阵的代码详解

目录
  • ADT
    • 集合
    • 关系
    • 关系矩阵
  • 功能实现
    • 关系的矩阵表示
    • 关系的性质判断
    • 关系的合成
  • 参考:

ADT

集合

template<class Type>    //集合的元素类型
class Set{  //集合ADT
    int size;   //基数
    vector<Type> 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<size;i++){
            if(p[i]==e) return i;
        }
        return -1;
};

关系

template<class Type>
class Relation{
    Set<Type> dom;    //定义域
    Set<Type> 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<Type> getDom()const { return dom; }     //返回定义域
    Set<Type> 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);
};

关系矩阵

template<class Type>
class RMatrix:public Relation<Type>{
    vector< vector<short> > m;  //二维矩阵用vector实现,注意不能使用bool类型,它有很高的特殊性
    public:
    RMatrix(int r_,int c_):Relation<Type>(r_,c_){
        for(int i=0;i<r_;i++){
            vector<short> v(c_,0);
            m.push_back(v);     //推入r_个长度为c_的vector数组构成一个r*c的二维数组
        }
    }
    RMatrix():Relation<Type>(){   //不输入矩阵大小时
        for(int i=0;i<MAX_NUM;i++){
            vector<short> v(MAX_NUM,0);
            m.push_back(v);
        }
    }
    RMatrix(const RMatrix<Type> &M){  //复制构造函数
       // printf("here!");
        Set<Type> Dom=M.getDom(),Ran=M.getRan();
        int k1=Dom.getSize(),k2=Ran.getSize();
        for(int i=0;i<k1;i++){
            Relation<Type>::pushDom(Dom[i]);
        }
        for(int i=0;i<k2;i++){
            Relation<Type>::pushRan(Ran[i]);
        }
        m.resize(k1);
        for(int i=0;i<k1;i++){
            m[i].resize(0);
            for(int j=0;j<k2;j++){
                m[i].push_back(M[i][j]);
              //  printf("%d",m[i][j]);
            }
        }
    }
    void updateSize(){   //根据定义域和值域的基数设置矩阵规模
        int row=Relation<Type>::getDom().getSize();  //在子类中调用基类函数需要制定基类
        int col=Relation<Type>::getRan().getSize();
     //   printf("row=%d,col=%d",row,col);
        m.resize(row);
        for(int i=0;i<row;i++){
            m[i].resize(0);
            for(int j=0;j<col;j++){
                m[i].push_back(short(0));
             //   printf("%d",m[i][j]);
            }
        }
        return;
    }
    vector<short> operator[](int p1)const { return m[p1]; }    //可以直接双括号使用!
    void set(int p1,int p2,short e){     //设置矩阵值
        m[p1][p2]=e;
    }
    void push(vector<short> v){  //添加矩阵的行
        m.push_back(v);
    }
    /* 将两个关系矩阵合成,括号内的在右 */
    RMatrix<Type> matrixSynthesis(const RMatrix<Type> &M1)const {
        RMatrix<Type> M;    //此处的M是临时变量,必定被销毁,无法作为引用被返回	(<!-1)
        Set<Type> d=Relation<Type>::getDom(),r=M1.getRan();	//矩阵合成的行列关系差点弄错!
        int k1=d.getSize(),k2=r.getSize(),k3=M1.getR();
        for(int i=0;i<k1;i++){
            M.pushDom(d[i]);
        }
        for(int i=0;i<k2;i++){
            M.pushRan(r[i]);
        }
        M.updateSize();
        for(int i=0;i<k1;i++){
            for(int j=0;j<k2;j++){
                bool f=0;
                for(int p=0;p<k3;p++){
                    if(m[i][p] && M1[p][j]) f=1;
                }
                if(f) M.set(i,j,f);
            }
        }
        return M;
    }
    void randomRelation(){  //随机生成一段关系,需要放在updatesize之后
      //  printf("time=%d\n",time(0));       //伪随机的实现需要新添加两个文件头
        srand(time(0));     //初始化随机数
        int r=Relation<Type>::getR(),c=Relation<Type>::getC();
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                m[i][j]=rand()%2;   //生成0或1
            }
        }
        return ;
    }
    bool isSelf()const {  //自反性检测
        int r=Relation<Type>::getR();
        for(int i=0;i<r;i++){
            if(!m[i][i]) return 0;
        }
        return 1;
    }
    bool antiSelf()const {  //反自反性检测
        int r=Relation<Type>::getR();
        for(int i=0;i<r;i++){
            if(m[i][i]) return 0;
        }
        return 1;
    }
    bool isSymmetric()const { //对称性
        int r=Relation<Type>::getR();
        for(int i=0;i<r;i++){
            for(int j=i+1;j<r;j++){
                if(m[i][j]!=m[j][i]) return 0;
            }
        }
        return 1;
    }
    bool antiSymmetric()const { //反对称性,注意都为0不违反反对称性!
        int r=Relation<Type>::getR();
        for(int i=0;i<r;i++){
            for(int j=i+1;j<r;j++){
                if(m[i][j] && m[i][j]==m[j][i]) return 0;
            }
        }
        return 1;
    }
    bool isPassing()const {   //传递性
        RMatrix<Type> M_=matrixSynthesis(*this);	//const函数只能调用const函数 <!-2
        int r=Relation<Type>::getR();
        for(int i=0;i<r;i++){
            for(int j=0;j<r;j++){
                if(m[i][j]==0 && M_[i][j]==1) return 0;
            }
        }
        return 1;
    }
};
  • <!-1 处若是给函数返回值加上引用会报一个警告,调用函数后集合ADT处会出现一个内存错误,这是因为M此处是临时变量,是一定被销毁的,所以作为引用被返回当然就出了问题,而此处不用引用是完全可行的。如果一定要用引用,也许可以考虑把M定义为静态变量。
  • <!-2 处曾有过一个报错:"passing 'const RMatrix<char>' as 'this' argument discards qualifiers",原因是当时我只将 isPassing 函数设为const,却没把其中调用的 matrixSynthesis 函数设为const。

功能实现

关系的矩阵表示

根据关系输出矩阵:

void inputRelation(RMatrix<char> &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<char> 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<char> &M1){    //格式化输出矩阵,要定义常量成员函数
    Set<char> 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<char> M1;   //设置集合的元素为字符类型
    inputRelation(M1);
    outputMatrix(M1);
    return 0;

根据矩阵输出关系序偶:

void inputMatrix(RMatrix<char> &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<char> A=M1.getDom(),B=M1.getRan();
    */
    M1.updateSize();
    printf("请输入关系矩阵:(空格分隔)\n");
    int k=M1.getC(),tmp;
    for(int i=0;i<k;i++){
        for(int j=0;j<k;j++){
            scanf("%d",&tmp);
            if(tmp) M1.set(i,j,tmp);
        }
    }
    printf("\n");
    return;
}
void outputRelation(const RMatrix<char> &M1){    //格式化输出序偶,记得定义常量成员函数
    int k1=M1.getR(),k2=M1.getC();
    Set<char> 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(M1[i][j]){
              //  printf("i=%d,j=%d->",i,j);
                printf("(%c,%c) ",Dom[i],Ran[j]);
            }
        }
        printf("\n");
    }
}
int main(){
    RMatrix<char> M1;   //设置集合的元素为字符类型
    inputMatrix(M1);
    outputRelation(M1);
    return 0;
}

关系的性质判断

I. 输入一个包含n个元素的集合A,要求随机产生3个定义在集合A上的不同的关系R1,R2,R3,其中,R1和R2是自反且对称的,R3是反对称的,并显示R1,R2,R3的关系矩阵表示。

先上一个尝试用伪随机实现的算法

void inputSet(RMatrix<char> &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<char> A=M1.getDom(),B=M1.getRan();
    */
    M1.updateSize();
    printf("\n");
    return;
}
void outputMatrix(const RMatrix<char> &M1){    //格式化输出矩阵,要定义常量成员函数
    Set<char> 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<char> &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<char> M1;   //设置集合的元素为字符类型
    inputSet(M1);
    RMatrix<char> 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<char> &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<char> A=M1.getDom(),B=M1.getRan();
    */
    M1.updateSize();
    printf("\n");
    return;
}
void outputMatrix(const RMatrix<char> &M1,string str=""){    //格式化输出矩阵,要定义常量成员函数
    int k1=M1.getR(),k2=M1.getC();
    Set<char> 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<char> &M,bool isSelf,bool isSymmetric,bool antiSymmetric){   //后三个参数标记函数性质,分别为自反性,对称性,反对称性
    M.randomRelation();     //先基础随机化处理
    int r=M.getC();
    if(isSelf){     //补足自反性
        if(!M.isSelf()){
            for(int i=0;i<r;i++){
                M.set(i,i,1);
            }
        }
    }
    if(isSymmetric){        //补足对称性
        if(!M.isSymmetric()){
            for(int i=0;i<r;i++){
                for(int j=i+1;j<r;j++){
                    if(M[i][j]!=M[j][i]) M.set(j,i,M[i][j]);
                }
            }
        }
    }
    if(antiSymmetric){      //补足反对称性
        if(!M.antiSymmetric()){
            for(int i=0;i<r;i++){
                for(int j=i+1;j<r;j++){
                    if(M[i][j] && M[i][j]==M[j][i]) M.set(j,i,0);
                }
            }
        }
    }
}
int main(){
    RMatrix<char> M1;   //设置集合的元素为字符类型
    inputSet(M1);
    RMatrix<char> 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<char> &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<k;i++){
        for(int j=0;j<k;j++){
            scanf("%d",&tmp);
            if(tmp) M1.set(i,j,tmp);
        }
    }
    printf("\n");
    return;
}
void judgeMatrix(const RMatrix<char> &M1){
    if(M1.isSelf()) printf("具有自反性\n");
    if(M1.isSymmetric()) printf("具有对称性\n");
    if(M1.antiSymmetric()) printf("具有反对称性\n");
    if(M1.isPassing()) printf("具有传递性\n");
}
int main(){
    RMatrix<char> M1(6,6);
    inputMatrix(M1);
    judgeMatrix(M1);
    return 0;
}

关系的合成

关系合成运算:

void outputMatrix(const RMatrix<char> &M1){    //格式化输出矩阵,要定义常量成员函数
    int k1=M1.getR(),k2=M1.getC();
    Set<char> 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<char> &M1,RMatrix<char> &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<char> multiplyMatrix(const RMatrix<char> &M1,const RMatrix<char> &M2){  //默认集合元素就是char类型~
    RMatrix<char> M;
        Set<char> d=M1.getDom(),r=M2.getRan();
        int k1=d.getSize(),k2=r.getSize(),k3=M2.getR();
        for(int i=0;i<k1;i++){
            M.pushDom(d[i]);
        }
        for(int i=0;i<k2;i++){
            M.pushRan(r[i]);
        }
        M.updateSize();
        for(int i=0;i<k1;i++){
            for(int j=0;j<k2;j++){
                int f=0;
                for(int p=0;p<k3;p++){
                    if(M1[i][p] && M2[p][j]) f+=1;
                }
                if(f) M.set(i,j,f);
            }
        }
        return M;
}
void outputRelation(const RMatrix<char> &M1){    //格式化输出序偶,记得定义常量成员函数
    int k1=M1.getR(),k2=M1.getC();
    Set<char> 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(M1[i][j]){
              //  printf("i=%d,j=%d->",i,j);
                printf("(%c,%c) ",Dom[i],Ran[j]);
            }
        }
        printf("\n");
    }
}
void getCalculate(const RMatrix<char> &M1,const RMatrix<char> &M2){
    RMatrix<char> M=M1.matrixSynthesis(M2);     //布尔积运算
    printf("布尔积运算所得的");
    outputMatrix(M);    //输出布尔积结果
    RMatrix<char> M_=multiplyMatrix(M1,M2);     //矩阵乘积运算
    printf("矩阵乘积所得的");
    outputMatrix(M_);
    outputRelation(M);
    return;
}
int main(){
    RMatrix<char> M1,M2;   //设置集合的元素为字符类型
    inputRelation(M1,M2);
    getCalculate(M1,M2);
    return 0;
}

缝合并优化了几个函数。

关系的n次运算:

void outputMatrix(const RMatrix<char> &M1){    //格式化输出矩阵,要定义常量成员函数
    int k1=M1.getR(),k2=M1.getC();
    Set<char> 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<char> &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<char> &M1,int n){
    RMatrix<char> M(M1);
    int n_=n;
    n--;
    while(n--)
        M=M.matrixSynthesis(M);
    printf("得出 R^%d",n_);
    outputMatrix(M);
    return;
}
int main(){
    RMatrix<char> M1;   //设置集合的元素为字符类型
    inputRelation(M1);
    int n;
    printf("请输入n:");
    scanf("%d",&n);
    nR(M1,n);
    return 0;
}

参考:

知乎-vector<bool>

新世纪debug战士-C++实现伪随机

到此这篇关于C++实现关系与关系矩阵的文章就介绍到这了,更多相关C++关系矩阵内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++实现求动态矩阵各元素的和

    本文实例为大家分享了C++实现动态矩阵各元素的求和,供大家参考,具体内容如下 一.n阶方阵求和 功能:输入方阵维度,点击<Enter>,然后根据提示输入矩阵各阶元素,点击<Enter>,最后输出矩阵以及矩阵各元素的和. 代码: #include<iostream> using namespace std; //输入维度n,输出n维矩阵,并求各元素和 int main() { int **p,n,i,j,sum=0; cout<<"请输入矩阵维度n:

  • C++实现转置矩阵的循环

    目录 前言 一.思路分析 二.代码实现 1.转置矩阵函数 2.调用函数实现转置矩阵 总结 前言 矩阵的转置主要考查我们对循环的使用,通过简单的循环结构,我们可以很方便的完成矩阵的转置. 一.思路分析 转置矩阵与原矩阵的区别在于行列交换,我们可以构建一个二维数组完成对原矩阵的存储,我们只需将每个元素与其行列相反的位置处的元素进行交换,就可完成对矩阵的转置. 二.代码实现 1.转置矩阵函数 我们首先编写一个函数,完成对矩阵的转置. 代码如下(示例): /* Alkaid#3529 */ // 转职矩

  • c++中的继承关系

    1 什么是继承 继承概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能.这样产生新的类,称派生类.继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程. 面向对象的继承关系指类之间的父子关系.用类图表示如下: 2 为什么要有继承?/ 继承的意义? 因为继承是面向对象中代码复用的一种手段.通过继承,可以获取父类的所有功能,也可以在子类中重写父类已有的功能 以及 添加父类中没有的功能. 3如何理

  • C/C++实现蛇形矩阵的示例代码

    目录 题目描述 题解部分 完整代码 菜鸡蒟蒻想在博客中记录一些算法学习的心得体会,会持续更新C/C++方面的题解,方便理清思路和日后复习.如果还能结识一起敲代码的小伙伴的话就更好啦嘿嘿,因为实在是太弱了,肯定免不了错误百出.欢迎批评指正,期待共同成长! 题目描述 给出一个不大于 9 的正整数 n,输出 n×n 的蛇形方阵. 从左上角填上 1 开始,顺时针方向依次填入数字,如同样例所示.注意每个数字有都会占用 3 个字符,前面使用空格补齐. 输入样例 输入 4 输出 1  2  3  4 12 1

  • C++实现关系与关系矩阵的代码详解

    目录 ADT 集合 关系 关系矩阵 功能实现 关系的矩阵表示 关系的性质判断 关系的合成 参考: ADT 集合 template<class Type> //集合的元素类型 class Set{ //集合ADT int size; //基数 vector<Type> p; public: Set():size(0){} Set(int s):size(s){ p.resize(s); //重置大小 } int getSize()const{ return size; } void

  • MySQL主库binlog(master-log)与从库relay-log关系代码详解

    主库binlog: # at 2420 #170809 17:16:20 server id 1882073306 end_log_pos 2451 CRC32 0x58f2db87 Xid = 32880 COMMIT/*!*/; # at 2451 #170814 11:07:18 server id 1882073306 end_log_pos 2528 CRC32 0x40774a4b Query thread_id=92 exec_time=0 error_code=0 SET TIM

  • java编程无向图结构的存储及DFS操作代码详解

    图的概念 图是算法中是树的拓展,树是从上向下的数据结构,结点都有一个父结点(根结点除外),从上向下排列.而图没有了父子结点的概念,图中的结点都是平等关系,结果更加复杂. 无向图                                                       有向图 图G=(V,E),其中V代表顶点Vertex,E代表边edge,一条边就是一个定点对(u,v),其中(u,v)∈V. 这两天遇到一个关于图的算法,在网上找了很久没有找到java版的关于数据结构中图的存储及其

  • Python自然语言处理之词干,词形与最大匹配算法代码详解

    本文主要对词干提取及词形还原以及最大匹配算法进行了介绍和代码示例,Python实现,下面我们一起看看具体内容. 自然语言处理中一个很重要的操作就是所谓的stemming和lemmatization,二者非常类似.它们是词形规范化的两类重要方式,都能够达到有效归并词形的目的,二者既有联系也有区别. 1.词干提取(stemming) 定义:Stemmingistheprocessforreducinginflected(orsometimesderived)wordstotheirstem,base

  • Java编程实现快速排序及优化代码详解

    普通快速排序 找一个基准值base,然后一趟排序后让base左边的数都小于base,base右边的数都大于等于base.再分为两个子数组的排序.如此递归下去. public class QuickSort { public static <T extends Comparable<? super T>> void sort(T[] arr) { sort(arr, 0, arr.length - 1); } public static <T extends Comparabl

  • Spring自动装配与扫描注解代码详解

    1 javabean的自动装配 自动注入,减少xml文件的配置信息. <?xml version="1.0" encoding="UTF-8"?> <!-- 到入xml文件的约束 --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p&quo

  • Hibernate中Session增删改查操作代码详解

    把三状态转换图放在这,方便分析方法的作用: 1.Session的save()方法 Session是Hibernate所有接口中最重要的接口,提供了对数据保存,更新,查询和删除的方法. Session的save()方法可以使临时态或游离态转换为持久态.例如,保存一个Customer对象: SessionFactory sessionFactory; Configuration configuration = new Configuration().configure(); sessionFacto

  • Python类的继承和多态代码详解

    Python类的继承 在OOP(ObjectOrientedProgramming)程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Baseclass.Superclass). 我们先来定义一个classPerson,表示人,定义属性变量name及sex(姓名和性别): 定义一个方法print_title():当sex是male时,printman:当sex是female时,prin

  • Java的静态类型检查示例代码详解

    关于静态类型检查和动态类型检查的解释: 静态类型检查:基于程序的源代码来验证类型安全的过程: 动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间分析程序,确保没有类型错误.基本的思想是不要让类型错误在运行期间发生. 在各色各样的编程语言中,总共存在着两个类型检查机制:静态类型检查和动态类型检查. 静态类型检查是指通过对应用程序的源码进行分析,在编译期间就保证程序的类型安全. 动态类型检查是在程序的运行过程中,验证程序的类型安全.在Java中,编译期间使用静态类型

  • Python面向对象之继承代码详解

    本文研究的主要是Python面向对象之继承的相关内容,具体如下. Python 继承 即一个派生类(derived class)继承基类(bass class)字段和方法.继承也允许把一个派生类的对象作为一个基类对象对待.例如,有这样一个设计,一个Cat类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例如,Cat是一个Animal). 继承实现了代码的重用. 继承的基本语法: class 派生类名(基类名1 [, 基类名2....]): 基类名写在括号里,基本类是在

随机推荐