PDA

View Full Version : Class ma trận, lỗi câu lệnh if kiểm tra điều kiện nhân 2 ma trận, sửa giúp mình!



code_c
20-12-2011, 04:48 PM
Như chúng ta đã biết muốn nhân 2 ma trận thì 2 ma trận phải cùng cấp hoặc số cột của ma trận này bằng só hàng của ma trận kia.
VD: Ma trận cấp mm nhân vs ma trận cấp mm sẽ ra ma trận cấp mm, ma tran cap mn nhân vs ma trận cấp np sẽ ra ma trận cấp mp.
ở đây chỗ kiểm tra dk nhân 2 ma trận của mình mới đúng dk 1 ý là ma trận cấp mm *mm thì được còn nhâp cấp mn*np thì chưa đúng, các bạn xem sửa giúp với.


if(m != k.m || n != k.n)
{
cout<<"Hai tran phai cung cap moi nhan duoc\n";
exit(0);
}

// matran1.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "math.h"

using namespace std;

class matran
{
private:
int m,n;
int a[10][10];
public:
matran();
matran(int a,int b,int x);
~matran();
void nhapc1();//ham nhap lam cach 1
void nhapc2();//ham nhap lam cach 2
void xuat();
matran operator+(matran &k);//tru 2 ma tran lam tuong tu
matran operator*(matran &k);
friend ostream & operator << (ostream &output, matran &k);
friend istream & operator >> (istream &input, matran &k);
};

matran::matran()
{
m=n=1;
a[0][0]=1;
}

matran::matran(int m1,int n1,int x)
{
m=m1;
n=n1;
for(int i=1;i<=m1;i++)
for(int j=1;j<=n1;j++)
{
a[i][j]=x;
}
}

matran::~matran()
{
m=n=0;
}

void matran::nhapc1()
{
cout<<"Nhap so dong:";
cin>>m;
cout<<"Nhap so cot: ";
cin>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
cout<<"\nNhap phan tu hang "<<i<<" cot "<<j<<" = ";
cin>>a[i][j];
}
}

void matran::nhapc2()
{
do
{
cout<<"Nhap so hang:";
cin>>m;
cout<<"Nhap so cot:";
cin>>n;
}
while((m<=1||m>=10)&&(n<=1||n>=10));
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
cout<<"\nNhap phan tu hang "<<i<<" cot "<<j<<" = ";
cin>>a[i][j];
}
}

void matran::xuat()
{
for(int i=1;i<=m;i++)
{
cout<<"\n";
for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<"\n";
}
}
istream & operator >> (istream &input,matran &k)
{
cout<<"Nhap so hang:";
input>>k.m;
cout<<"Nhap so cot:";
input>>k.n;
for(int i=1;i<=k.m;i++)
for(int j=1;j<=k.n;j++)
{
cout<<"Phan tu hang "<<i<<" cot "<<j<<" :";
input>>k.a[i][j];
}
return input;
}

ostream & operator << (ostream &output,matran &k)
{
for(int i=1;i<=k.m;i++)
{
output<<"\n";
for(int j=1;j<=k.n;j++)
output<<k.a[i][j]<<" ";
output<<"\n";
}
return output;
}

matran matran::operator+(matran &k)
{
matran x;
if(m!=k.m || n!=k.n)
{
cout<<"Hai ma tran phai cung cap moi cong duoc!";
exit(0);
}
else
{
x.m = k.m;
x.n = k.n;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
x.a[i][j] = a[i][j]+ k.a[i][j];
}
return x;
}

matran matran::operator*(matran &k)
{
matran x;
if(m != k.m || n != k.n)
{
cout<<"Hai tran phai cung cap moi nhan duoc\n";
exit(0);
}
else
{
x.m = k.m;
x.n = k.n;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
{
x.a[i][j] = 0,0;
for(int t=1;t<=x.n;t++)
x.a[i][j] += a[i][t]*k.a[t][j];
}
}
return x;
}

void main()
{
cout<<"Ham khoi tao ma tran co doi so: ";
matran x(2,2,1);
x.xuat();

cout<<"Nhap ma tran 1\n";
matran a,b,c,d;
a.nhapc1();
cout<<"Xuat ma tran 1:";
a.xuat();

cout<<"Nhap ma tran 2\n";
b.nhapc2();
cout<<"Xuat ma tran 2:";
b.xuat();

cout<<"Hai ma tran cong voi nhau:";
c=a+b;
cout<<c;

cout<<"Hai ma tran nhan voi nhau:";
d=a*b;
cout<<d;

getch();
}

treatmaster
20-12-2011, 10:11 PM
nhân ma trận thì phải phân biệt thứ tự a*b chưa chắc j = b*a.
bởi dậy phải xét đúng thứ tự
để ma trận a*b được thì a.n == b.m dậy thôi.
còn trong điều kiện của bạn bạn thử phủ định lại xem đúng ko nha
~(m!=k.m || n!=k.n) <=> m=k.m && n==k.n

boss14420
20-12-2011, 11:04 PM
Cái mà bạn gọi là "điều kiện 1" thực ra cũng chỉ là trường hợp đặc biệt của "điều kiện 2", vậy nên chỉ cần kiểm tra "điều kiện 2" là đủ:
if(m != b.n)
...

code_c
20-12-2011, 11:24 PM
nhân ma trận thì phải phân biệt thứ tự a*b chưa chắc j = b*a.
bởi dậy phải xét đúng thứ tự
để ma trận a*b được thì a.n == b.m dậy thôi.
còn trong điều kiện của bạn bạn thử phủ định lại xem đúng ko nha
~(m!=k.m || n!=k.n) <=> m=k.m && n==k.n
bạn giải thích khó hiểu quá mình thử làm như bạn thì kết quả ko khả quan hơn mà ngược lại lúc này nhap 2 ma tran cùng cấp thì nó ẽit luôn còn nhập 2 ma trận khác cấp nhưng vẫn thoả điều kiện nhân thì nó ra số quá lớn, nói chung là sai.
http://i1095.photobucket.com/albums/i472/OLAKEN91/Untitled.jpg

Cái mà bạn gọi là "điều kiện 1" thực ra cũng chỉ là trường hợp đặc biệt của "điều kiện 2", vậy nên chỉ cần kiểm tra "điều kiện 2" là đủ:
if(m != b.n)mình hiểu ý bạn, đã thử theo cách này nhưng sai bạn à.

clchicken
23-12-2011, 12:15 PM
mình hiểu ý bạn, đã thử theo cách này nhưng sai bạn à.
Sai là sai thế nào. Kiểm tra 2 ma trận nhân dc ko thì xem số cột của này có = số hàng của kia ko.
Chứ bạn xem lại cái điều kiện kiểm tra của bạn ấy. Làm gì có chuyện cột này = cột kia, hàng này = hàng kia ? . Cho bạn cái 2 ma trận [2x3] thêm cái [2x3] nữa xem bạn nhân = cách nào ??

"ĐÃ HIỂU Ý BẠN". Mà cái Ý ĐÓ LÀ ĐÚNG nhưng chương trình bạn vẫn sai có nghĩa là PHẢI ĐI TÌM CHỖ KHÁC DẪN ĐẾN SAI, chứ ko phải là BIẾN CÁI ĐÚNG ĐẤY THÀNH CÁI KHÁC BẠN TỰ NGHĨ RA để chương trình trở thành ... blah blah

1 and 1= 1 chứ
Đang ở trạng thái 0 and 1 = 0
Thì phải biến sao để về 1 and 1 cho nó = 1 .
Chứ sao lại chế "0 and 0 để bằng 1 " Làm gì có phép toán này???


Bạn biết vì sao sai ko ??
Ma trận kết quả x đâu có dc khởi tạo vùng nhớ ?

code_c
25-12-2011, 08:12 AM
Sai là sai thế nào. Kiểm tra 2 ma trận nhân dc ko thì xem số cột của này có = số hàng của kia ko.
Chứ bạn xem lại cái điều kiện kiểm tra của bạn ấy. Làm gì có chuyện cột này = cột kia, hàng này = hàng kia ? . Cho bạn cái 2 ma trận [2x3] thêm cái [2x3] nữa xem bạn nhân = cách nào ?
bạn nói đúng, nhập 2 ma trận giống y nhau kiểu (2*3) *(2*3) có mà nhân bằng niềm tin :D


Bạn biết vì sao sai ko ??
Ma trận kết quả x đâu có dc khởi tạo vùng nhớ ? cái này ko đúng nè, nều thế thì nó đã sai luôn ở phép cộng hay giả sử nhân ma trận (2*2) với (2*2) rồi?

code_c
25-12-2011, 08:44 AM
Đây là code mới toanh, nhưng tại sao nhập ma trận (2*2)*(2*3) thì hỉ ra ma trận 2*2 còn
nhập ma trận (2*3) nhân (3*4) thì ra số lớn quá ?

mà sao cái đoạn này của hàm nhân khó hiểu thế ko biết mình vẽ ra giấy rồi mà vẫn ko hiểu vòng for nó chạy kiểu gì ?

x.m = n;
x.n = k.m;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
{
x.a[i][j] = 0,0;
for(int t=1;t<=x.n;t++)
x.a[i][j] += a[i][t]*k.a[i][j];
}

#include "stdio.h"
#include "conio.h"
#include "iostream"
#include "math.h"

using namespace std;

class matran
{
private:
int m,n;
int a[10][10];
public:
matran();
matran(int a,int b,int x);
~matran();
void nhapc1();//ham nhap lam cach 1
void nhapc2();//ham nhap lam cach 2
void xuat();
matran operator+(matran &k);//tru 2 ma tran lam tuong tu
matran operator*(matran &k);
friend ostream & operator << (ostream &output, matran &k);
friend istream & operator >> (istream &input, matran &k);
};

matran::matran()
{
m=n=1;
a[0][0]=1;
}

matran::matran(int m1,int n1,int x)
{
m=m1;
n=n1;
for(int i=1;i<=m1;i++)
for(int j=1;j<=n1;j++)
{
a[i][j]=x;
}
}

matran::~matran()
{
m=n=0;
}

void matran::nhapc1()
{
cout<<"Nhap so dong:";
cin>>m;
cout<<"Nhap so cot: ";
cin>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
cout<<"\nNhap phan tu hang "<<i<<" cot "<<j<<" = ";
cin>>a[i][j];
}
}

void matran::nhapc2()
{
do
{
cout<<"Nhap so hang:";
cin>>m;
cout<<"Nhap so cot:";
cin>>n;
}
while((m<=1||m>=10)&&(n<=1||n>=10));
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
cout<<"\nNhap phan tu hang "<<i<<" cot "<<j<<" = ";
cin>>a[i][j];
}
}

void matran::xuat()
{
for(int i=1;i<=m;i++)
{
cout<<"\n";
for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<"\n";
}
}
istream & operator >> (istream &input,matran &k)
{
cout<<"Nhap so hang:";
input>>k.m;
cout<<"Nhap so cot:";
input>>k.n;
for(int i=1;i<=k.m;i++)
for(int j=1;j<=k.n;j++)
{
cout<<"Phan tu hang "<<i<<" cot "<<j<<" :";
input>>k.a[i][j];
}
return input;
}

ostream & operator << (ostream &output,matran &k)
{
for(int i=1;i<=k.m;i++)
{
output<<"\n";
for(int j=1;j<=k.n;j++)
output<<k.a[i][j]<<" ";
output<<"\n";
}
return output;
}

matran matran::operator+(matran &k)
{
matran x;
if(m!=k.m||n!=k.n)
{
cout<<"Hai ma tran phai cung cap moi cong duoc!";
exit(0);
}
else
{
x.m = k.m;
x.n = k.n;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
x.a[i][j] = a[i][j]+ k.a[i][j];
}
return x;
}

matran matran::operator*(matran &k)
{
matran x;
if(n!=k.m)
{
cout<<"Hai tran phai cung cap va so hang = so cot hoac so cot ma tran nay = so hang ma tran kia:\n";
exit(0);
}
else
{
x.m = n;
x.n = k.m;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
{
x.a[i][j] = 0,0;
for(int t=1;t<=x.n;t++)
x.a[i][j] += a[i][t]*k.a[i][j];
}
}
return x;
}
void main()
{
cout<<"Ham khoi tao ma tran co doi so: ";
matran x(2,2,1);
x.xuat();

matran e,f,g;

cout<<"Phep nhan!\n";
cout<<"Nhap ma tran 1: \n";
e.nhapc1();
cout<<"Xuat ma tran 1: ";
e.xuat();

cout<<"Nhap ma tran 2: \n";
f.nhapc2();
cout<<"Xuat ma tran 2:";
f.xuat();
cout<<"Hai ma tran nhan voi nhau:";
g=e*f;
cout<<g;

getch();
}

treatmaster
25-12-2011, 09:25 AM
x.m = n;
x.n = k.m;
for(int i=1;i<=x.m;i++)
for(int j=1;j<=x.n;j++)
{
x.a[i][j] = 0,0;
for(int t=1;t<=x.n;t++)
x.a[i][j] += a[i][t]*k.a[i][j]; // cùng dòng mtrixA này nhân vs cùng dòng mtrixB
}

nhìn dòng nhân là thấy sai rõ ràng

code_c
25-12-2011, 11:00 AM
x.a[i][j] += a[i][t]*k.a[i][j];
đã fix thành x.a[i][j] += a[i][t]*k.a[t][j]; nhưng vẫn sai bạn à, search gu gồ thấy người khác cũng viết hàm nhân thế này mà sao mình chạy ko dk ta ? (8-)>

treatmaster
25-12-2011, 11:27 AM
2 mtrix A(mxn), B(nxp)
AxB = C(mxp)



for(int i=0;i<m;i++)
for(int j=0;j<p;j++)
{
C[i][j] = 0 ;
for(int k=0;k<n;k++)
{
C[i][j] += A[i][k]*B[k][i]
}
}

clchicken
25-12-2011, 01:19 PM
cái này ko đúng nè, nều thế thì nó đã sai luôn ở phép cộng hay giả sử nhân ma trận (2*2) với (2*2) rồi?
À xin lỗi. Bạn đã cấp phát tĩnh ở thuộc tính rồi :)


x.m = n;
x.n = k.m;
Sai chỗ này nè
x.m=m ; x.n=k.n mới đúng chứ. (m x n) * (k.m x k.n) = (m x k.n) chứ .

Gán sai kích thước nên vòng lặp tính bậy là phải rồi bạn ơi :D

lo3e_you
25-12-2011, 10:21 PM
xem pài nè nhé.

#include <iostream>
#include <math.h>
#include <conio.h>
#include <string.h>
using namespace std;
class sv
{
private:

float DT,DL,DH,trungbinh;
public:
char hoten[25];
void nhap(){
cout<<"nhap ho ten"<<endl;
cin.ignore();
cin.get(hoten,25);
cout<<"nhap diem T,L,H"<<endl;
cin>>DT>>DL>>DH;
}
float DTB() {
trungbinh= (DL+DT+DH)/3;
return trungbinh;
}
void in(){
cout<<"ho ten :"<<hoten<<endl;
cout<<"diem toan :"<<DT<<endl;
cout<<"diem li :"<<DL<<endl;
cout<<"diem hoa :"<<DH<<endl;
cout<<"diem trung binh"<<DTB()<<endl;
}

};
main() {
sv sinhvien[100],bp;
int i,n,j;
cout<<"nhap vao so sinh vien"<<endl;
cin>>n;
cout<<"nhap danh sach sinh vien\n";
for(i=1;i<=n;i++)
{
cout<<i<<":\n";
sinhvien[i].nhap();
}
cout<<"in danh sach sinh vien da nhap\n";
for(i=1;i<=n;i++)
{
cout<<i<<":\n";
sinhvien[i].in();
}
for(i=1;i<=n-1;i++)
for(j=i+1;i<=n;j++){
if(sinhvien[i].DTB()>sinhvien[j].DTB())
{ bp=sinhvien[i];
sinhvien[i]=sinhvien[j];
sinhvien[j]=bp;
}
cout<<"sinh vien duoc sap xep theo diem TB"<<endl;
for(i=1;i<=n;i++)
{
sinhvien[i].in();
}
cout<<"sinh vien co diem tb lon nhat la\n";
sinhvien[n].in();
}
for(i=1;i<=n-1;i++)
for(j=i+1;i<=n;j++)
{
if(strcmp(sinhvien[i].hoten,sinhvien[j].hoten)>0)
{bp=sinhvien[i];
sinhvien[i]=sinhvien[j];
sinhvien[j]=bp;}
cout<<"sinh vien duoc sap xep theo ho ten"<<endl;
for(i=1;i<=n;i++)
sinhvien[i].in();
}
system("pause");
}

lo3e_you
25-12-2011, 10:22 PM
xem pài này nhé.

#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
class matran {
private:
unsigned sd,sc;
float**a;
public:
matran(int n=2,int m=2);
matran(unsigned sd,unsigned sc);
void matran:: operator=(const matran b);
void nhap();
void in();
~matran();
matran(const matran&);
int doixung();
int donvi();
matran operator+(const matran);
matran operator-(const matran);
matran operator*(const matran);
};
matran::matran(int n,int m){
sd=n;sc=m;
a=new float*[sd];
for(int i=0;i<sd;i++)
a[i]=new float[sc];
}
matran::matran(unsigned n,unsigned m){
sd=n;sc=m;
a=new float*[sd];
for(int i=0;i<sd;i++)
a[i]=new float[sc];
}
void matran::operator=(const matran b) {
sd=b.sd;sc=b.sc;
int i,j;
for(i=0;i<sd;i++)
for(j=0;j<sc;j++)
a[i][j]=b.a[i][j];
}
matran::~matran(){
for(int i=0;i<sd;i++)
delete [] a[i];
delete []a;
}
matran::matran(const matran&b){
sd=b.sd;
sc=b.sc;
a=new float*[b.sd];
for(int i=0;i<b.sd;i++)
a[i]=new float[b.sc];
for(int i=0;i<b.sd;i++)
for(int j=0;j<b.sc;j++)
a[i][j]=b.a[i][j];
}
void matran::nhap() {
int i,j;
cout<<"\nnhap so dong,cot";
cin>>sd>>sc;
a=new float*[sd];
for(i=0;i<sd;i++)
a[i]=new float[sc];
cout<<"\nnhap cac phan tu"<<endl;
for(i=0;i<sd;i++)
for(j=0;j<sc;j++)
{cout<<"a["<<i<<","<<j<<"]=";
cin>>a[i][j];
}}
void matran::in(){
cout<<"\ncac phan tu la";
for(int i=0;i<sd;i++)
{cout<<endl;
for(int j=0;j<sc;j++)
cout<<a[i][j]<<" ";
}}
matran matran::operator+(const matran b) {
int i,j;
if((this->sd!=b.sd)&&(this->sc!=b.sc)) cout<<"khong cong duoc";
else {
sd=b.sd;sc=b.sc;
matran kq(sd,sc);
for(i=0;i<sd;i++)
for(j=0;j<sc;j++)
kq.a[i][j]=a[i][j]+b.a[i][j];
return kq;
}}
matran matran::operator-(const matran b) {
int i,j;
if((sd!=b.sd)&&(sc!=b.sc)) cout<<"khong tru duoc";
else {
matran kq(sd,sc);
sd=b.sd;sc=b.sc;
for(i=0;i<sd;i++)
for(j=0;j<sc;j++)
kq.a[i][j]=a[i][j]-b.a[i][j];
return kq;
}}
matran matran::operator*(const matran b) {
int i,j;
if(this->sc!=b.sd) cout<<"khong nhan duoc";
else { matran kq(sd,b.sc);
kq.sd=sd;
kq.sc=b.sc;
for(i=0;i<sd;i++)
for(j=0;j<b.sc;j++)
{kq.a[i][j]=0;
for(int k=0;k<sc;k++)
kq.a[i][j]+=a[i][k]*b.a[k][j];
}
return kq;
}}
int matran::donvi(){
if(sd!=sc) return 0;
else {
for(int i=0;i<sd;i++)
for(int j=0;j<sd;j++)
if(a[i][i]!=1) return 0;
for(int i=0;i<sd;i++)
for(int j=i+1;j<sd;j++)
if((a[i][j]!=0)&&(a[j][i]!=0)) return 0;
return 1;
}}
int matran::doixung() {
if(sd!=sc) return 0;
for(int i=0;i<sd;i++)
for(int j=i+1;j<sd;j++)
if(a[i][j]!=a[j][i]) return 0;
return 1;
}
main() {
matran a,b,c,kqc,kqn;
cout<<"nhap a ";a.nhap();a.in();
cout<<"nhap b ";b.nhap();b.in();
cout<<"tong a va b "; (a+b).in();
cout<<"tich a va b "; (a*b).in();
if((a+b).donvi()) cout<<"\nla ma tran don vi";
else cout<<"\nkhong la ma tran don vi";
if((a+b).doixung()) cout<<"\nla ma tran doi xung";
else cout<<"\nkhong doi xung";
system("pause");
return 0;
}