矩阵转置,相乘,求逆

lcaamtb 2003-10-16 11:43:07
要求编写函数矩阵a[n][m]转置,相乘,求逆三个函数,并且,矩阵元素为double型的,n,m为用户输入。并且如何从函数返回矩阵。定给高分!!
...全文
1317 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
blas 2003-10-23
  • 打赏
  • 举报
回复
一个经过优化的矩阵乘法程序,比一般写法的程序要快4倍左右

int m;
int i, j, k;

double r;
double *A, *B, *C;

m = 1000;

A = new double[m*m];
B = new double[m*m];
C = new double[m*m];
// 或者如下
//A = (double*)malloc(m*m*sizeof(double));
//B = (double*)malloc(m*m*sizeof(double));
//C = (double*)malloc(m*m*sizeof(double));

//置初值
for (i=0; i<m*m; i++) {
A[i] = 1;
B[i] = 1;
C[i] = 0;
}

int bf1, bf2; // blocking factor
int ii, jj, kk, im;
int minj, mink;

bf1 = 48; // 可以修改
bf2 = 48;

for (jj=0; jj<m; jj+=bf1)
for (kk=0; kk<m; kk+=bf1) {
for (ii=0; ii<m%bf1; ii+=m%bf1) {
for (i=ii; i<m%bf1; ++i)
{
minj = (jj+bf1)<m ? (jj+bf1):m;
for (j=jj; j<minj; ++j) {
r = 0;
im = i*m;
mink = (kk+bf1)<m ? (kk+bf1):m;
for (k=kk; k<mink; ++k) {
r += A[im+k]*B[k*m+j];
}
C[im+j] += r;
}
}
}
for (; ii<m; ii+=bf1) {
for (i=ii; i<ii+bf1; ++i)
{
minj = (jj+bf1)<m ? (jj+bf1):m;
for (j=jj; j<minj; ++j) {
r = 0;
im = i*m;
mink = (kk+bf1)<m ? (kk+bf1):m;
for (k=kk; k<mink; ++k) {
r += A[im+k]*B[k*m+j];
}
C[im+j] += r;
}
}
}
}
delete[] A;
delete[] B;
delete[] C;
// 对应于malloc
//free(A);
//free(B);
//free(C);


jingle16 2003-10-23
  • 打赏
  • 举报
回复
对我很有用
谢谢了
lcaamtb 2003-10-18
  • 打赏
  • 举报
回复
不是的,因为我是为老师写一个TC程序,需要使用这些,不过谢谢你们,忘记说明一下,是要TC的,C++我看不懂,以前,我只使用过DELPHI,所以C 很差.可否麻烦各位再高台贵手,我的QQ:25389192,EMAIL:lcaamtb@hotmail.com;
iamknight 2003-10-16
  • 打赏
  • 举报
回复
数据结构相关的书中有全部的源代码。
playboyxp 2003-10-16
  • 打赏
  • 举报
回复
上面第二个漏乐一句
第十行插入b[j][i]=a[i][j];
playboyxp 2003-10-16
  • 打赏
  • 举报
回复
你合并一下
相乘
#include <iostream.h>
void main()
{
void multi(int a[3][2],int b[2][3]);
int a[3][2],b[2][3],i,j;
for( i=0;i<3;i++)
for( j=0;j<2;j++)
cin>>a[i][j];
for( i=0;i<2;i++)
for( j=0;j<3;j++)
cin>>b[i][j];
multi(a,b);
}
void multi(int a[3][2],int b[2][3])
{
int c[3][3],count=0,i,j,n;
for( i=0;i<3;i++)
for( j=0;j<3;j++)
c[i][j]=0;
for( i=0;i<3;i++)
for( j=0;j<3;j++)
for( n=0;n<2;n++)
c[i][j]=c[i][j]+a[i][n]*b[n][j];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
cout<<c[i][j]<<" ";
count++;
if(count%3==0) cout<<endl;
}
}
转置
#include <iostream.h>
void main()
{
int a[10][10],b[10][10];
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
cin>>a[i][j];
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
cout<<b[i][j];
}
动态开辟二维数组
#include <iostream.h>
void main()
{
int n,**p;
cin>>n;
p=new int*[n];
for(int i=0;i<n;i++)
p[i]=new int[n];
for(i=0;i<n;i++)
delete [] p[i];
delete [] p;
}
ttlb 2003-10-16
  • 打赏
  • 举报
回复
毕业设计?应该不止是做一个矩阵吧?
sharkhuang 2003-10-16
  • 打赏
  • 举报
回复
你是不是毕业设计做这个!我当年也做了这个!很无聊的!
cnxiaohai 2003-10-16
  • 打赏
  • 举报
回复
ttlb(小鸟___ttlb___)

写的太漂亮了

但我就是觉的太完整

读起来太复杂

其实playboyxp(learning)写的也不错

这是两种风格

playboyxp(learning)明显是学生

他的这种写法再工程开发的时候是不可取的

我很建议playboyxp(learning)去看看林锐的书

对了playboyxp是不是那个“永不死机”啊??????????????
ttlb 2003-10-16
  • 打赏
  • 举报
回复
template<typename T>
Matrix<T>& Matrix<T>::operator/= (const Matrix<T> &rhs)
{
if (rhs.m_iRow == m_iCol && rhs.m_iCol == m_iRow)
{
for (int i = 0; i < m_iRow; ++i)
for (int j = 0; j < m_iCol; ++j)
m_pptMat[i][j] += rhs.m_pptMat[i][j];
}
return *this;
}

// 友元函数:

template<typename T>
ostream& operator << (ostream & os, const Matrix<T> &rhs)
{
for (int i = 0; i < rhs.m_iRow; ++i)
{
for (int j = 0; j < rhs.m_iCol; ++j)
{
if (strcmp(typeid(rhs.m_pptMat[i][j]).name(), "double") == 0)
{
os << setw(12) << setprecision(6) << rhs.m_pptMat[i][j];
}
else
{
os << setw(10) << setprecision(6) << rhs.m_pptMat[i][j];
}
}
os << endl;
}
return os;
}

// helper 函数:

template<typename T>
inline Matrix<T> operator + (const Matrix<T> &lhs, const Matrix<T> &rhs)
{
Matrix<T> mat = lhs;
mat += rhs;
return mat;
}

template<typename T>
inline Matrix<T> operator - (const Matrix<T> &lhs, const Matrix<T> &rhs)
{
Matrix<T> mat = lhs;
mat -= rhs;
return mat;
}

template<typename T>
inline Matrix<T> operator * (const Matrix<T> &lhs, const Matrix<T> &rhs)
{
Matrix<T> mat = lhs;
mat *= rhs;
return mat;
}

template<typename T>
inline Matrix<T> operator / (const Matrix<T> &lhs, const Matrix<T> &rhs)
{
Matrix<T> mat = lhs;
mat /= rhs;
return mat;
}

}


#endif // _TTLB_MATRIX_H

ttlb 2003-10-16
  • 打赏
  • 举报
回复
// 函数定义:

template<typename T>
inline Matrix<T>::Matrix(int iRow, int iCol)
: m_iRow(iRow), m_iCol(iCol)
{
create(m_iRow, m_iCol);
}

template<typename T>
inline Matrix<T>::Matrix(const Matrix<T> &rhs)
: m_iRow(rhs.m_iRow), m_iCol(rhs.m_iCol)
{
create(m_iRow, m_iCol);
if (0 != m_iRow && 0 != m_iCol)
for (int i = 0; i < m_iRow; ++i)
memcpy(m_pptMat[i], rhs.m_pptMat[i], sizeof(T) * m_iCol);
}

template<typename T>
inline Matrix<T>& Matrix<T>::operator= (const Matrix<T> &rhs)
{
if (&rhs != this)
{
create(rhs.m_iRow, rhs.m_iCol);
if (0 != m_iRow && 0 != m_iCol)
for (int i = 0; i < m_iRow; ++i)
memcpy(m_pptMat[i], rhs.m_pptMat[i], sizeof(T) * m_iCol);
}
return *this;
}

template<typename T>
void Matrix<T>::create(int iRow, int iCol)
{
if (0 >= iRow || 0 >= iCol)
{
m_iRow = 0;
m_iCol = 0;
m_pptMat = 0;
}
else
{
m_iRow = iRow;
m_iCol = iCol;
m_pptMat = new T*[m_iRow];
for (int i = 0; i < m_iRow; ++i)
m_pptMat[i] = new T[m_iCol];
}
}

template<typename T>
inline void Matrix<T>::release()
{
if (0 != m_iRow && 0 != m_iCol)
{
for (int i = 0; i < m_iRow; ++i)
delete[] m_pptMat[i];
delete[] m_pptMat;
m_pptMat = 0;
m_iRow = m_iCol = 0;
}
}

template<typename T>
inline void Matrix<T>::resize(int iRow, int iCol)
{
if (iRow >= m_iRow && iCol >= m_iCol)
{
Matrix<T> mat(*this);
release();
create(iRow, iCol);
for (int i = 0; i < mat.m_iRow; ++i)
{
memcpy(m_pptMat[i], mat.m_pptMat[i], mat.m_iCol * sizeof(T));
}
}
}

template<typename T>
inline void Matrix<T>::swap_line(int i, int j)
{
if (i < m_iRow && i > 0 && j < m_iRow && j > 0)
{
for (int k = 0; k < m_iCol; ++k)
{
swap(m_pptMat[i][k], m_pptMat[j][k]);
}
}
}

template<typename T>
void Matrix<T>::transpose()
{
if (m_iCol != m_iRow)
{ // row col not equal, must realloc memory
Matrix<T> mat(*this);
release();
create(mat.m_iCol, mat.m_iRow);
for (int i = 0; i < m_iRow; ++i)
{
for (int j = 0; j < m_iCol; ++j)
{
m_pptMat[i][j] = mat.m_pptMat[j][i];
}
}
}
else
{ // row equals col, neednot realloc memory, swap only
for (int i = 0; i < m_iRow - 1; ++i)
{
for (int j = i + 1; j < m_iCol; ++j)
{
swap(m_pptMat[i][j], m_pptMat[j][i]);
}
}
}
}

template<typename T>
bool Matrix<T>::is_formulatable() const
{
return row() == col();
}

template<typename T>
double Matrix<T>::formulate()
{
assert(is_formulatable());

Matrix<T> mat(*this);

// 结果
double iResult = 1;

// 从上到下的行变换
for (int i = 0; i < m_iRow - 1; ++i)
{
// 如果主对角线上是 0, 则通过行交换使之不为零
if (0 == mat.m_pptMat[i][i])
{
for (int m = i + 1; m < mat.m_iRow; ++m)
{
if (mat.m_pptMat[m][i] != 0)
{
mat.swap_line(i, m);
iResult *= -1;
}
}
// 如果还是 0
if (0 == mat.m_pptMat[i][i])
{
return 0;
}
}
// 主对角线上不是 0
else
{
for (int j = i + 1; j < mat.m_iRow; ++j)
{
if (0 == mat.m_pptMat[j][i])
continue;
// 系数
double dMult = mat.m_pptMat[j][i] / mat.m_pptMat[i][i];
for (int k = 0; k < m_iCol; ++k)
{
mat.m_pptMat[j][k] -= mat.m_pptMat[i][k] * dMult;
}
}
}
} // for (int i = 0; i < m_iRow - 1; ++i), 从上到下的行变换结束
// 计算结果
for (int i = 0; i < mat.m_iRow; ++i)
{
iResult *= mat.m_pptMat[i][i];
}

return iResult;
}

template<typename T>
bool Matrix<T>::is_contradictable()
{
Matrix<T> mat(*this);
return 0 != mat.formulate();
}
// before contradict -> col change -> after contradict
// mat this mat this(result)
// 1 2 3 1 0 0 1 0 0 * * *
// 4 5 6 0 1 0 0 1 0 * * *
// 7 8 9 0 0 1 0 0 1 * * *
//
template<typename T>
void Matrix<T>::contradict()
{
if (is_contradictable())
{
Matrix<T> mat(*this);
// this 置为单位矩阵
reset();
for (int i = 0; i < m_iRow; ++i)
m_pptMat[i][i] = 1;
// 从上到下的行变换
for (int i = 0; i < m_iRow - 1; ++i)
{
// 如果主对角线上是 0, 则通过行交换使之不为 0
// 因为有 is_contradictable() 的保证
// 所以,行交换之后主对角线上的元素肯定不为 0
if (0 == mat.m_pptMat[i][i])
{
for (int m = i + 1; m < mat.m_iRow; ++m)
{
if (mat.m_pptMat[m][i] != 0)
{
mat.swap_line(i, m);
swap_line(i, m);
}
}
}
// 主对角线上不是 0
else
{
for (int j = i + 1; j < mat.m_iRow; ++j)
{
if (0 == mat.m_pptMat[j][i])
continue;
// 系数
double dMult = mat.m_pptMat[j][i] / mat.m_pptMat[i][i];
for (int k = 0; k < m_iCol; ++k)
{
m_pptMat[j][k] -= m_pptMat[i][k] * dMult;
mat.m_pptMat[j][k] -= mat.m_pptMat[i][k] * dMult;
}
}
}
} // for (int i = 0; i < m_iRow - 1; ++i), 从上到下的行变换结束

// 从下到上的行变换
// 因为已经进行了从上到下的行变换,所以,主对角线上不可能有 0
for (int i = m_iRow - 1; i > 0; --i)
{
for (int j = i - 1; j >= 0; --j)
{
if (0 == mat.m_pptMat[j][i])
continue;
double dMult = mat.m_pptMat[j][i] / mat.m_pptMat[i][i];
for (int k = m_iCol - 1; k >= 0; --k)
{
m_pptMat[j][k] -= m_pptMat[i][k] * dMult;
mat.m_pptMat[j][k] -= mat.m_pptMat[i][k] * dMult;
}
}
} // for (int i = m_iRow - 1; i > 0; --i), 从上到下的行变换结束

// mat 各位设为 1 ,使之成为单位矩阵,此时的 this 即为结果
// 因为已经进行了从上到下的行变换,所以,主对角线上不可能有 0
for (int i = 0; i < m_iRow; ++i)
{
for (int j = 0; j < m_iCol; ++j)
{
if (0 == m_pptMat[i][j])
continue;
m_pptMat[i][j] /= mat.m_pptMat[i][i];
}
}
} // if (is_contradictable()) 结束
}

template<typename T>
inline void Matrix<T>::reset()
{
for (int i = 0; i < m_iRow; ++i)
for (int j = 0; j < m_iCol; ++j)
m_pptMat[i][j] = 0;
}

template<typename T>
bool Matrix<T>::is_identity() const
{
if (m_iRow != m_iCol)
return false;
for (int i = 0; i < m_iRow; ++i)
{
if (m_pptMat[i][i] != static_cast<T>(1))
{
return false;
}
}
return true;
}

template<typename T>
inline Matrix<T>& Matrix<T>::operator+= (const Matrix<T> &rhs)
{
if (rhs.m_iRow == m_iRow && rhs.m_iCol == m_iCol)
{
for (int i = 0; i < m_iRow; ++i)
for (int j = 0; j < m_iCol; ++j)
m_pptMat[i][j] += rhs.m_pptMat[i][j];
}
return *this;
}

template<typename T>
inline Matrix<T>& Matrix<T>::operator-= (const Matrix<T> &rhs)
{
if (rhs.m_iRow == m_iRow && rhs.m_iCol == m_iCol)
{
for (int i = 0; i < m_iRow; ++i)
for (int j = 0; j < m_iCol; ++j)
m_pptMat[i][j] -= rhs.m_pptMat[i][j];
}
return *this;
}

template<typename T>
Matrix<T>& Matrix<T>::operator*= (const Matrix<T> &rhs)
{
if ((rhs.m_iRow == m_iCol && rhs.m_iCol == m_iRow)
&& !is_empty() && !rhs.is_empty())
{
Matrix<T> mat(*this);
Matrix<T> mat2(rhs);
if (m_iRow != m_iCol)
{
release();
create(mat.m_iRow, mat2.m_iCol);
}
reset();
for (int i = 0; i < m_iRow; ++i)
for (int j = 0; j < m_iCol; ++j)
for (int k = 0; k < mat.m_iCol; ++k)
m_pptMat[i][j] += mat.m_pptMat[i][k] * mat2.m_pptMat[k][j];
}
return *this;
}
ttlb 2003-10-16
  • 打赏
  • 举报
回复

// TtlbMatrix.h
// Part of Ttlb Library, in namespace ttlb
// Copyright: Ttlb(Tang Tao), 2003
// Includes Matrix manipulations

#ifndef _TTLB_MATRIX_H
#define _TTLB_MATRIX_H

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <cassert>
#include <typeinfo>
#include <cstring>
using std::ostream;
using std::cout;
using std::endl;
using std::swap;
using std::setw;
using std::setprecision;
// 不用声明 std::strcmp

namespace ttlb
{
template<typename T>
class Matrix
{
public:
// 构造函数
explicit Matrix(int iRow = 0, int iCol = 0);
// 拷贝构造函数
Matrix(const Matrix<T> &cmMat);
// 拷贝赋值
Matrix& operator= (const Matrix<T> &cmMat);
// destructor, virtual to support derivation
virtual ~Matrix() { release(); }

// 是否为空
bool is_empty() const { return 0 == m_iRow; }
// 改变(只允许扩大)容量
void resize(int iRow, int iCol);
// 交换第 i,j 两行
void swap_line(int i, int j);
// 转置
void transpose();
// 是否可以计算行列式
bool is_formulatable() const;
// 求行列式的值
double formulate();
// 是否可以求逆
bool is_contradictable();
// 求逆矩阵
void contradict();

// 下标操作符
T* operator[] (int iRowNum) const { return m_pptMat[iRowNum]; }
// 一系列算术运算操作符重载
Matrix& operator+= (const Matrix<T> &rhs);
Matrix& operator-= (const Matrix<T> &rhs);
Matrix& operator*= (const Matrix<T> &rhs);
Matrix& operator/= (const Matrix<T> &rhs);
// 输出操作符重载
template<typename T>
friend ostream& operator<< (ostream &os, const Matrix<T> &cmMat);

public:
// 全部置 0
void reset();
// 是否为单位矩阵
bool is_identity() const;
// 取得行数
int row() const { return m_iRow; }
// 取得列数
int col() const { return m_iCol; }

private:
// 分配内存(iRow 行, iCol 列)
void create(int iRow, int iCol);
// 释放内存
void release();

private:
int m_iRow; // 行
int m_iCol; // 列
T **m_pptMat; // 指向二维数组的指针
};

69,337

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧