희소행렬에 관해 질문좀 하겠습니다.
갤투
#includestdio.h
#includestdlib.h
#define IS_EMPTY(ptr) (!(ptr)) //공백리스트인지를 검사
#define IS_FULL(ptr) (!(ptr)) //가용 메모리를 전부 사용했는지 검사
#define COMPARE(x,y) ((xy)??1:(x==y)?0:1) //스위치 문에서 쓰일 비교함수
#define MAX_SIZE 50 //최대 행렬 크기
typedef enum {head, entry} tagfield; //각 필드들의 타입 정의
typedef struct matrix_node *matrix_pointer;
struct entry_node{
int row;
int col;
int value;
};
struct matrix_node{
matrix_pointer down;
matrix_pointer right;
tagfield tag;
union {
matrix_pointer next;
struct entry_node entry; //교재 수정
} u; //상이한 두 종류의 노드가 필요하므로 union사용하여 구조생성
};
matrix_pointer hdnode[MAX_SIZE]; //보조 배열 hdnode 사용
matrix_pointer mread(void); //희소 행렬에서의 읽기 함수 선언
matrix_pointer new_node(void); //희소 행렬에서 새 행렬 노드를 얻는 함수 선언
void mwrite (matrix_pointer); //희소 행렬의 출력 함수 선언
void merase(matrix_pointer *); //희소 행렬의 삭제.. 함수 선언
matrix_pointer mread(void)
{
//행렬을 읽어 연결 표현으로 구성한다. 전역 보조배열 hdnode를 사용한다.
int num_rows, num_cols, num_terms,num_heads, i;
//num_terms 0이 아닌 항의 수
int row, col, value, current_row;
matrix_pointer temp, last, node; //링크드 리스트의 temp last node초기화
printf(Enter the number of row, columns and number of nonzero terms: );
scanf(%d %d %d, &num_rows, &num_cols, &num_terms);
//각행렬의 수와 값의 수를 입력받음
num_heads = (num_cols num_rows) ? num_cols : num_rows;
//입력한 행과 열이 같으면 num_cols, 아니면 mum_rows
//헤드 노드 리스트에 대한 헤드 노드를 생성한다.
node = new_node();
node - tag = entry; //node의 tag는 entry를 가리킴
node - u.entry.row = num_rows;//node의 u.entry.row는 num_rows를 가리킨//다.
node - u.entry.col = num_cols; //node의 u.entry.col는 num_cols를 가리킨다.
if(!num_heads) //만약 헤드노드가 아니면
node - right = node; //node의 right가 node를 가리킨다.
else { //헤드 노드들을 초기화한다.
for (i=0; inum_heads; i++){
temp=new_node();
hdnode[i]=temp;
hdnode[i]-tag=head;
hdnode[i]-right=temp;
hdnode[i]-u.next=temp;
}
current_row=0;
last=hdnode[0]; //현재 행의 마지막 노드
//행렬의 값에 해당하는 행과 열의 값을 입력받는다.
for (i=0; inum_terms; i++){ // 노드 구성
printf(Enter row, column and value: ); //각 행렬의 값을 입력
//num_terms일때 까지 반복
//정렬되는 순서에 입각해.
scanf(%d %d %d, &row,&col,&value);
if (row current_row) {
//현재 행을 종료함,row가 1이면 줄 바꾸기
last - right = hdnode[current_row];
current_row = row;
last = hdnode[row]; //last는 마지막 col값을 가리키며..
}
temp = new_node();
temp - tag = entry;
temp - u.entry.row = row;
temp - u.entry.col = col;
temp - u.entry.value = value;
last - right = temp; //행 리스트에 연결
last=temp; //last에 값 넣기
//열 리스트에 연결
hdnode[col] - u.next - down = temp;
hdnode[col] - u.next = temp;
}
//마지막 행을 종료함
last - right = hdnode[current_row];
//모든 열 리스트를 종료함
for (i=0; inum_cols; i++)
hdnode[i] - u.next -down = hdnode[i]; //down(열)을 모두 연결
//모든 헤드 노드들을 연결함
for (i=0; inum_heads-1; i++)
hdnode[i] - u.next = hdnode[i+1];
hdnode[num_heads-1] - u.next = node; //u.next를 모두 연결
node - right = hdnode[0];
}
return node; //node값을 되돌린다.
}
matrix_pointer new_node(void) // 새 행렬 노드를 얻는 함수
{
matrix_pointer temp;
temp=(matrix_pointer) malloc(sizeof(struct matrix_node));
//matrix_node 만큼의 필요한 기억장소를 요구
if(IS_FULL(temp)) { // 가용 메모리를 전부 사용했는지 검사
fprintf(stderr, The memory is full\n);
exit(1);
}
return temp;
}
void mwrite (matrix_pointer node) //희소 행렬의 출력 함수
{
//행렬을 행 우선으로 출력한다.
int i;
matrix_pointer temp, head=node-right;
//행렬의 차원
printf(\n num_rows=%d, num_cols=%d\n, node-u.entry.row, node-u.entry.col);
printf(\nThe matrix by row, column, and value :);
for (i=0; inode-u.entry.row; i++) {
//각 행에 있는 엔트리들을 출력
fornbsp;for(temp=head-right;temp!=head;temp=temp-right)
printf(%d,%2d,%2d\n\n\n, temp-u.entry.row, temp-u.entry.col, temp-u.entry.value);
head=head-u.next; //다음 행을 가리킨다
}
}
void merase(matrix_pointer *node)//희소행렬의 모든 노드들을시스템 메모리로 반환한다.
{
//행렬을 삭제하고, 노드들을 히프로 반환한다.
matrix_pointer x,y,head=(*node)-right;
int i;
//엔트리 노드와 헤드 노드들을 행 우선으로 반환한다.
for(i=0; i(*node)-u.entry.row;i++) {
y=head-right;
while(y!=head) {
x=y; y=y-right; free(x);
}
x=head; head=head-u.next; free(x);
}
//나머지 헤드 노드들을 반환한다.
y=head;
while(y!=*node) {
x=y; y=y-u.next; free(x);
}
free(*node); *node=NULL; //free를 사용하여 한번에 한 노드씩 반환
printf(merased!\n);
}
matrix_pointer madd(matrix_pointer node1,matrix_pointer node2)// 두 행렬을 더하는 함수
{
int num_heads,i,row,col,value,current_row;
matrix_pointer temp1,temp2,temp,last,node,head1=node1-right,head2=node2-right;
//노드1의 행이 열보다 크면 노드의 행으로 반환...
num_heads=(node1-u.entry.rownode1-u.entry.col)?
node1-u.entry.row:node1-u.entry.col;
// 헤드 노드 리스트에 대한 헤드 노드를 생성한다.
node=new_node();
node-tag=entry;
node-u.entry.row=node1-u.entry.row;
node-u.entry.col=node1-u.entry.col;
for(i=0;inum_heads;i++) { //헤드노드 초기화
temp=new_node();
hdnode[i]=temp; //hdnode[i]는 열 i와 행 i에 대한 헤드노드를 가리키는 //포인터로써
hdnode[i]-tag=head; // 입력행렬을 구성하는 동안 임의의 열을 효과적 //으로 접근한다.
hdnode[i]-right=temp; //hdnode의 right는 temp를 가리킴
hdnode[i]-u.next=temp;
}
current_row=0;
last=hdnode[0]; // 현재 행의 마지막 노드
for(i=0;inode-u.entry.row;i++) { // 노드 구성
temp1=head1-right;
temp2=head2-right;
while (temp1-u.entry.row==current_row || temp2-u.entry.row==current_row) {
switch(COMPARE(temp1-u.entry.row,temp2-u.entry.row)); {//temp1과 temp2를 비교
case 1 ://temp1의 엔트리 행이 temp2의 엔트리 행보다 //작을경우
col=temp1-u.entry.col; //temp1의 엔트리 열의 값에 //col를 집어넣는다.
row=temp1-u.entry.row;//temp1의 엔트리 행의 값에 //row를 집어넣는다.
value=temp1-u.entry.value; //temp1의 엔트리 값을 //가지는 값의 갯수에 value를 집어넣는다.
temp1=temp1-right;//temp1의 오른쪽을 temp1과 연결
break;
case 0 : //temp1의 행이 temp2의행 과 같을경우
switch (COMPARE(temp1-u.entry.col,temp2-u.entry.col));
{
case -1 : //temp1의 엔트리 col값이 temp2그것보다 작을경우
col=temp1-u.entry.col;
row=temp1-u.entry.row;
value=temp1-u.entry.value;
temp1=temp1-right;
break;
case 0 : //temp1의 col이 temp2의 col와 같을경우
col=temp1-u.entry.col;
row=temp1-u.entry.row; value=temp1-u.entry.value+temp2-u.entry.value;
temp1=temp1-right;
temp2=temp2-right;
break;
case 1 : //temp1의 col이 temp2의 col보다 클경우
col=temp2-u.entry.col;
row=temp2-u.entry.row;
value=temp2-u.entry.value;
temp2=temp2-right;
break;
}
break;
case 1 : //temp1의 row값이 temp2의 row값보다 클경우
col=temp2-u.entry.col;
row=temp2-u.entry.row;
value=temp2-u.entry.value;
temp2=temp2-right;
break;
}
temp=new_node();
temp-tag=entry;
temp-u.entry.row=row;
temp-u.entry.col=col;
temp-u.entry.value=value;
last-right=temp;
last=temp;
hdnode[col]-u.next-down=temp;
hdnode[col]-u.next=temp;
}
head1=head1-u.next; //다음 노드를 가리킨다.
head2=head2-u.next;
last-right=hdnode[current_row]; //마지막 행을 종료한다.
current_row++;
last=hdnode[current_row];
}
for(i=0;inode-u.entry.col;i++)
hdnode[i]-u.next-down=hdnode[i];
for(i=0;inum_heads-1;i++) //모든 헤드 노드들을 연결한다
hdnode[i]-u.next=hdnode[i+1];
hdnode[num_heads-1]-u.next=node;
node-right=hdnode[0];
return node;
}
matrix_pointer mmult(matrix_pointer node1,matrix_pointer node2) // 두 행렬을 곱한다.
{
int num_heads,i,row,col,value,current_row;
matrix_pointer temp1,temp2,temp,last,node,head1=node1-right,head2=node2-right;
num_heads=(node1-u.entry.rownode1-u.entry.col)?
node1-u.entry.row:node1-u.entry.col;
///헤드 노드 리스트에 대한 헤드 노드를 생성한다.
node=new_node();
node-tag=entry;
node-u.entry.row=node1-u.entry.row; //u.entry.row를 가리킴
node-u.entry.col=node1-u.entry.col;
for(i=0;inum_heads;i++) { //헤드 노드 초기화
temp=new_node();
hdnode[i]=temp;
hdnode[i]-tag=head;
hdnode[i]-right=temp;
hdnode[i]-u.next=temp;
}
current_row=0;
last=hdnode[0]; //현재 행의 마지막 노드
while(head1!=node1) {
while(head2!=node2) {
temp1=head1-right;
temp2=head2-right;
value=0;
row=temp1-u.entry.row;
col=temp2-u.entry.row;
while(temp1!=head1 && temp2!=head2) {
switch (COMPARE(temp1-u.entry.col,temp2-u.entry.col)); {
case -1 : //temp1의 col값이 temp의 col값보다 작은경우
temp1=temp1-right;
break;
case 0 : //temp1의 col이 같을경우
value += temp1-u.entry.value*temp2-u.entry.value;
temp1 = temp1-right;
temp2 = temp2-right;
break;
case 1 ://temp1이 클경우
temp2 = temp2-right;
break;
}
}
if(value) {
temp=new_node();
temp-tag=entry;
temp-u.entry.row=row;
temp-u.entry.col=col;
temp-u.entry.value=value;
last-right=temp;//행 리스트에 연결
last=temp;
// 열 리스트에 연결
hdnode[col]-u.next-down=temp;
hdnode[col]-u.next=temp;
}
head2=head2-u.next;
}
head1=head1-u.next;
head2=node2-right;
// 마지막 행을 종료함
last-right=hdnode[current_row];
current_row++;
last=hdnode[current_rurrent_row];
}
for(i=0;inode-u.entry.col;i++)
hdnode[i]-u.next-down=hdnode[i]; //down 모두 연결
// 모든 헤드 노드들을 연결함
for(i=0;inum_heads-1;i++)
hdnode[i]-u.next=hdnode[i+1];
hdnode[num_heads-1]-u.next=node;
node-right=hdnode[0];
return node;
}
matrix_pointer mtranspose(matrix_pointer node1)//전치행렬구하는 함수
{
int i,num_heads,current_row;
matrix_pointer last,temp1,temp,node,head1=node1-right;
//헤드 노드의 node1이 행이 열보다 클 경우 노드1은 행의 헤드노드 생성
num_heads=(node1-u.entry.rownode1-u.entry.col)?
node1-u.entry.row:node1-u.entry.col;
node=new_node();
node-tag=entry;
node-u.entry.row=node1-u.entry.row;
node-u.entry.col=node1-u.entry.col;
for(i=0;inum_heads;i++) { //헤드 노드 초기화
temp=new_node();
hdnode[i]=temp;
hdnode[i]-tag=head;
hdnode[i]-right=temp;
hdnode[i]-u.next=temp;
}
current_row=0;
last=hdnode[0]; //현재 행의 마지막 노드
for(i=0;inode-u.entry.row;i++) { // 노드 구성
for(temp1=head1-down ; temp1!=head1 ; temp1=temp1-down) {
temp=new_node();
temp-tag=entry;
temp-u.entry.row=temp1-u.entry.col;
temp-u.entry.col=temp1-u.entry.row;
temp-u.entry.value=temp1-u.entry.value;
last-right=temp; // 행 리스트에 연결
last=temp;
//열 리스트에 연결
hdnode[temp1-u.entry.row]-u.next-down=temp;
hdnode[temp1-u.entry.row]-u.next=temp;
}
head1=head1-u.next;
last-right=hdnode[current_row];
current_row++;
last=hdnode[current_row];
}
for(i=0;inode-u.entry.col;i++)
hdnode[i]-u.next-down=hdnode[i]; //down 모두 연결
// 모든 헤드 노드들을 연결함
for(i=0;inum_heads-1;i++)
hdnode[i]-u.next=hdnode[i+1];
hdnode[num_heads-1]-u.next=node;
node-right=hdnode[0];
return node;
}
void main()
{
int chioce=0; //chioce값 초기화
matrix_pointer a = mread(); //행렬 읽어드리기
matrix_pointer b = mread(); //희소행렬을 읽기
matrix_pointer add= madd(a,b); //add=x+y
matrix_pointer mult= mmult(a,b); //mult=x*y
matrix_pointer trans= mtranspose(a); //전치행렬
//while 문을 이용하여 메뉴를 사용자가 종료하기 전까지 계속
//입력 할 수 있도록 요구 한다.
while (chioce!=7) //만약 사용자가 7을 입력하면 프로그램은 종료한다
{
printf(----MENU---- \n);
printf( 1 mread \n);
printf( 2 mwrite \n);
printf( 3 merase \n);
printf( 4 madd \n);
printf( 5 mmult \n);
printf( 6 mtranspose \n);
printf( 7 exit \n);
scanf(%d, &chioce);
//각각 선택한 번호는 다음의 스위치 문에 의해 수행된다
switch (chioce) {
case 1 : a = mread(); b = mread(); //x, y 행렬을 읽어 표현
break;
case 2 : mwrite(a); mwrite(b); //x, y행렬의 내용을 출력
break;
case 3 : merase(&a); merase(&b); //x, y을 제거
break;
//두 행렬 x, y을 더하여 결과행렬 add 출력
case 4 : add = madd(a,b); mwrite(add);
break;
//두 행렬 x, y을 곱하고 결과 행렬 mult 출력
case 5 : mult = mmult(a,b); mwrite(mult);
break;
//희소 행렬 x를 trans로 전치 시킴
case 6 : trans = mtranspose(a); mwrite(trans);
break;
default : exit(0);
break;
}
}
}
-------------------------------------------------------------------------------------------------
일단 완전 초보입니다 ㅠ 이번에 과제가 팀별 과제가 나왔는데
여러가지 소스를 좀 짜집기 한 흔적이 많이 많이...보일겁니다 ㅠ
근데 이 소스대로 컴파일 하면 자꾸 syntax error 라는 문구가 뜹니다.
고수님들 보면 풋..하고 웃으실지도 모르지만..정말 제 입장에선 똥줄이 타네요 ㅠ
이 소스를 간단히 요약하자면 연결 리스트를 사용해서 희소행렬을 산술 연산하는 내용입니다.
잃어들이고 출력하고 삭제, 덧셈, 곱셈 그리고 행렬을 생성하는것까지..
스크롤 압박이 좀 있긴 하지만..고수님들 한눈에 보이시는 잘못된 점 지적좀 부탁드립니다.
번호 | 제 목 | 글쓴이 | 날짜 |
---|---|---|---|
2676065 | 웹사이트 또는 메신저 등에서 원하는 텍스트를 검사하는방법?? (1) | 모든 | 2024-11-23 |
2676033 | 배열 기초연습중 발생하는 에러 ㅠㅜ... | Creative | 2024-11-23 |
2676005 | keybd_event 게임 제어 | 영글 | 2024-11-23 |
2675900 | 진짜기본적인질문 | 글길 | 2024-11-22 |
2675845 | 수정좀해주세요ㅠㅠㅠ | 해골 | 2024-11-21 |
2675797 | 병합 정렬 소스 코드 질문입니다. (2) | 도래솔 | 2024-11-21 |
2675771 | 큐의 활용이 정확히 어떻게 되죠?? | 해긴 | 2024-11-21 |
2675745 | 도서관리 프로그램 질문이요 | 도리도리 | 2024-11-20 |
2675717 | 2진수로 변환하는것! (3) | 동생몬 | 2024-11-20 |
2675599 | for문 짝수 출력하는 법 (5) | 널위해 | 2024-11-19 |
2675575 | Linux 게시판이 없어서.. | 첫삥 | 2024-11-19 |
2675545 | 구조체 이용할 때 함수에 자료 넘겨주는 것은 어떻게 해야 하나요? | 아연 | 2024-11-19 |
2675518 | 사각형 가로로 어떻게 반복해서 만드는지좀.. 내용 | 신당 | 2024-11-18 |
2675491 | !느낌표를 입력하는것은 어떻게합니까~~?ㅠㅠ (5) | 사지타리우스 | 2024-11-18 |
2675411 | 파일입출력으로 받아온 파일의 중복문자열을 제거한 뒤 파일출력 | 앨버트 | 2024-11-17 |
2675385 | 링크드리스트 주소록 질문드립니다. (1) | 겨루 | 2024-11-17 |
2675356 | 2진수를 10진수로 바꾸려고 하는데 막히네요.. | 풀잎 | 2024-11-17 |
2675297 | Prity 비트 발생기 | 한란 | 2024-11-16 |
2675249 | C책 좀 추천해 주세요 (2) | 딸기우유 | 2024-11-16 |
2675193 | 연습문제 17-1 질문입니다. | 한별나라 | 2024-11-15 |