在c中编写稀疏矩阵的代码 [英] write code for sparse matrix in c

查看:62
本文介绍了在c中编写稀疏矩阵的代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里我在编译过程中给出了一些代码我遇到了4个编译错误....请你解释一下这个问题???





 #include< stdio.h> 
#include< conio.h>
void main()
{
int r,c, I,J;
int x [ 100 ] [ 100 < /跨度>];
void 稀疏( int x [] [], int r, int c);
printf( 输入行数:);
scanf( %d,& r);
printf( 输入列数:);
scanf( %d,& c);

for (i = 0 ; i< r; i ++)
{
for (j = 0 ; j< c; j ++)
{
scanf( %d,& x [i] [j] );
}
}
稀疏(x,r,c);
getch();
}
void 稀疏( int x [] [], int r, int c)
{
int sp [ 200 ] [ 200 ];
int m,n,k = 1 ;
for (m = 0 ; m< r; m ++)
{
for (n = 0 ; n< c; n ++)
{
if (x [m] [n]!= 0
{
sp [k] [ 0 ] = m + 1;
sp [k] [ 1 ] = n + 1;
sp [k] [ 2 ] = x [m] [n];
k ++;
}
}
}
sp [ 0 ] [ 0 < /跨度>] = R;
sp [ 0 ] [ 1 ] = c;
sp [ 0 ] [ 2 ] = k-1;

printf( 稀疏矩阵为:\ n);
for (m = 0 ; m< k; m ++)
{
for (n = 0 ; n< 3; n ++)
{
printf( %d \ t,sp [m] [n]);
}
}
}

解决方案

将参数定义为 int ** x 而不是 int x [] []





如上面的解决方案#2所示,上述情况还不够。

对于(多维)数组,您必须至少传递除第一个维度以外的所有维度(您可以当然也传递第一个)。或者你明确地进行元素位置计算。



C / C ++需要知道所有(但第一个)维度来计算具体元素。原因:多维数组存储在一块内存中,通过计算该内存块中的相应位置来访问每个元素: pos = ...((((idx0)* dim1 + idx1)* dim2 + idx2)* ... + ...)...



在你的情况下

- idx0:0 ... 99

- dim1:100

- idx1:0 ... 99

(*没有*更高的维度和内容2,3,4 ......)



假设您在函数调用中传递了正确的参数,以下结果相同:



隐式 explicit

  void 稀疏( int  x [] [   100   ], int 行, int  cols)
{
for int m = 0 ; m<行; ++ m)
{
for int n = 0 ; n< cols; ++ n)
{
...

int v = x [m] [n];
...
}
}
}

  void 稀疏( int  ** x, int 行, int  cols)
{
for int m = 0 ; m< rows; ++ m)
{
for int n = 0 ; n< cols; ++ n)
{
...
int * first_elem = * x;
int v = first_elem [ m * cols + n ];
...
}
}
}





[/编辑]



干杯

Andi


< blockquote>如果不知道列的大小,编译器就不能为expresion x [m] [n]生成代码。



表达式x [m] [n]实际上只是语法糖:



 *(x + m * colsize + n)





您需要将功能声明更改为:



无效稀疏(int ** pArr,int r,int c)



并将所有对x [m] [n]的引用替换为:



 *(pArr + m * c + n)


我想我可以提供帮助,但请记住,无论何时你正确的程序,你有2个基本的受众,计算机和那些将尝试理解你的代码并在将来维护它的人。在这方面,最大的问题是你需要缩进你的代码,以便人们能够理解你的意思。



从计算机的角度来看,最大的问题是当你把它传递到例程''sparse()''时,计算机不知道数组''x'有多大。



让我们来探索计算机如何处理数组的内存。在计算机中,内存是线性的,这意味着内存实际上只是一个长数字列表,每个数字在列表中都有一个名为地址的位置。为了表示二维数组,编译器将第一行放在内存的第一部分中,将第二行放在下一部分中等等。这意味着,例如,一个数组是2乘3,或者使用代码

 myArray [ 2 ] [ 3 ] 

将有两行,每行3个值。假设数组的第一行中的值为1,2和3,第二行的值为4,5和6。在这种情况下,计算机内存将如下所示:1,2,3,4,5,6。



当我们写一个表达式,如< pre lang =c ++> int sample = myArray [ 1 ] [ 2 ];

编译器必须通过使用其对数组大小的了解,从坐标计算出正确的内存地址。在这种情况下,编译器知道每行是3长,因此被访问的存储器位置是1 * 3 + 2,或者是阵列内存中的第5个存储器位置。 (别忘了数组是从零开始的,这意味着第一行是行号零。)因此,在这个例子中,''sample''将被设置为5.



现在我们从代码的计算机角度来看核心问题:因为你没有告诉编译器你的定义''稀疏()''数组有多大,编译器无法知道计算数组中每个元素的地址应该做什么数学。



一个简单的修复,不推荐,是告诉编译器在两个位置将数组传递给''sparse()''时有多大。这不推荐使用,因为在将数组传递给函数时会复制值,这在这种情况下是浪费时间。在一些系统中还有一个限制,可以将多少数据传递到例程中。



如果这只是一个快速测试程序,并且不需要是保持在未来,最简单的解决方案是将数组''''放在''main()''行之外,然后将其传递到''sparse()''例程中。



您的代码还有其他问题,例如,您使用200行200列定义的sp [] []似乎永远不会有超过前3列使用。从可读性的角度来看,我个人的规则是永远不要使用单字母变量,因为它们很难理解它们的含义应该是什么。



无论如何,我希望我的ramblings是指导性的,尽管我还有很多东西要继续调试。下面是你的代码版本,为了便于阅读而缩进,'x''全局化,所以''稀疏()''可以使用它。

  #include   <   stdio.h  >  
#include < conio.h >

int x [ 100 ] [ 100 ];

void main()
{
int R,C,I,J;
void 稀疏( int r, int c);
printf( 输入行数:);
scanf( %d,& r);
printf( 输入列数:);
scanf( %d,& c);

for (i = 0 ; i< r; i ++)>
{
for (j = 0 ; j< c; j ++)> ;
{
scanf( %d,& x [i] [J]);
}
}
稀疏(r,c);
getch();
}
void 稀疏( int r, int c)
{
int sp [ 200 ] [ 200 ];
int m,n,k = 1 ;
for (m = 0 ; m< r; m ++)>
{
for (n = 0 ; n< c; n ++)> ;
{
if (x [m] [n]!= 0
{
sp [k] [ 0 ] = m + 1;
sp [k] [ 1 ] = n + 1;
sp [k] [ 2 ] = x [m] [n];
k ++;
}
}
}
sp [ 0 ] [ 0 < /跨度>] = R;
sp [ 0 ] [ 1 ] = c;
sp [ 0 ] [ 2 ] = k- 1 ;

printf( 稀疏矩阵为:\ n);
for (m = 0 ; m< k; m ++)>
{
for (n = 0 ; n< 3; n ++)
{
printf( %d \ t,sp [m] [N]);
}
}
}


here i m giving some code bt during compilation i faced 4 compilation errors ....will u plzz explain me ???


#include <stdio.h>
#include <conio.h>
void main()
{
int r,c,i,j;
int x[100][100];
void sparse(int x[][],int r,int c);
printf("Enter the no of rows :");
scanf("%d",&r);
printf("Enter the no of columns :");
scanf("%d",&c);

for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&x[i][j]);
}
}
sparse(x,r,c);
getch();
}
void sparse(int x[][],int r,int c)
{
int sp[200][200];
int m,n,k=1;
for(m=0;m<r;m++)
{
for(n=0;n<c;n++)
{
if(x[m][n]!=0)
{
sp[k][0]=m+1;
sp[k][1]=n+1;
sp[k][2]=x[m][n];
k++;
}
}
}
sp[0][0]=r;
sp[0][1]=c;
sp[0][2]=k-1;

printf("The sparse matrix is :\n");
for(m=0;m<k;m++)
{
for(n=0;n<3;n++)
{
printf("%d\t",sp[m][n]);
}
}
}

解决方案

Define the arguments as int**x instead of int x[][].

[EDIT]
The above is not sufficient as shown in solution #2.
With (multi-dimensional) arrays, you must pass at least all but the first dimensions (you may also pass the first, of course). Or you do the element position calcualtion explicitly.

C/C++ require to know all (but the first) dimension to calculate the concrete element. Reason: multi-dimensional arrays are stored in one chunk of memory, where each element is accessed by calculating the respective position within that block of memory: pos = ...((((idx0) * dim1 + idx1) * dim2 + idx2) * ... + ...) ....

In your case
- idx0: 0...99
- dim1: 100
- idx1: 0...99
(*no* higher dimension and idices 2,3,4...)

The following have identical results, assuming you pass the correct arguments in the function call:

implicitexplicit

void sparse(int x[][100], int rows, int cols)
{
   for(int m = 0; m < rows; ++m)
   {
       for(int n = 0; n < cols; ++n)
       { 
           ...

           int v = x[m][n];
           ...
       }
   }
}

void sparse(int **x, int rows, int cols)
{
   for(int m = 0; m < rows; ++m)
   {
       for(int n = 0; n < cols; ++n)
       { 
           ...
           int *first_elem = *x;
           int v = first_elem[m*cols+n];
           ...
       }
   }
}



[/EDIT]

Cheers
Andi


The compiler can''t generate code for the expresion x[m][n] if it doesn''t know what size the columns are.

The expression x[m][n] is really just syntactic sugar for:

*( x + m * colsize + n )



You need to change your function declaration to:

void sparse( int **pArr, int r, int c)

and replace all references to x[m][n] with:

*(pArr + m * c + n)


I think I can help, but please keep in mind that whenever you right programs you have 2 basic audiences, the computer and people who will try to understand your code and maintain it in the future. In this regard the biggest problem is that you need to indent your code so people can understand what you intended it to mean.

From the computer''s perspective, the biggest problem is that the computer does not know how big the array ''x'' is when you pass it into the routine ''sparse()''.

Let''s explore how the computer handles memory for an array. In a computer memory is linear, meaning that memory is really just one long list of numbers, with each number having a location in the list called its address. In order to represent a two dimensional array, the compiler puts the first row in the first part of memory, the second row in the next part, etc.. What this means is, for example, an array which is 2 by 3, or to use code

myArray[2][3]

will have two rows of 3 values each. Let''s say the array''s first row has the values 1, 2, and 3 in it and the second row has the values 4, 5, and 6 in it. In this case, the memory within the computer will look like this: 1, 2, 3, 4, 5, 6.

When we write an expression such as

int sample = myArray[1][2];

the compiler must compute the correct address of memory from the coordinates given by using its knowledge of the size of the array. In this case, the compiler knows each row is 3 long, so the memory location being accessed is 1 * 3 + 2, or the 5th memory location within the memory for the array. (Don''t forget that arrays are zero-based, meaning that the first row is row number zero.) Thus, in this example, ''sample'' will be set to 5.

Now we come to the core problem, from the computer''s perspective, in your code: because you have not told the compiler in your definition of ''sparse()'' how big the array is, the compiler cannot know what math it should do to compute the addresses of each element of the array.

One simple fix, which is not recommended, is to tell the compiler how big the array is when passing it into ''sparse()'', in both locations. This not recommended because when passing arrays into a function the values are copied, which in this case is a waste of time. There is also a limit in some systems on how much data can be passed into a routine.

If this is just a quick test program, and will not need to be maintained in the future, the simplest solution is to make the array ''x'' a global by putting it outside the ''main()'' line, then not passing it into the ''sparse()'' routine at all.

There are other issues with your code, for example, it appears that sp[][], which you define with 200 rows of 200 columns, will never have more than the first 3 column used. And from a readability standpoint, my personal rule is to never use single letter variables because they are hard to understand what their meaning is supposed to be.

At any rate, I hope my ramblings are instructional, though I have left much up to you to continue debugging. Below is a version of your code, indented for readability, with ''x'' made global so ''sparse()'' can use it.

#include <stdio.h>
#include <conio.h>

int x[100][100];

void main()
{
	int r,c,i,j;
	void sparse(int r,int c);
	printf("Enter the no of rows :");
	scanf("%d",&r);
	printf("Enter the no of columns :");
	scanf("%d",&c);
 
	for(i=0;i<r;i++)>
	{
		for(j=0;j<c;j++)>
		{
			scanf("%d",&x[i][j]);
		}
	}
	sparse(r,c);
	getch();
}
void sparse(int r,int c)
{
	int sp[200][200];
	int m,n,k=1;
	for(m=0;m<r;m++)>
	{
		for(n=0;n<c;n++)>
		{
			if(x[m][n]!=0)
			{
				sp[k][0]=m+1;
				sp[k][1]=n+1;
				sp[k][2]=x[m][n];
				k++;
			}
		}
	}
	sp[0][0]=r;
	sp[0][1]=c;
	sp[0][2]=k-1;
	 
	printf("The sparse matrix is :\n");
	for(m=0;m<k;m++)>
	{
		for(n=0;n<3;n++)
		{
			printf("%d\t",sp[m][n]);
		}
	}
}


这篇关于在c中编写稀疏矩阵的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆