duck_kk 2023-12-19 20:25 采纳率: 50%
浏览 1
已结题

链表形式存储的稀疏矩阵类相关错误

##在进行链表储存的稀疏矩阵类相关操作
#报多个类似错误

error C2440: “初始化”: 无法从“node *”转换为“node<hnode> *”
1> with
1> [
1> T=cnode
1> ]
1> and
1> [
1> T=int
1> ]
1>homework3.3.cpp(171,24): message : 指向的类型不相关; 转换需要 reinterpret_cast、C 样式强制转换或带圆括号的函数样式强制转换
1>homework3.3.cpp(168,61): message : 在编译 类 模板 成员函数“linkedmatrix &linkedmatrix::plus(linkedmatrix &)”时
1>homework3.3.cpp(469,30): message : 请参阅 "main" 中对 "linkedmatrix::plus" 的第一个引用
1>homework3.3.cpp(459,20): message : 查看对正在编译的 类 模板 实例化“linkedmatrix”的引用

#给出全部代码,为什么会报错呢?

#include<iostream>
using namespace std;

template<class T>
class node {
public:
    T data;
    node<T>* next;
    node<T>() { data = 0; next = nullptr; }
    node<T>(T a) { data = a; next = nullptr; }
};

template<class T>
class chain {
public:
    int length;
    node<T>* first;
    node<T>* tail;
    bool isempty() { return (first == nullptr); }
    chain<T>() { length = 0; first = tail = nullptr; }
    void insert(T a);
};

template<class T>
void chain<T>::insert(T a) {
    node<T>* p = new node<T>(a);
    if (isempty()) {
        first = p;
        tail = p;
        length++;
    }
    else {
        tail->next = p;
        tail = p;
        length++;
    }
}

template<class T>
class cnode {
public:
    int col;
    T value;
    int operator !=(cnode<T> a) { return (value != a.value); }
};

template<class T>
ostream& operator<<(ostream& out, cnode<T>& a) {
    out << "col=" << a.col << " " << "value=" << a.value << endl;
    return out;
}
template<class T>
istream& operator>>(istream& in, cnode<T>& a) {
    cout << "please input column" << endl;
    in >> a.col;
    cout << "please input value" << endl;
    in >> a.value;
    return in;
}

template<class T>
class hnode {
public:
    int row;
    chain<cnode<T>> b;
    int operator !=(hnode<T>& a) { return (row != a.row); }
};
template<class T>
ostream& operator<<(ostream& out, hnode<T>& a) {
    out << "row=" << a.row << endl;
    return out;
}
template<class T>
istream& operator>>(istream& in, hnode<T>& a) {
    cout << "please input row" << endl;
    in >> a.row;
    return in;
}

template<class T>
class linkedmatrix {
public:
    int rows;
    int cols;
    int num;
    chain<cnode<T>> a;

    template<class T>
    friend ostream& operator<<(ostream& out, linkedmatrix<T>& x);
    template<class T>
    friend istream& operator>>(istream& in, linkedmatrix<T>& x);

    linkedmatrix<T> &plus(linkedmatrix<T>& x);  //加
    linkedmatrix<T> &sub(linkedmatrix<T>& x);  //减
    linkedmatrix<T> &mul(linkedmatrix<T>& x);  //乘
    void transpose(linkedmatrix<T>& x);
    void set(int i, int j, T x);  //存入
    T get(int i, int j);  //取出

    linkedmatrix(int r, int c) {
        rows = r;
        cols = c;
    }
    linkedmatrix() {
        rows = 0;
        cols = 0;
        num = 0;
    }
};

template<class T>
ostream& operator<<(ostream& out, linkedmatrix<T>& x) {
    out << "rows=" << x.rows << " cols=" << x.cols << endl;
    node<hnode<T>> *p = x.a.first;//每一行的头节点组成的链表的首节点
    while (p) {
        hnode<T> temp = p->data;
        if (temp.b.first) {//每一行
            node<cnode<T>>* q = temp.b.first;
            cout << temp;
            while (q) {
                cnode<T> temp2 = q->data;
                cout << temp2;
                q = q->next;
            }
            cout << endl;
        }
        p = p->next;
    }
    return out;
}

template<class T>
istream& operator>>(istream& in, linkedmatrix<T>& x) {
    cout << "please input rows and columns" << endl;
    in >> x.rows >> x.cols;
    cout << "please input the numbers" << endl;
    in >> x.num;
    int i, j;
    T a;
    for (int k = 0; k < x.num; k++) {
        cout << "input the row, column and value of" << k << endl;
        cin >> i >> j >> a;
        x.set(i, j, a);
    }
}

template<class T>//转置矩阵
void linkedmatrix<T>::transpose(linkedmatrix<T>& x) {
    node<hnode<T>>* temp1 = a.first;
    node<cnode<T>>* temp2 = temp1->data.b.first;
    while (temp1)  //遍历所有行
    {
        node<cnode<T>>* link = temp2;
        while (link)  //遍历所有列
        {
            x.set(link->data.value, link->data.col, temp1->data.row);  //转置后位置放入
            next = next->link;  //当前行下一个元素
        }
        temp1 = temp1->next;
        if (!temp1)
            break;
        temp2 = temp1->data.b.first;
    }
}

//加法
template<class T>
linkedmatrix<T> & linkedmatrix<T>::plus(linkedmatrix<T>& x) {
    linkedmatrix<T> m(rows, cols);

    node<hnode<T>> *temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个节点
    node<hnode<T>> *temp2 = x.a.first;
    node<hnode<T>> *temp3 = m.a.first;

    while (temp1 && temp2) {  //同时遍历两个链表的每一行
        node<cnode<T>> *temp4 = temp1->data.b.first;  //指向每一行的非零元素组成的链表的第一个
        node<cnode<T>> *temp5 = temp2->data.b.first;

        //当两个行链表都不为空时
        while (temp4 && temp5) {  
            //列号相等则进行加法
            if (temp4->data.col == temp5->data.col) {  
                if (temp4->data.value + temp5->data.value) {  //如果相加后的value不为0则插入到新行链表中
                    cnode<T> a;
                    a.col = temp4->data.col;
                    a.value = temp4.data.value + temp5->data.value;
                    temp3->data.b.insert(a);//插入到结果矩阵的相应行中
                }
                temp4 = temp4->next;
                temp5 = temp5->next;
                if (!(temp4 && temp5)) {//如果为空 该行遍历完成
                    break;
                }
            }
            //一个的列号小于另一个列号,则将前一个插进新链表,并将前一个行链表指针右移
            if (temp4->data.col < temp5->data.col) {
                cnode<T> a;
                a.col = temp4->data.col;//列号和值为*this矩阵对应非零元素的列号和值
                a.value = temp4->data.value;
                temp3->data.b.insert(a);//插入到结果矩阵中
                temp4 = temp4->next;
                if (!temp4) {
                    break;
                }
            }
            //一个的列号大于另一个列号,则将后一个插进新链表,并将后一个行链表指针右移
            if (temp4->data.col > temp5->data.col) {
                cnode<T> a;
                a.col = temp5->data.col;//列号和值为x矩阵对应非零元素的列号和值
                a.value = temp5->data.value;
                temp3->data.b.insert(a);//插入到结果矩阵中
                temp5 = temp5->next;
                if (!temp5) {
                    break;
                }
            }
        }

        //后一个行链表已经遍历完,则把前一个链表所有剩余元素插进新链表
        while (temp4 && !temp5) {
            cnode<T> a;
            a.col = temp4->data.col;
            a.value = temp4->data.value;
            temp3->data.b.insert(a);
            temp4 = temp4->next;
        }

        //前一个行链表已经遍历完,则把后一个链表所有剩余元素插进新链表
        while (!temp4 && temp5) {
            cnode<T> a;
            a.col = temp5->data.col;
            a.value = temp5->data.value;
            temp3->data.b.insert(a);
            temp5 = temp5->next;
        }
        temp1 = temp1->next;//指向下一行
        temp2 = temp2->next;
        temp3 = temp3->next;
    }
    return m;
}

//相减
template<class T>
linkedmatrix<T> & linkedmatrix<T>::sub(linkedmatrix<T>& x) {
    linkedmatrix<T> m(rows, cols);

    node<hnode<T>>* temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个节点
    node<hnode<T>>* temp2 = x.a.first;
    node<hnode<T>>* temp3 = m.a.first;

    //同时遍历两个链表的每一行
    while (temp1 && temp2) {
        node<cnode<T>>* temp4 = temp1->data.b.first;//指向每一行的非零元素组成的链表的第一个
        node<cnode<T>>* temp5 = temp2->data.b.first;

        //当两个行链表都不为空时
        while (temp4 && temp5) {
            if (temp4->data.col == temp5->data.col) {//列号相等则进行减法
                if (temp4->data.value - temp5->data.value) {//如果相减后的value不为0则插入到新行链表中
                    cnode<T> a;
                    a.col = temp4->data.col;
                    a.value = temp4.data.value - temp5->data.value;
                    temp3->data.b.insert(a);
                }
                temp4 = temp4->next;
                temp5 = temp5->next;
                if (!(temp4 && temp5)) {
                    break;
                }
            }
            //一个的列号小于另一个列号,则将前一个插进新链表,并将前一个行链表指针右移
            if (temp4->data.col < temp5->data.col) {
                cnode<T> a;
                a.col = temp4->data.col;
                a.value = temp4->data.value;
                temp3->data.b.insert(a);
                temp4 = temp4->next;
                if (!temp4) {
                    break;
                }
            }
            //一个的列号大于另一个列号,则将后一个插进新链表,并将后一个行链表指针右移
            if (temp4->data.col > temp5->data.col) {
                cnode<T> a;
                a.col = temp5->data.col;
                a.value = -(temp5->data.value);
                temp3->data.b.insert(a);
                temp5 = temp5->next;
                if (!temp5) {
                    break;
                }
            }
        }
        //后一个行链表已经遍历完,则把前一个链表所有剩余元素插进新链表
        while (temp4 && !temp5) {
            cnode<T> a;
            a.col = temp4->data.col;
            a.value = temp4->data.value;
            temp3->data.b.insert(a);
            temp4 = temp4->next;
        }
        //前一个行链表已经遍历完,则把后一个链表所有剩余元素插进新链表
        while (!temp4 && temp5) {
            cnode<T> a;
            a.col = temp5->data.col;
            a.value = -(temp5->data.value);
            temp3->data.b.insert(a);
            temp5 = temp5->next;
        }
        temp1 = temp1->next;//指向下一行
        temp2 = temp2->next;
        temp3 = temp3->next;
    }
    return m;
}

//乘法
template<class T>
linkedmatrix<T>& linkedmatrix<T>::mul(linkedmatrix<T>& x) {
    linkedmatrix<T> y(x.cols, x.rows);  //转置后矩阵
    linkedmatrix<T> z(rows, x.cols);  //结果矩阵

    x.transpose(y);//转置后,乘法简化为两个双层链表逐行相乘

    node<hnode<T>>* temp1 = a.first;//指向矩阵的行头节点组成的链表的第一个
    node<hnode<T>>* temp2 = y.a.first;
    node<cnode<T>>* z1 = temp1->data.b.first;//指向矩阵每一行的非零元素组成的链表的第一个
    node<cnode<T>>* z2 = temp2->data.b.first;

    T sum = 0;//sum用来记录两行相乘后的数值

    while (temp1)//依次遍历*this矩阵的每一行
    {
        if (z1)//如果行链表不为空
        {
            while (temp2)//依次遍历y矩阵的每一行
            {
                //第二个矩阵的行链表为空,移动到其下一行
                while (!z2)
                {
                    temp2 = temp2->next;

                    if (!temp2) {  //temp2为空说明矩阵x中已经没有非零元素 结束循环
                        return z;
                    }

                    z2 = temp2->data.b.first;
                }

                //两个行链表都不为空则判断列号
                while (z1 && z2)
                {
                    //如果z1的列号大于z2的列号 z2右移
                    while (z1->data.col > z2->data.col)
                    {
                        z2 = z2->next;
                        if (!z2)//如果z2为空
                            goto L;//进入下一行
                    }
                    //如果z2的列号大于z1的列号 z1右移
                    while (z1->data.col < z2->data.col)
                    {
                        z1 = z1->next;
                        if (!z1)//如果z1为空
                            goto L;//指向下一行
                    }
                    //如果相等则相乘
                    if (z1->data.col == z2->data.col)
                    {
                        sum += z1->data.value * z2->data.value;
                        z1 = z1->next;
                        z2 = z2->next;
                    }
                L:;
                }
                if (sum)//当sum不为0则插进新链表
                {
                    z.set(sum, temp1->data.row, temp2->data.row);
                    sum = 0;//sum重置
                }

                z1 = temp1->data.b.first;  //z1重新指向*this当前行起始位置
                temp2 = temp2->next;//指向下一行
                if (!temp2)//temp2为空说明矩阵y中没有非零元素
                    break;
                z2 = temp2->data.b.first;
            }
        }
        temp1 = temp1->next;  //*this下一行
        if (!temp1)//temp1为空说明*this矩阵中没有非零元素
            break;
        z1 = temp1->data.b.first;
        temp2 = y.a.first;//重新指向第一个行头节点
        z2 = temp2->data.b.first;
    }
    return z;
}

template<class T>
void linkedmatrix<T>::set(int i, int j, T x) {
    node<hnode<T>> *p = a.first;
    while (p->data.row != i) {//p移动到所在行
        p = p->next;
    }
    node<cnode<T>>* q = p->data.b.first;//指向第r行行列表的头节点
    //如果此行为空 直接插入
    if (!q) {
        q = new node<cnode<T>>;
        q->data.col = j;
        q->data.value = x;
        p->data.b.insert(q->data.value);
        return *this;
    }
    int num = 0;//表示插入到链表中的具体位置坐标
    //如果此行不为空 遍历插入相应位置
    while (q) {
        if (q->data.col > j) {//当前col比列号大 插入到num位置(前面一位)
            node<cnode<T>> *temp = new node<cnode<T>>;
            temp->data.col = j;
            temp->data.value = x;
            p->data.b.insert(temp->data.value);
            return *this;
        }
        if (q->data.col == j) {
            cout << "此位置已存在数据,无法存入" << endl;
            return *this;
        }
        q = q.next;
        num++;
    }
    node<cnode<T>> *q1 = new node<cnode<T>>;//如果没有合适位置 插入队尾
    q1->data.col = j;
    q1->data.value = x;
    p->data.b.insert(q1->data.value);
    return *this;
}

template<class T>
T linkedmatrix<T>::get(int i, int j) {
    node<hnode<T>> *p = a.first;
    hnode<T> temp = p->data;

    //找到正确行
    while (temp.row != i) {
        p = p->next;
        temp = p->data;
    }

    node<cnode<T>> *q = temp.b.first;
    cnode<T> temp1 = q->data;
    while (temp1.col < j && q) {
        q = q->next;
        temp1 = q->next;
    }
    return temp1.value;
}
int main() {
    linkedmatrix<int> a, b;
    cin >> a;
    cin >> b;
    int i, j, v;
    cout << "pleasr input the row,column and value of the element that you want to store" << endl;
    cin >> i >> j >> v;
    a.set(i, j, v);
    cout << "please input the row and column of the element that you want to get" << endl;
    cin >> i >> j;
    a.get(i, j);
    cout << "a+b=" << a.plus(b) << endl;
    cout << "a-b=" << a.sub(b) << endl;
    cout << "a*b=" << a.mul(b) << endl;
    return 0;
}



  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 12月27日
    • 创建了问题 12月19日

    悬赏问题

    • ¥15 C++ 句柄后台鼠标拖动如何实现
    • ¥15 有人会SIRIUS 5.8.0这个软件吗
    • ¥30 comsol仿真等离激元
    • ¥15 静电纺丝煅烧后如何得到柔性纤维
    • ¥15 (标签-react native|关键词-镜像源)
    • ¥100 照片生成3D人脸视频
    • ¥15 伪装视频时长问题修改MP4的时长问题,
    • ¥15 JETSON NANO
    • ¥15 VS开发qt时如何在paintgl函数中用pushbutton控制切换纹理
    • ¥20 关于 openpyxl 处理excel文件地问题