记录一下本人在学习C语言时做的有价值的部分小练习,持续更新.
(1)计算1/2+1/3+...+1/n=1
// this is a code calculating s=1/2+1/3+1/4+...+1/n=1
#include<stdio.h>
int main()
{
int n,m;
double s,d;
printf("enter the number of loop:");
scanf("%d",&n);
for (s=0,m=1,d=2;m<=n;m+=1,d*=2)
{
s+=1/d;
printf("when loop =%d,d=%f,s=%f\n ",m,d,s);
}
return 0;
}
(2)计算浮点类型数的正整数次方
// this is a code calculating the positive power of a number
#include<stdio.h>
float power(float n,int p);
int main()
{
float di;
int zhi;
printf("please enter the dishiu and the zhisu(char or negtive number to quit");
while(scanf("%f%d",&di,&zhi)==2&&zhi>0)
{
printf("%f to the %dth power is %f\n",di,zhi,power(di,zhi));
printf("please enter another group of number(char or negtive number to quit)");
}
printf("quit successfully\n");
}
float power(float n,int p)
{
int i;
float pow=1;
for(i=1;i<=p;i++)
pow*=n;
return pow;
}
(3)ABA型金字塔
#include<stdio.h>
int main()
{
char CH;int CHn;
printf("please enter a character between A-Z");
CH=getchar();CHn=(int)CH-64;
// CHn确定程序有多少行,用于第一个for循环
int hang,lie;
for(hang=1,lie=1;hang<=CHn;hang++,lie=hang)
{
for( ;lie<CHn;lie++)
printf(" ");
char ch;
int a;
for(a=1,ch='A';a<=hang;ch++,a++)
printf("%c",ch);
ch=ch-2;
for(a=1;a<hang;ch--,a++)
printf("%c",ch);
printf("\n");
}
return 0;
}
(4)输入字符串,倒序输出字符串.此时要注意,字符串的最后一个单元储存‘\0',所以定义时要注意单元总个数.
#include<stdio.h>
#include<string.h>
int main()
{
char lstring [100];
int n;
printf("please enter a string:(within 100 characters):");
scanf("%s",lstring);
n=strlen(lstring);
int a;char string[n];
for(a=0;a<n;a++)
string[a]=lstring[a];
string[n]='\0';
char gnirts[n+1];
for(a=0;a<n;a++)
gnirts[n-1-a]=string[a];
gnirts[n]='\0';
printf("%s\n",string);
printf("%s",gnirts);
return 0;
}
(5) 计量输入句子中的字符数,单词数,行数.
#include<stdio.h>
#include<ctype.h>/*import function: isalpha() to judge a letter*/
int main()
{
char ch=0;
int n_ch=0,n_line=1,n_word=0,bool=0;
printf("please enter a sentence(\"|\" to stop):");
while((ch=getchar())!='|')
{
if (!isalpha(ch))
bool=0;
if (isalpha(ch))
{
n_ch++;
}
if (isalpha(ch)&&bool==0)
{
n_word++;
bool=1;
}
if (ch=='\n')
n_line++;
}
printf("%d characters,%d words,%d lines in total",n_ch,n_word,n_line);
return 0;
}
(6)求比输入数字小的所有素数.(很多内嵌循环,写得比较臃肿).
如果把第18行的break;去掉,那么代码的运行效率会低很多.
#include<stdio.h>
int main()
{
int s,s0,num,a;
printf("please enter a positive number:");
while(scanf("%d",&s)==1)
{
if(s>0)
{
printf("%d is a positive number,the sushu less than %d is :",s,s);
for(s0=1,num=0;s0<=s;s0++)
{
for(a=2;a<s0;a++)
{
if(s0%a==0)
{
num++;
break;
}
}
if(num==0)
printf("%d,",s0);
num=0;
}
}
else
printf("not a positive number\nplease entert another positive number:");
}
printf("error!");
return0;
}
(7)猜数字.第10行的判断条件可以避免在扫描字符时误将'\n'扫描到程序中.此代码判断输入'\n'时,执行第10行while循环之外的部分.
#include<stdio.h>
int main()
{
printf("please think about a number between 1-100\n");
float sml=1,big=100;
char ch;
while(big-sml>1)
{
printf("%.3f-%.3f?(print(y/n)):",sml,(big+sml)/2);
while((ch=getchar())!='\n')
{ if(ch=='y')
big=(big+sml)/2;
if(ch=='n')
sml=(big+sml)/2;
}
}
printf("%d",(int)big);
return 0;
}
(8)10进制与二进制相互转化.
十进制转换为二进制时,输入最大十进制数字a为1023,是因为十进制的1023用二进制表示为1111111111,此数为小于int型变量的最大值(2147483647)的最大二进制数值,而十进制的1024用二进制表示为10000000000,大于int型变量的最大值.所以1023为一个转折点.
当然,程序员也可以修改b的类型为long,long long,甚至可以把所有变量都修改为long long类型,可以扩大程序的转换范围.不过,到底有没有必要转换a,x的类型还需要程序员自己判断(直觉告诉我不需要).我这里就不啰嗦了.
#include<stdio.h>
#include<math.h>
int cal1(int x);
int cal2(int x);
int main()
{
int a,y;
printf("please enter 1 to convert 10 to 2 and enter 2 to convert2 to 10.(char to quit)");
while(scanf("%d",&y)==1)
{
if (y==1)
{
printf("please enter a number between 0 to 1023 :");
scanf("%d",&a);
if(a<0||a>1023)
printf("this number is out of limit!\n");
else
printf("the number you want is %d\n",cal1(a));
}
else if (y==2)
{
printf("please enter a number between 0 to 1111111111:");
scanf("%d",&a);
if(a<0||a>1111111111)
printf("this number is out of limit!\n");
else
{
int test=a;
while(test>0)
{ if(test%10>=0&&test%10<=2)
{
test-=test%10;
test/=10;
}
else
{
printf("this is not a Binary digits\n");
goto retry;
}
}
printf("the number you want is %d\n",cal2(a));
}
}
else
printf("wrong number\n");
retry:printf("enter 1 to convert 10 to 2 and 2 to convert2 to 10.(char to quit)\n");
}
printf("code completed\n");
return 0;
}
int cal1(int a)
{
int x,n=0,b=0;
while(a>=1)
{
x=a%2;
b+=x*pow(10,n);
n++;
a-=x;
a/=2;
}
return b;
}
int cal2(int a)
{
int x,b=0,n=0;
while(a>=1)
{
x=a%10;
b+=x*pow(2,n);
n++;
a-=x;
a/=10;
}
return b;
}
(8.1)使用位运算快速实现10-2进制转换
#include<stdio.h>
#include<limits.h>
int main()
{
unsigned long a;
scanf("%ld",&a);
int n = CHAR_BIT*sizeof(long);
char b[n];
b[n]='\0';
for(int i=n-1;i>=0;i--)
{
b[i]=(a&0x01)+'0';
a >>= 1;
}
puts(b);
return 0;
}
(8.2)十进制数字以二进制数字字符串形式输出
半个小时8行哈哈哈哈
void show_ten_in_char_bi(int a)
{
static int n=0;
n++;
if(a)
{
show_ten_in_char_bi(a>>1);
if((--n%4)==0)
putchar(' ');
putchar((a&0x1)+'0');
}
}
(9) 将输入数字进行排序
程序分为三部分.
第一部分(4-8行):将输入放到数组input[]中
第二部分(9-12行):根据输入数字的数量定义output[]并初始化.这里将每个值都初始化为float类型的最小值.这样初始化是为了保证每一个进入output的input值都能保留在其中,防止被其中随机的大值排出在外.
第三部分(13-28)行:将input[]中的每一个值经过比较大小后放入output[]中.
第一个for为执行每一个input[]中的值,
第二个for为将每一个执行的input[i]值与output[]中的值进行比较,决定它放在哪里.else中的for是将output中的靠后面的值读区相邻的靠前的数值,if为将input[i]的值储存在相应的output[]中.
第三个for是输出output[]的值.
#include<stdio.h>
int main()
{
printf("please enter the number to rank(within 100 numbers)(char to quit):");
float input [100];
int n=0;
while(scanf("%f",&input[n])==1)
n++;
float output[n+1];
int i;
for(i=0;i<=n;i++)
output[i]=-3.40282e+038; /* this is the minimize of float */
int ii,x;
for(i=0;i<n;i++)
{
for(ii=0;ii<n+1;ii++)
{
if(input[i]<output[ii])
continue;
else
{
for(x=n;x>ii;x--)
output[x]=output[x-1];
output[ii]=input[i];
break;
}
}
}
for(i=0;i<n;i++)
printf("%f\n",output[i]);
return 0;
}
(10)读取输入的字符串,并消去其中的某个字符,并记录此字符的数量.
子函数s_fgets的一种情况下的作用是使用fgets()函数读取字符串,并删除'\n'(如果有(即输入的非'\n'字符个数小于n-1,(n来自fgets(char * ch,int n)))).另一种情况下的作用是清除缓存区中的其他字符,这只有当输入屏幕的字符串的数量>=n-1时才会执行.
这两种情况组成所有情况.
#include<stdio.h>
#include<string.h>
#define CONTENT 100
#define WHICHCHAR ' '
char * s_fgets(char ch[],int n);
char * s_fgets(char ch[],int n)
{
char * bol=fgets(ch,n,stdin);
// printf("fgets complete");
char * find;
if(bol)
{
find=strchr(ch,'\n');
if(find)
*find='\0';
else
while(getchar()!='\n')
continue;
// printf("s_gets complete");
}
return bol;
}
int main()
{
char ipt[CONTENT];
int i,count;
while(s_fgets(ipt,CONTENT)&&*ipt)
{
// printf("into while");
for(count=0,i=0;i<CONTENT&&*(ipt+i)!='\0';i++)
{
while(*(ipt+i+count)==WHICHCHAR)
count++;
*(ipt+i)=*(ipt+i+count);
}
printf("the quanity of '%c' is %d\n",count,WHICHCHAR);
puts(ipt);
printf("complete.'\\n' to quit.\n");
}
printf("quit succfuly");
}
(11)倒序输出字符串
8,21,22行使用函数strcat()函数,但必须要定义一个指向char的指针.
18,19行使用sprintf()函数,但必须要确定第一个参数的指向地址.
16行通过比较两个数组首元素地址的差值直接赋值,较为简便.
三种方法都可以实现相同的功能.
#include<stdio.h>
#include<string.h>
int main()
{
char ipt[100];
char opt[100];
int i=0;
char ch;char * temp=ch;
char * p=ipt;
fgets(ipt,100,stdin);
while(*(++p))
continue;
while(*(--p))
{
// *(opt+i++)=*p;
// i++;
// sprintf(opt+i,"%c",*p);
*temp=*p;
strcat(opt,temp);
// putchar(*p);
// puts(opt);
}
}
(12)四则运算
本人热衷于嵌套循环。发现四则运算中的括号中的内容完全可以作为新的运算,所以采用嵌套循环,即默认输入的字符串自带一个括号。
主要流程:
- 从字符串中提取数字和运算符。
数字使用读取while循环判断是否为数字(isalnum()(from:ctype.h))或者小数点,提取字符转化为新字符串,使用atof转化为float类型数据,放入堆栈中。
运算符直接读取:
- 如果是四则运算符:若在站内已有至少一个运算符时与前一个运算符比较优先级:如果前一个运算符优先级高于或等于当前栈顶运算符,则pop出前一个运算符,并pop出数字栈中的两个栈顶数字,进行运算后push入栈。(为了能够识别负数,所以需要在数字栈和运算符栈元素都为1时,将数字栈的栈底加入数字0,这样才能使运算符栈内的唯一运算符作用于两个数字。)
- 如果是'('则继续读取,直至读到逻辑上对应个')'。因为可能出现括号中有括号的情况,所以不能使用strchr或者strrchr,应该记录读取到的'('和‘)'数量。当数量匹配时,才可以作为新的嵌套循环的输入值。
当所有元素提取完成之后,我们再来看一下数字栈和运算符栈中剩余的内容:
运算符栈中存在至少为0,之多为输入字符串中运算符总数。无论是如何,栈内顶部运算符的优先级肯定要高于底下一个运算符的优先级。
数字栈中数字的数量为运算符栈运算符的数量(或者加一,即括号内是负数)
2、从尾到头把数字做运算。
从运算符栈顶pop出运算符,从数字栈中pop两个数字,进行相应运算。结束后将运算结果重新push入数字栈。依次循环直至运算符栈元素数量为0,数字栈元素数量为1.
总结:
我们从头来捋一下流程。首先,所有的表达式都能找到对应个括号。所以,括号内的内容都可以作为嵌套循环的输入。这样,我们就可以无需考虑括号了。
接着,我们可以把所有的运算顺序看成单个小单元,每个小单元内的运算顺序为从左到右,小单元与小单元直接的运算顺序为从右到左(对应栈的从顶到底)。在上面流程1中我们在读取字符串,读取到运算符时自动判断优先级,即自动判断当前小单元内有无从左到右的运算,如果没有,则不进行运算,小单元内只有对应的一个运算符和一个运算符后面的数字。如果有,则直接从左到右运算,也是只留下对应的一个运算符和一个运算符后面的数字。
这样下来,读取完整个字符串之后,我们顺便让每个小单元只对应一个运算符和一个数字。之后进行流程2,从右向左运算。
缺点:
1由于是嵌套循环,空间复杂度为n^x(x为维度,即括号嵌套的数量),所以不能计算括号中出现很多括号,中出现很多括号的情况,这样会占用大量的内存空间。
这种让数字pop出,计算,再push入栈的操作个人认为会比较浪费时间。可以采用变量储存结果,并拿去进行接下来的运算,或者直接改变栈内数字的值,即只pop不push
#include<stdio.h>
#include<ctype.h>
#include"stack_4cal.h"
float cal(char input[]) ;
int main()
{
char input[50]="(-1)+1.1*(0.2*(2-1)/1)";
printf("%.3f,",cal(input));
}
float cal(char input[])//解释
{
STACK Number={NULL,0};
STACK Operator={NULL,0};
char ch=0;;
int i=0;
ch=input[i];
while(ch!='\0')
{
if(isalnum(ch)||ch=='.')//解释
{
char chi[5]={0};
int ii=0;
while(isalnum(ch)||ch=='.')
{
chi[ii]=ch;
ii++;
i++;
ch=input[i];
}
i--;
ITEM a={atof(chi),'\0',0};//解释
PushToStack(a,&Number);
}
else
{
int class_=0;
if(ch=='(')
{
int kuohaojudg1=1;
int kuohaojudg2=0;
char kuohaoch[30]={0};
int ii=0;
for(ii=0;;ii++)
{
if(input[i+ii+1]=='(')
{
kuohaoch[ii]=input[i+ii+1];
kuohaojudg1++;
}
else if(input[i+ii+1]==')')
{
kuohaojudg2++;
if(kuohaojudg1==kuohaojudg2)
break;
kuohaoch[ii]=input[i+ii+1];
}
else
kuohaoch[ii]=input[i+ii+1];
}
kuohaoch[ii]='\0';
kuohaoch[ii+1]='\0';
ITEM tempp={0,'\0',0};
tempp.num=cal(kuohaoch);
PushToStack(tempp,&Number);
i=i+ii+2;
ch=input[i];
}
if(ch=='+'||ch=='-')
class_=0;
else if(ch=='*'||ch=='/')
class_=1;
ITEM a={0,ch,class_};
PushToStack(a,&Operator);
while(Operator.num>=2&&Operator.top->item.class_<=Operator.top->next->item.class_)
{
if(a.ch=='\0')
{
ITEM temp={0,'\0',0};
PopFromStack(&temp,&Operator);
continue;
}
ITEM temptop={0,'\0',0};
ITEM tempnext={0,'\0',0};
PopFromStack(&temptop,&Operator);
PopFromStack(&tempnext,&Operator);
PushToStack(temptop,&Operator);
ITEM temptopi={0,'\0',0};
ITEM tempnexti={0,'\0',0};
PopFromStack(&temptopi,&Number);
PopFromStack(&tempnexti,&Number);
float iii=0;
switch(tempnext.ch)
{
case '+':
iii=tempnexti.num+temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '-':
iii=tempnexti.num-temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '*':
iii=tempnexti.num*temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '/':
iii=tempnexti.num/temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
}
}
}
i++;
ch=input[i];
}
while(!StackIsEmpty(&Operator))//解释
{
if(Number.num==1)
{
ITEM top={0,'\0',0};
PopFromStack(&top,&Number);
ITEM end={0,'\0',0};
end.num=0;
PushToStack(end,&Number);
PushToStack(top,&Number);
}
ITEM temptop={0,'\0',0};
PopFromStack(&temptop,&Operator);
ITEM temptopi={0,'\0',0};
ITEM tempnexti={0,'\0',0};
PopFromStack(&temptopi,&Number);
PopFromStack(&tempnexti,&Number);
switch(temptop.ch)
{
float iii;
case '+':
iii=tempnexti.num+temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '-':
iii=tempnexti.num-temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '*':
iii=tempnexti.num*temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
case '/':
iii=tempnexti.num/temptopi.num;
temptopi.num=iii;
PushToStack(temptopi,&Number);
break;
}
}
// printf("%d\n",Number.top->item.num);
float temp=Number.top->item.num;
DeleteStack(&Number);
DeleteStack(&Operator);
return temp;
}
#ifndef __STACK_4CAL_H__
#define __STACK_4CAL_H__
#define MAXNUMBER 10
#include<stdbool.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
typedef struct item
{
float num;
char ch;
int class_;
}ITEM;
typedef struct node
{
ITEM item;
struct node * next;
}NODE;
typedef struct stack
{
NODE * top;
unsigned int num;
}STACK;
bool StackIsEmpty(STACK * Stack)
{
if(Stack->num==0)
return true;
else
return false;
}
bool StackIsFull(STACK * Stack)
{
if(Stack->num>=MAXNUMBER)
return true;
else
return false;
}
bool PushToStack(ITEM a,STACK * Stack)
{
if(StackIsFull(Stack))
{
fprintf(stderr,"failed to Push Item to Satck:Stack is full");;
return false;
}
Stack->num++;
NODE * pnode=(NODE * )malloc(sizeof(NODE));
if(pnode==NULL)
{
fprintf(stderr,"failed to push Item toStack:malloc error");
return false;
}
else
pnode->item=a;
pnode->next=Stack->top;
Stack->top=pnode;
return true;
}
bool PopFromStack(ITEM * Item,STACK * Stack)
{
if(StackIsEmpty(Stack))
{
// fprintf(stderr,"failed to pop Item from Satck:Stack is empty");
return false;
}
else
{
*Item=Stack->top->item;
NODE * tempnext=Stack->top->next;
free(Stack->top);
Stack->num--;
Stack->top=tempnext;
return true;
}
}
bool DeleteStack(STACK * Stack)
{
ITEM tempitem;
while(PopFromStack(&tempitem,Stack))
continue;
if(Stack->num==0)
return true;
else
return false;
}
#endif
(13)三元组法对稀疏矩阵实现存储,输出,转置。
目录:
|-Sparse_Matrix
|-Inc
|-sparse_matrix_10.h
|-sparse_matrix_3.h
|-Src
|-sparse_matrix_10.c
|-sparse_matrix_3.c
|-README.md
sparse_matrix_3.h:
//an ADT of sparse matrix
#ifndef __SPARSE_MATRIX_3_H_
#define __SPARSE_MATRIX_3_H_
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define MAXNUMBER 50
typedef struct node
{
unsigned int column;
unsigned int row;
int a;
} NODE;
typedef struct
{
unsigned int num_row;
unsigned int num_column;
unsigned int num;
NODE data[MAXNUMBER];
} SPARSE_MATRIX;
int cmp_row(const void * first,const void * second)
{
if(((NODE *)first)->row>((NODE *)second)->row)
return 1;
if(((NODE *)first)->row==((NODE *)second)->row)
return 0;
if(((NODE *)first)->row<((NODE *)second)->row)
return -1;
return 0;
}
int cmp_column(const void * first,const void * second)
{
if(((NODE *)first)->column>((NODE *)second)->column)
return 1;
if(((NODE *)first)->column==((NODE *)second)->column)
return 0;
if(((NODE *)first)->column<((NODE *)second)->column)
return -1;
return 0;
}
void CreatMatrix(SPARSE_MATRIX *test,unsigned int row ,unsigned int column, int matrix [row][column])
{
test->num_row = row;
test->num_column = column;
test->num = 0;
for(int i = 0; i < row; i++)
{
for(int j = 0; j < column; j++)
{
if(matrix[i][j] != 0)
{
test->data[test->num].row = i+1;
test->data[test->num].column = j+1;
test->data[test->num].a = matrix[i][j];
test->num++;
}
}
}
}
void ShowMatrix(SPARSE_MATRIX * test)
{
unsigned int cur_num=0;
unsigned int cur_column;
unsigned int cur_row=1;
while(cur_row<=test->num_row)
{
if(cur_row==test->data[cur_num].row)
{
cur_column=1;
while(cur_column<=test->num_column)
{
if(cur_num==test->num)//to avoid segsion fault cause by unseged array
{
while(cur_column<=test->num_column)
{
printf("0\t");
cur_column++;
}
break;
}
if(cur_row==test->data[cur_num].row&&cur_column==test->data[cur_num].column)
{
printf("%d\t",test->data[cur_num].a);
cur_num++;
}
else if(cur_row==test->data[cur_num].row&&cur_column<test->data[cur_num].column)
printf("0\t");
else if(cur_row==test->data[cur_num].row&&cur_column>test->data[cur_num].column)
assert(0);
else if(test->data[cur_num].row>cur_row)
printf("0\t");
else
assert(0);
cur_column++;
}
}
else if(cur_row<test->data[cur_num].row)
{
for(int i=1;i<=test->num_column;i++)
printf("0\t");
}
else if(cur_row>test->data[cur_num].row)
assert(0);
else
assert(0);
putchar('\n');
cur_row++;
}
putchar('\n');
}
void Transpose_Matrix(SPARSE_MATRIX *test)
{
unsigned int temp=test->num_column;
test->num_column=test->num_row;
test->num_row=temp;
for(int i=0;i<test->num;i++)
{
int temp;
temp=test->data[i].column;
test->data[i].column=test->data[i].row;
test->data[i].row=temp;
}
qsort(test->data,test->num,sizeof(NODE),cmp_row);
unsigned int i=0;
unsigned int sort_num;
while(i<test->num)
{
sort_num=0;
while(i<test->num-1&&test->data[i].row==test->data[i+1].row)
{
i++;
sort_num++;
}
if(i>=test->num-1)
{
qsort(test->data+i-sort_num,sort_num+1,sizeof(NODE),cmp_column);
break;
}
else
{
qsort(test->data+i-sort_num,sort_num+1,sizeof(NODE),cmp_column);
i++;
}
}
}
#endif
sparse_matrix_10.h:
//an ADT of sparse matrix
#ifndef __SPARSE_MATRIX_10_H_
#define __SPARSE_MATRIX_10_H_
#define MAXNUMBER 200
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
typedef struct node
{
unsigned int column;
unsigned int row;
int num ;
struct node * column_next;
struct node * row_next;
}NODE;
typedef struct sparse_matrix
{
NODE * set;
unsigned int num_row;
unsigned int num_column;
}SPARSE_MATRIX;
bool AddToMatrix(SPARSE_MATRIX * matrix,unsigned int row ,unsigned int column,int a)
{
NODE * pnode_column=matrix->set;
for(unsigned int i=0;i<column+1;i++)
pnode_column=pnode_column->column_next;
NODE * pnode_row=matrix->set;
for(unsigned int i=0;i<row+1;i++)
pnode_row=pnode_row->row_next;
NODE * pnode_target={0};
while(1)//to find the correct position(row) for node_target
{
if(pnode_column->row_next==NULL)
{
pnode_target=malloc(sizeof(NODE));
pnode_column->row_next=pnode_target;
pnode_column->row_next->num=a;
pnode_column->row_next->column=column;
pnode_column->row_next->row=row;
pnode_column->row_next->row_next=NULL;
break;
}
else if(pnode_column->row_next->row<row)
{
pnode_column=pnode_column->row_next;
continue;
}
else if(pnode_column->row_next->row==row)
{
pnode_column->row_next->num=a;
break;
}
else if(pnode_column->row_next->row>row)
{
NODE * temp_pnode=pnode_column->row_next;
pnode_target=malloc(sizeof(NODE));
pnode_column->row_next=pnode_target;
pnode_column->row_next->num=a;
pnode_column->row_next->column=column;
pnode_column->row_next->row=row;
pnode_column->row_next->row_next=temp_pnode;
break;
}
}
if(pnode_row->column_next==NULL)
{
pnode_row->column_next=pnode_target;
pnode_target->column_next=NULL;
}
else
while(1)
{
if(pnode_row->column_next==NULL)
{
pnode_row->column_next=pnode_target;
pnode_target->column_next=NULL;
break;
}
else if(pnode_row->column_next->column<column)
{
pnode_row=pnode_row->column_next;
continue;
}
else if(pnode_row->column_next->column==column)
{
if(pnode_row->column_next!=pnode_target)
{
fprintf(stderr,"signicifant logical error:multiply declaration of pnode_traget.");
assert(0);
}
break;
}
else if(pnode_row->column_next->column>column)
{
int temp_column=pnode_row->column_next->column;
NODE * temp_pnode=pnode_row->column_next;
pnode_row->column_next=pnode_target;
pnode_target->column_next=temp_pnode;
break;
}
}
return true;
}
bool CreatMatrix(SPARSE_MATRIX * Sparse_matrix ,unsigned int row ,unsigned int column, int matrix [row][column])
{
NODE * Set=malloc(sizeof(NODE));
if(Set==NULL)
{
fprintf(stderr,"failed to creat matrix:malloc error");
return NULL;
}
Sparse_matrix->set=Set;
Sparse_matrix->num_column=column+1;
Sparse_matrix->num_row=row+1;
NODE * Set_column[column+1];
for(unsigned int i=1;i<=column;i++)
{
Set_column[i]=malloc(sizeof(NODE));
if(Set_column[i]==NULL)
{
fprintf(stderr,"failed to creat matrix:malloc error");
return false;
}
Set_column[i]->row=0;
Set_column[i]->column=i;
}
for(unsigned int i=1;i<=column;i++)
{
if(i==column)
Set_column[i]->column_next=NULL;
else
Set_column[i]->column_next=Set_column[i+1];
Set_column[i]->row_next=NULL;
}
Sparse_matrix->set->column_next=Set_column[1];
NODE * Set_row[row+1];
for(unsigned int i=1;i<=row;i++)
{
Set_row[i]=malloc(sizeof(NODE));
if(Set_row[i]==NULL)
{
fprintf(stderr,"failed to creat matrix:malloc error");
return false;
}
Set_row[i]->row=i;
Set_row[i]->column=0;
}
for(unsigned int i=1;i<=row;i++)
{
if(i==row)
Set_row[i]->row_next=NULL;
else
Set_row[i]->row_next=Set_row[i+1];
Set_row[i]->column_next=NULL;
}
Sparse_matrix->set->row_next=Set_row[1];
for(unsigned int i=0;i<row;i++)
{
for(unsigned int ii=0;ii<column;ii++)
{
if(matrix[i][ii])
AddToMatrix(Sparse_matrix,i,ii,matrix[i][ii]);
}
}
return true;
}
void ShowMatrix(SPARSE_MATRIX * matrix)
{
NODE * node_column;
NODE * node_row=matrix->set->row_next;
unsigned int current_num;
while(node_row!=NULL)
{
node_column=node_row->column_next;
current_num=1;
while(current_num<matrix->num_column)
{
if(node_column==NULL)
{
printf("0\t");
}
else
{
if((node_column->column+1)==current_num)
{
printf("%d\t",node_column->num);
node_column=node_column->column_next;
}
else if((node_column->column+1)>current_num)
printf("0\t");
else if((node_column->column+1)<current_num)
printf("0\t");
}
current_num++;
}
node_row=node_row->row_next;
putchar('\n');
}
}
bool FreeMatrix(SPARSE_MATRIX * matrix)
{
NODE * pcolumn;
NODE * prow=matrix->set;
NODE * temp_column;
NODE * temp_row;
do
{
temp_row=prow;
prow=prow->row_next;
do
{
temp_column=temp_row;
temp_row=temp_row->column_next;
printf("%d ",temp_column->num);
free(temp_column);
} while (temp_row!=NULL);
putchar('\n');
} while (prow!=NULL);
return true;
}
#endif
sparse_matrix_3.c:
#include"sparse_matrix_3.h"
int main()
{
SPARSE_MATRIX test;
CreatMatrix(&test,7,5,(int[7][5]){{0,1,0,2,0},{3,0,4,0,5},{0,6,0,7,0},{8,0,9,0,10},{0,11,0,12,0},{13,0,14,0,15},{0,16,0,17,0}});
ShowMatrix(&test);
Transpose_Matrix(&test);
ShowMatrix(&test);
}
sparse_matrix_10.c:
#include"sparse_matrix_10.h"
int main()
{
SPARSE_MATRIX test;
CreatMatrix(&test,7,5,(int[7][5]){{0,1,0,2,0},{3,0,4,0,5},{0,6,0,7,0},{8,0,9,0,10},{0,11,0,12,0},{13,0,14,0,15},{0,16,0,17,0}});
ShowMatrix(&test);
FreeMatrix(&test);
}
readme:
使用三元组创建、修改、转置、输出稀疏矩阵。
转置过程为修改行列值,使用qsort()先对行进行快速排序,再对列进行快速排序。
使用稀疏矩阵创建、修改、输出稀疏矩阵。
创建过程为先读取行列数,创建十字链表的表头,并置空。读取所有非0数据,按照依次读取输入输入的复合字面量的每行中的每列的数据,按照先贴在列表头,再与行表头衔接的方式添加至十字链表中。
修改的过程为读取要修改的数据和所在的位置后,先在十字链表中定位到修改的位置,若所在位置原本存在节点,则直接修改节点数据;若不存在节点,则按照先在列链表中从链表头向后移动,直至找到节点与节点之间或者节点与NULL之间的位置,创建新节点连接上下左右四个方向的两个节点或者NULL之间。
输出过程为按照行的方式从表头像后读取,并且在输出中填充0.
下图123为debug过程中工作区变量的变化,可以看到矩阵实现了转置。
图4显示了稀疏矩阵实际存储在内存中的形式,可以看到是使用十字链表形式。