一.编写程序用三元组实现稀疏矩阵的按列转置操作。
算法设计:
用三元组表实现
程序设计三个函数:
- 函数InitSPNode()用来建立一个稀疏矩阵的三元组表。
键入行数,列数,非零元的值,输入(-1,-1,-1)结束。 - 函数ShowMatrix()用来输出稀疏矩阵。
按矩阵a的列进行循环处理,对a的每一列扫描三元组,找出相应的元素,若找到,则交换其行号与列号,并存储到矩阵b的三元组中。 - 函数TransposeSMatrix()用来完成稀疏矩阵的转置
在p和列col的两重循环中完成,时间复杂度为O(nt).如果非零元素的个数t和mn同数量级,则算法的时间复杂度变为O(m*n^2).
完整代码:
#include <stdio.h>
#include <string.h>
#define OK 1
#define MAXSIZE 10
//定义三元组结构体
typedef struct{
int i,j; //行序数i;列序数j;非零元的值v
int v;
}SPNode;
//定义矩阵结构体
typedef struct{
SPNode data[MAXSIZE]; //三元组结构数组
int m,n,t; //矩阵的最大行数、最大列数、非零元总数-1 t
}SPMatrix;
//初始化三元组
void InitSPNode (SPMatrix *a){
int i,j,k,val,maxrow,maxcol; //最大行数maxrow,最大列数maxcol, 行数i,列数j,非零元的值val
maxrow = 0; // 初始化为零
maxcol = 0;
i=0;
j=0;
k=0; //三元组结构数组的数组下标 k 非零元的数组下标
while(i != -1 && j != -1){
printf(“请输入(行 列 值):\n”); //键入i,j,val
scanf("%d %d %d",&i,&j,&val);
a->data[k].i=i;
a->data[k].j=j;
a->data[k].v=val;
if(maxrow<i){ //刷新最大行数
maxrow=i;
}
if(maxcol<j){ // 刷新最大列数
maxcol=j;
}
k++; //非零元的数组下标加一
}
a->m=maxrow;
a->n=maxcol;
a->t=k-1;
}
//打印矩阵
void ShowMatrix(SPMatrix *a){
int p, q; //矩阵的行数p,列数q
int t=0;
for(p=1;p<=a->m;p++){ //从第一行开始
for(q=1;q<=a->n;q++){ //从第一列开始
if(a->data[t].ip && a->data[t].jq){ //输出该位置的值
printf("%d “,a->data[t].v);
t++;
}
else{ //为零元则输出零
printf(“0 “);
}
}
printf(”\n”);
}
}
//转置函数
void TransposeMatrix(SPMatrix *a,SPMatrix *b){
int q,col,p;
b->m=a->n; //将a最大列数赋给b的最大函数
b->n=a->m; //将a最大函数赋给b的最大列数
b->t=a->t; //将a的t赋给b的t
if(b->t){
q=0;
for(col=0;col<=a->n;++col){ //将数组a按列进行循环处理
for(p=0;pt;++p){
if(a->data[p].j==col){
b->data[q].i=a->data[p].j;
b->data[q].j=a->data[p].i;
b->data[q].v=a->data[p].v;
++q;
}
}
}
}
}
int main(void){
SPMatrix a,b;
printf(”\n结束请输入(-1 -1 -1)\n");
InitSPNode(&a);
printf(“输入矩阵为: \n”);
ShowMatrix(&a);
TransposeMatrix(&a,&b);
printf(“输出矩阵为: \n”);
ShowMatrix(&b);
return 0;
}
运行结果
二:KMP算法的实现:求一个字符串在另一个字符串从中第一次出现的位置。
算法设计:
设计使用串的顺序结构来实现。
- 函数GetNext()用来求next的值
求模式串t的next函数值并存放在数组next中。 - 函数IndexKMP()用来实现模式匹配算法。
子串中的每一个字符一次和主串中的一个连续的字符序列相等,则成为匹配成功。否则称为匹配不成功,程序中函数GetNext()是求出模式串t的next函数值,并村饭如数组。
完整代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef char String[MAXSIZE+1]; /* 下标为0处存放串的长度 */
int StrAssign(String T,char * chars){ //字符串chars
if(strlen(chars)>MAXSIZE){
return 0;
}
else{
T[0]=strlen(chars); //第一位保存字符串长度
for(int i=1;i<=T[0];i++){
T[i]=*(chars+i-1);
}
return 1;
}
}
void StrPrint(String T){
for(int i=1;i<=(T[0]+1);i++)
printf("%c",T[i]);
printf("\n");
}
void GetNext(String T,int *next){
int i,k;
i=1;
k=0;
next[1]=0;
while(i<T[0]){
if(k==0||T[i]==T[k]){
i++;
k++;
next[i]=k;
}
else
k=next[k]; //若k值不相同,则k值回溯
}
}
int IndexKMP(String S,String T,int pos){
int i=pos; //i用于主串S当前位置的下标值,从指定位置pos开始
int j=1; //j用于子串T当前位置的下标值,从1开始
int next[255];
GetNext(T,next); //分析T串得到next数组
while(i<=S[0]&&j<=T[0])
{
if(j==0||S[i]==T[j]) //j=0即回溯到边界的情况时 或 两字母相等时 继续
{
i++;
j++;
}
else{
j=next[j]; //j退回到合适的位置
}
}
if(j>T[0])
return i-T[0];
else
return 0;
}
int main(void){
int i;
String S,T;
StrAssign(S,"qwerrrrrrtqwertqweryyyy");
StrAssign(T,"qwery");
printf("主串为: ");
StrPrint(S);
printf("子串为: ");
StrPrint(T);
i=IndexKMP(S,T,1);
printf("主串和子串在第%d个字符处首次匹配。\n",i);
return 0;
}