实验总结报告-串和数组
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验总结报告—栈和队列
学号:姓名:时间:
一、目的
1.做实验的目的
2.2.撰写实验报告的目的
二、内容
1.说明实验次数及实验内容
本次实验用一个实验课时完成。
实验内容:
1. 编写函数StrAssign(), StrCopy() , StrLenth() , StrCompare() , StrConcat() ,
Substring(), Replace(),完成串赋值,串复制,求串长度,串比较,串连接,求字
串,子串替代等相应功能。
注:Replace() 依赖Find_KMP()
2. 使用KMP 算法,编写函数Find_KMP(char *S,char *P,int start)实现字符串匹配。
测试数据:
2.1
char S[] = “abcabcabcd”;
char P[] = “abcabcd”;
2.2char S[] = “abcdababcabcdabcabcabcd”;
char P[] = “abcabcd”;
2.3
char S[] = “cocaocoaoc”;
char P[] = “coaoc”;
要求: 1.打印出模式串P 的next[]模式数组;
2.完成Find_KMP()后在Repalce()中调用,将P 替换成“AAA”。
注意2.2 有2 个地方要替换。
3. 创建三元组实现以下稀疏矩阵的存储,并利用三元组实现稀疏矩阵的转置,比
较“按需查找”方法与“按位就座”方法的区别。
0 12 9 0 0 0 0
0 0 0 0 0 0 0
3 0 0 0 0 1
4 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 7 0 0 0
建议实现流程为1.矩阵2.三元组3.转置的三元组4.转置的矩阵,将3 或4
打印出来。
2.做实验完成情况
实验内容在实验课时时间内完成(提前编写了大概1/2部分的代码),
选做内容也完成。
本次实验内容较多,为使代码看着简洁有条理,采用了建工程的方式。
串部分:
自定义了头文件String.h:
/*自定义头文件*/
#include<stdio.h>
#define MAX_LEN 255
typedef unsigned char SString[MAX_LEN + 1];
/*自定义函数*/
void StrAssign(SString &T, char s[]);//将字符串常量s赋给T
void StrPrint(SString T);//打印串
void StrCopy(SString &T, SString S);//串复制
void test();//检验串操作
int StrLength(SString T);//求串长
int StrCompare(SString T, SString S);//比较串,T>S返回正值,T<S返回负值,相等返回0
void StrConcat(SString &T, SString S1, SString S2);//用T返回SString 类型串S1、S2连接成的新串
void SubString(SString &S, SString T, int pos, int len);//用S返回串T中起始位置为pos,长度为len的字串
void Index(SString S, SString T, int pos[]);//若S串中存在不重叠的子串T,则用pos[]返回所有T串的起始位置
void StrReplace(SString &S, SString T, SString V);//若串S中存在字串T,则用V替代所有不重叠的T
void StrInsert(SString &S, int pos, SString T);//在串S中pos位置插入子串T
void StrDelete(SString &S, int pos, int len);//在串S中pos位置删除长度为len的子串
void GetNext(SString S, int next[]);//求模式串中的next函数修正值并写入数组next[]
int FindKMP(SString S, SString T, int start);//在串S中从start位置开始,查找第一次出现模式T的位置返回,没找到返回-1
void StrReplace2(SString &S, SString T, SString V);//若串S中存在字串T,则用V替代所有不重叠的T
void KMP();//KMP算法及其应用
在头文件中对所有要用到的自定义函数进行了声明,各函数的功能可见代码注释部分。
串赋值:
#include"String.h"
void StrAssign(SString &T, char s[]){
if (!s){
printf("Error\n");
return;
}
int i = 0;
while (s[i]!='\0'){
T[i] = s[i];
i++;
}
T[i] = '\0';
}
该操作将字符串常量s中的元素赋值给SString类型T;串复制:
#include"String.h"
void StrCopy(SString &T, SString S){
if (!S){
printf("原串为空串\n");
return;
}
int i = 0;
while (S[i] != '\0'){
T[i] = S[i];
i++;
}
T[i] = '\0';
}
该操作完成将SString类型T赋给SString类型S;求串长度:
#include"String.h"
int StrLength(SString T){
int i=0;
while (T[i] != '\0')
i++;
return i;
}
该操作返回SString类型中元素的个数即串的长度;串比较:
#include"String.h"
int StrCompare(SString T, SString S){
int i;
for (i = 0; T[i] != '\0'&&S[i] != '\0';i++)
if (S[i] != T[i])
return T[i] - S[i];
return T[i] - S[i];
}
串连接:
#include"String.h"
void StrConcat(SString &T, SString S1, SString S2){
int i;
if (!S1&&!S2){
printf("Error\n");
return;
}//S1、S2均为空
if (!S1&&S2){
for (i = 0; S2[i] != '\0'; i++)
T[i] = S2[i];
T[i] = '\0';
return;
}//S1为空
if (!S2&&S1){
for (i = 0; S1[i] != '\0'; i++)
T[i] = S1[i];
T[i] = '\0';
return;
}//S2为空
for (i = 0; i <= StrLength(S1); i++)
T[i] = S1[i];
for (i = 0; i <= StrLength(S2); i++)
T[i + StrLength(S1)] = S2[i];
T[StrLength(S1) + StrLength(S2) + 1] = '\0';
}
此操作完成将串S1和S2连接之后赋给T;
求子串:
#include"String.h"
void SubString(SString &S, SString T, int pos, int len){
int Tlen,i;
Tlen = StrLength(T);
if (pos + len > Tlen || pos<0 || pos>Tlen - 1 || len < 0){ printf("Error");
return;
}
for (i = 0; i < len; i++)
S[i] = T[i + pos];
S[i] = '\0';
}
该操作求出T串的一个子串S;
子串代替:
参考BF算法:
#include"String.h"
void StrReplace(SString &S, SString T, SString V){
int pos[20], i,Tlen;
Tlen = StrLength(T);
for (i = 0; i < 20; i++)
pos[i] = 1000;
Index(S, T, pos);
for (i = 0; pos[i] != 1000; i++){
StrDelete(S, pos[i], Tlen);
StrInsert(S, pos[i], V);
}
}
此方法要用到Index()函数,此函数参考BF算法完成:#include"String.h"
void Index(SString S, SString T, int pos[]){
int i,j=0,Slen, Tlen,flag=0,count= 0;
Slen = StrLength(S);
Tlen = StrLength(T);
for (i = 0; i <= Slen;){
if (S[i]== T[j]){
flag++;
if (flag == Tlen){
pos[count] =i-Tlen+1;
count++;
flag = 0;
j = 0;
i++;
}
else{
i++;
j++;
}
}
else{
flag = 0;
i++;
j = 0;
}
}
if (count == 0)
printf("S中没有T串\n");
}
参考KMP算法:
#include"String.h"
void StrReplace2(SString &S, SString T, SString V){
int start,Tlen;
Tlen = StrLength(T);
while (FindKMP(S,T,0) != -1){
start = FindKMP(S, T, 0);
StrDelete(S, start, Tlen);
StrInsert(S, start, V);
}
}
此方法利用了KMP算法,需要求next[]数组;KMP算法:
#include"String.h"
int FindKMP(SString S, SString T, int start){
int i, j = 0, next[20];
GetNext(T, next);
if (start<0 || start>StrLength(S) - StrLength(T)){ return -1;
}
i = start;
while (i < StrLength(S) && j < StrLength(T)){ if (j == -1 || S[i] == T[j]){
i++;
j++;
}
else
j = next[j];
}
if (j == StrLength(T))
return i - j;
return -1;
}
KMP算法需要求next[]数组进行辅助;Next:
#include"String.h"
void GetNext(SString S, int next[]){
int j = 0, k = -1;
next[0] = -1;
while (j < StrLength(S)){
if (k == -1 || S[j] == S[k]){
j++;
k++;
if (S[j] != S[k])
next[j] = k;
else
next[j] = next[k];
}
else
k = next[k];
}
}
此操作获得模式串改进后的next[]数组;
除此之外,我还用到了子串删除和子串插入的操作:
#include"String.h"
void StrDelete(SString &S, int pos, int len){
int i;
if (pos > StrLength(S) - 1 || pos + len > StrLength(S) || len < 0 || pos < 0){
printf("Error");
return;
}
for (i = pos; i <= StrLength(S)-len; i++)
S[i] = S[i + len];
}
#include"String.h"
void StrInsert(SString &S, int pos, SString T){
int i,Slen,Tlen;
Slen = StrLength(S);
Tlen = StrLength(T);
for (i = Slen; i>=pos; i--)
S[i+Tlen] = S[i];
for (i = 0; i < Tlen; i++)
S[pos + i] = T[i];
S[Slen + Tlen + 1] = '\0';
}
主函数中分别调用test()和KMP()用来实现对串操作的检验和对KMP 算法的检验
主函数:
/*主函数*/
#include"String.h"
#include<stdlib.h>
int main(){
/*检验串操作的正确性*/
test();
/*KMP算法及其应用*/
KMP();
system("pause");
return 0;
}
Test():
#include"String.h"
void test(){
printf("=========================================\n");
printf("Test Begain:\n");
printf("\n");
char s[] = "abcdefgh";
int len, r, pos[20], i;
SString T, S,Q,P;
SString R = "abcdkhaksabcdlkjflabcd";
SString R2 = "abc";
SString R3 = "xyz";
StrAssign(T, s);
StrPrint(T);
StrCopy(S, T);
StrPrint(S);
len = StrLength(S);
printf("len=%d\n", len);
r = StrCompare(R, T);
printf("r=%d\n", r);
StrConcat(Q, T, R);
StrPrint(Q);
SubString(P, Q, 5, 10);
StrPrint(P);
for (i = 0; i < 20; i++)
pos[i] = 1000;
Index(R, R2, pos);
for (i = 0;pos[i]!=1000;i++)
printf("pos[%d]=%d ",i, pos[i]); printf("\n");
StrDelete(R, 5, 6);
StrInsert(R, 4, R2);
StrReplace(R, R2, R3);
StrPrint(R);
printf("\n");
printf("Test End!\n");
printf("=========================================\n"); }
KMP():
#include"String.h"
void KMP(){
printf("KMP Begain:\n");
printf("\n");
SString S1 = "abcabcabcd", S2 = "abcdababcabcdabcabcabcd", S3 = "cocaocoaoc";
SString P1 = "abcabcd", P2 = "abcabcd", P3 = "coaoc";
SString P = "AAA";
int next1[20], next2[20], next3[20], i, r1, r2, r3;
GetNext(P1, next1);
for (i = 0; i < StrLength(P1); i++)
printf("next1[%d]=%d\n", i, next1[i]);
r1 = FindKMP(S1, P1, 0);
printf("r1=%d\n", r1);
StrReplace2(S1, P1, P);
StrPrint(S1);
printf("\n");
GetNext(P2, next2);
for (i = 0; i < StrLength(P2); i++)
printf("next2[%d]=%d\n", i, next2[i]);
r1 = FindKMP(S2, P2, 0);
printf("r2=%d\n", r1);
StrReplace2(S2, P2, P);
StrPrint(S2);
printf("\n");
GetNext(P3, next3);
for (i = 0; i < StrLength(P3); i++)
printf("next3[%d]=%d\n", i, next3[i]);
r1 = FindKMP(S3, P3, 0);
printf("r3=%d\n", r1);
StrReplace2(S3, P2, P);
StrPrint(S3);
printf("\n");
printf("KMP End!\n");
printf("=========================================\n"); }
实验结果:
从实验结果来看,串的各个操作成功实现。
数组部分:
自定义了头文件Array.h:
/*自定义头文件(数组)*/
#include<stdio.h>
#define MAX_SIZE 1000
/*结构体*/
typedef int ElemType;
typedef struct{
int i, j;
ElemType e;
}Triple;
typedef struct{
Triple data[MAX_SIZE];
int mu, nu, tu;
}TSMatrix;
/*自定义函数*/
void CreateTSMatrix(TSMatrix &M, ElemType m[][7],int r,int c);//创建三元组
void PrintTSMatrix(TSMatrix M);//打印三元组
void CreateRpos(TSMatrix M,int rpos[],int num[]);//求矩阵的rops数组void TRansposeTS(TSMatrix M, TSMatrix &T);//将三元组顺序表压缩存储的矩阵M转置为矩阵T
在头文件中对所有要用到的自定义函数进行了声明,各函数的功能可见代码注释部分。
创建三元组:
#include"Array.h"
void CreateTSMatrix(TSMatrix &M, ElemType m[][7],int r,int c){
M.mu = r;
M.nu = c;
M.tu = 0;
int k, l;
for (k = 0; k < r; k++){
for (l = 0; l < c; l++){
if (m[k][l] != 0){
M.data[M.tu].e = m[k][l];
M.data[M.tu].i = k;
M.data[M.tu].j = l;
M.tu++;
}
}
}
此操作将r*c的矩阵创建成三元组表示的矩阵TSMatrix M;转置三元组矩阵:
#include"Array.h"
#define MAXM 100
void TRansposeTS(TSMatrix M, TSMatrix &T){
int p, q,col;
int num[MAXM], rpos[MAXM];
T.mu = M.nu;
T.nu = M.mu;
T.tu = M.tu;
if (!M.tu)
return;
CreateRpos(M, rpos, num);
for (p = 0; p < M.tu; p++){
col = M.data[p].j;
q = rpos[col];
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++rpos[col];
}
}
该操作将原三元组矩阵进行转置得到新的三元组矩阵,此过程需要用到一个辅助函数以获得rpos[]数组:
#include"Array.h"
void CreateRpos(TSMatrix M, int rpos[], int num[]){
int col,t;
for (col = 0; col < M.nu; col++)
num[col] = 0;
for (t = 0; t < M.tu; t++)
++num[M.data[t].j];
rpos[0] = 0;
for (col = 1; col < M.nu; col++)
rpos[col] = rpos[col - 1] + num[col - 1];
}
为检验是否正确建立三元组矩阵以及是否成功进行了转置,需要将三元组进行打印:
#include"Array.h"
void PrintTSMatrix(TSMatrix M){
printf("i j e\n");
int k;
for (k = 0; k < M.tu; k++)
printf("%d %d %d\n", M.data[k].i, M.data[k].j,M.data[k].e);
printf("\n");
}
主函数:
#include"Array.h"
#include<stdlib.h>
int main(){
ElemType m[6][7] = { { 0, 12, 9, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 3, 0, 0, 0, 0, 14, 0 }, { 0, 0, 24, 0, 0, 0, 0 }, { 0, 18, 0, 0, 0, 0, 0 }, { 15, 0, 0, 7, 0, 0, 0 } };
TSMatrix M,T;
CreateTSMatrix(M, m, 6, 7);
PrintTSMatrix(M);
TRansposeTS(M, T);
PrintTSMatrix(T);
system("pause");
return 0;
}
实验结果:
从实验结果来看成功进行了三元组的有关操作。
三、总结。