注册CSDN四年了,从来没发过东西。
这次开这篇博文,一是为了记录自己数据结构的学习进程,二是为了督促自己学习,三是为了锻炼代码能力。
因为现在在学第四章,就先上传第四章的练习。前三章之后补上。
![运行效果](https://i-blog.csdnimg.cn/blog_migrate/d1ba7390e9cf1dcabbca1baedb673ce1.png)
/*
串的实现,采用静态分配方式(C/C++语言),即定长顺序存储,以.cpp结尾的C++语言文件
由于C++语言支持引用,故已.cpp结尾,但仍采用C语言语法书写(但也不一定)。
故:采用引用方式实现各种基本功能。
*/
using namespace std;
#include<iostream>
#include<bitset>
#include <stdio.h> //标准输入输出头文件
#include <stdbool.h> //在C99以后是GCC是有bool类型的定义的,但需引入stdbool.h头文件,其中false=0 true=1;
#include <stdlib.h>
#define MaxLen 255 //定义串的最大长度
typedef struct {
char ch[MaxLen + 1]; //每个分量存储一个字符,且0号单元不存放元素
int length; //串的实际长度
} SString;
void PrintMenu(); //定义菜单函数
void FunSelect(); //定义功能选择函数
void InitString( SString &S ); //定义初始化一个串
bool StrAssign( SString &T, char *chars ); //定义串的赋值操作
bool StrCopy( SString &T, SString S ); //定义串的复制操作
bool StrEmpty( SString S ); //定义串的判空操作
int StrCompare( SString S, SString T ); //定义串的比较操作
int StrLength( SString S ); //定义求串长操作
bool SubString( SString &Sub, SString S, int pos, int len ); //定义求子串操作
bool Concat( SString &T, SString S1, SString S2 ); //定义串联接操作
bool ClearString( SString &S ); //定义串的清空操作
int Index( SString S, SString T ); //定义串的定位操作
void PrintSString( SString S ); //定义打印串中各元素的值
SString S; //定义一个串,名为S
SString T; //定义一个串,名为T
int main() {
InitString( S ); //初始化串S
InitString( T ); //初始化串T
PrintMenu(); //打印菜单函数
FunSelect(); //功能选择函数
return 0;
}
//实现初始化一个串
void InitString( SString &S ) {
for( int i = 0; i <= MaxLen; i++ ) {
S.ch[i] = '\0'; //将串中每一个元素都初始化为'\0'
}
S.length = 0; //将串的长度初始化为0
}
//实现串的赋值操作
bool StrAssign( SString &T, char *chars ) {
char *c = chars;
int j = 0;
for (j = 0; *c; j++, ++c)
;
if (j == 0 || j > MaxLen) //判断字符串的长度是否合法
return false;
else
{
T.length = j;
for (int i = 1; i <= T.length; i++)
{
T.ch[i] = chars[i - 1]; //将字符串赋给串
}
return true;
}
}
//实现串的复制操作
bool StrCopy( SString &T, SString S ) {
for( int i = 1; i <= S.length; i++ ) {
T.ch[i] = S.ch[i];
}
T.length = S.length;
return true;
}
//实现串的判空操作
bool StrEmpty( SString S ) {
if ( S.length == 0 ) //串的结构体中,以lenth记录串长,串长为0即为空串
return true;
else return false;
}
//实现串的比较操作
int StrCompare( SString S, SString T ) {
for ( int i = 1; i <= S.length && i <= T.length; i++ ) {
if ( S.ch[i] != T.ch[i] )
return S.ch[i] - T.ch[i];
}
return S.length - T.length; //S>T,返回值>0; S=T,返回值=0; S<T,返回值<0
}
//实现求串长操作
int StrLength( SString S ) {
int i = 1;
while( S.ch[i] != '\0' ) { //遍历串中各个元素,直到查到串的结尾,即 '\0',便可求得串长
i++;
}
return i - 1;
}
//实现求子串操作
bool SubString( SString &Sub, SString S, int pos, int len ) {
if ( pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1 )
return false; //判断所求子串的起始位置和长度在主串中是否合法
for ( int i = pos; i < pos + len; i++ )
Sub.ch[i - pos + 1] = S.ch[i]; //将主串对应位置的元素赋予子串
Sub.length = len;
return true;
}
//实现串联接操作
bool Concat( SString &T, SString S1, SString S2 ) { //用T返回由S1和S2联接而成的新串。若未截断,返回true,否则返回fasle
if( S1.length + S2.length <= MaxLen ) { //未截断情况
for( int i = 1; i <= S1.length + S2.length; i++ ) {
if( i <= S1.length )
T.ch[i] = S1.ch[i];
else T.ch[i] = S2.ch[i - S1.length];
}
T.length = S1.length + S2.length;
return true;
}
else if( S1.length < MaxLen ) { //截断情况,且S1的长度小于MaxLen
for( int i = 1; i <= MaxLen; i++ ) {
if( i <= S1.length )
T.ch[i] = S1.ch[i];
else T.ch[i] = S2.ch[i - S1.length];
}
T.length = MaxLen;
return false;
}
else { //截断情况,且S1的长度恰好等于MaxLen
for( int i = 1; i <= MaxLen; i++ ) {
T.ch[i] = S1.ch[i];
}
T.length = MaxLen;
return false;
}
}
//实现串的清空操作
bool ClearString( SString &S ) {
for( int i = 0; i <= S.length; i++ ) {
S.ch[i] = '\0'; //将串中各个元素变为'\0'
}
S.length = 0;
return true;
}
//实现串的定位操作
int Index( SString S, SString T ) {
int k = 1; //定义k,用于存储主串与子串对比的起始位置
int i = k, j = 1;
while( i <= S.length && j <= T.length ) {
if( S.ch[i] == T.ch[j] ) {
++i;
++j; //主串与子串元素对应,则对比下一个元素
} else {
k++;
i = k;
j = 1; //主串与子串元素对应失败,则主串中回退到起始位置k,子串回退到起始位置1
}
}
if( j > T.length )
return k;
else
return 0;
}
//实现打印串中各元素的值
void PrintSString( SString S ) {
if( S.length == 0 ) {
printf( "该串为空串" );
}
int i;
for( i = 1; i <= S.length; i++ ) {
printf( "%c", S.ch[i] );
}
printf( "\n" );
}
//实现打印菜单函数
void PrintMenu() {
printf( "\n数据结构-第四章-串-定长顺序存储表示\n\n" );
printf( " ————————————————————————————\n" );
printf( "|\t 1.赋值操作\t2.复制操作\t\t\t |\n\n" );
printf( "|\t 3.判空操作\t4.比较操作\t\t\t |\n\n" );
printf( "|\t 5.求串长\t6.求子串\t7.串联接\t |\n\n" );
printf( "|\t 8.清空串\t9.定位串\t0.退出\t\t |\n" );
printf( " ————————————————————————————\n\n" );
}
//实现功能选择函数
void FunSelect() {
int funNum;
while( true ) {
printf( "请输入功能函数序号:" );
scanf( "%d", &funNum );
fflush( stdin );
switch( funNum ) {
case 0:
exit( 0 );
case 1: {
char flag;
printf( "请输入要操作的串S or T:" );
scanf( "%c", &flag );
fflush( stdin );
switch( flag ) {
case'S': {
printf( "请输入要赋值的字符串:" );
char chars[256];
scanf( "%[^\n]%*c", chars );
fflush( stdin );
if ( StrAssign( S, chars ) ) {
printf( "赋值成功,当前串中元素值为:\n" );
PrintSString( S );
} else {
printf( "赋值失败\n" );
}
break;
}
case'T': {
printf( "请输入要赋值的字符串:" );
char chars[256];
scanf( "%[^\n]%*c", chars );
fflush( stdin );
if ( StrAssign( T, chars ) ) {
printf( "赋值成功,当前串中元素值为:\n" );
PrintSString( T );
} else {
printf( "赋值失败\n" );
}
break;
}
}
break;
}
case 2: {
char flag;
printf( "请输入要粘贴而成的串S or T:" );
scanf( "%c", &flag );
fflush( stdin );
switch( flag ) {
case'S': {
if( StrCopy( S, T ) ) {
printf( "已将串T复制给串S,串S中的元素值为:\n" );
PrintSString( S );
} else {
printf( "复制失败\n" );
}
break;
}
case'T':{
if( StrCopy( T, S ) ) {
printf( "已将串S复制给串T,串T中的元素值为:\n" );
PrintSString( T );
} else {
printf( "复制失败\n" );
}
break;
}
break;
}
}
case 3:{
char flag;
printf("请输入要判空的串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
if(StrEmpty( S )){
printf("串S为空串\n");
}else{
printf("串S非空,其元素个数为:%d\n",S.length);
}
break;
}
case'T':{
if(StrEmpty( T )){
printf("串T为空串\n");
}else{
printf("串T非空,其元素个数为:%d\n",T.length);
}
break;
}
}
break;
}
case 4:{
if(StrCompare(S,T)>0){
printf("串S和串T的比较结果为:S>T \n");
}
else if(StrCompare(S,T)<0){
printf("串S和串T的比较结果为:S<T \n");
}
else{
printf("串S和串T的比较结果为:S=T \n");
}
break;
}
case 5:{
char flag;
printf("请输入要求串长的串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
printf("串S的串长为:%d\n",StrLength(S));
break;
}
case'T':{
printf("串T的串长为:%d\n",StrLength(T));
break;
}
}
break;
}
case 6:{
char flag;
printf("请输入要求子串的串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
printf("请输入子串的起始位置pos及子串的长度len\n");
int pos;
int len;
SString Sub;
scanf("%d%d",&pos,&len);
if(SubString(Sub,S,pos,len)){
printf("串S第%d个字符起长度为%d的子串为:\n",pos,len);
PrintSString( Sub );
}else{
printf("求子串操作失败!原因:位序或长度不合法\n");
}
break;
}
case'T':{
printf("请输入子串的起始位置pos及子串的长度len\n");
int pos;
int len;
SString Sub;
scanf("%d%d",&pos,&len);
if(SubString(Sub,S,pos,len)){
printf("串T第%d个字符起长度为%d的子串为:\n",pos,len);
PrintSString( Sub );
}else{
printf("求子串操作失败!原因:位序或长度不合法\n");
}
break;
}
}
break;
}
case 7:{
char flag;
printf("请输入联接而成的新串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
char chars[256];
SString S1;
SString S2;
printf("请输入串S1的内容:\n");
scanf( "%[^\n]%*c", chars );
fflush( stdin );
StrAssign( S1, chars );
printf("请输入串S2的内容:\n");
scanf( "%[^\n]%*c", chars );
fflush( stdin );
StrAssign( S2, chars );
if(Concat(S,S1,S2)){
printf( "联接成功,当前串S中元素值为:\n" );
PrintSString( S );
}else{
printf( "发生截断,当前串S中元素值为:\n" );
PrintSString( S );
}
break;
}
case'T':{
char chars[256];
SString S1;
SString S2;
printf("请输入串S1的内容:\n");
scanf( "%[^\n]%*c", chars );
fflush( stdin );
StrAssign( S1, chars );
printf("请输入串S2的内容:\n");
scanf( "%[^\n]%*c", chars );
fflush( stdin );
StrAssign( S2, chars );
if(Concat(S,S1,S2)){
printf( "联接成功,当前串T中元素值为:\n" );
PrintSString( S );
}else{
printf( "发生截断,当前串T中元素值为:\n" );
PrintSString( S );
}
break;
}
}
break;
}
case 8:{
char flag;
printf("请输入要清空的串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
if(ClearString(S)){
printf("已清空串S!\n");
}else{
printf("清空失败!\n");
}
break;
}
case'T':{
if(ClearString(S)){
printf("已清空串S!\n");
}else{
printf("清空失败!\n");
}
break;
}
}
break;
}
case 9:{
char flag;
printf("请输入要进行定位操作的母串S or T:");
scanf( "%c", &flag );
fflush( stdin );
switch(flag){
case'S':{
if(Index(S,T)!=0){
printf("主串S中与串T相等的子串的起始位置为:%d\n",Index(S,T));
}else{
printf("主串S中不存在与串T相等的子串\n");
}
break;
}
case'T':{
if(Index(T,S)!=0){
printf("主串T中与串S相等的子串的起始位置为:%d\n",Index(T,S));
}else{
printf("主串T中不存在与串S相等的子串\n");
}
break;
}
}
break;
}
}
}
}