1. 程式人生 > >資料結構:字串(堆)——基本操作

資料結構:字串(堆)——基本操作

資料結構的重要行不言而喻,簡單介紹我在這部分遇到的一些問題,希望對大家有少許幫助。

首先實現的多個操作:
在這裡插入圖片描述

程式碼:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define    OK    1
#define  ERROR   -1
#define  OVERFLOW  -3
#define   BIG    2
#define   EQUAL  0
#define   LITTLE  -2
typedef    int Status;

typedef  struct
{ char *ch; int length; }HString; //功能 void menu() { printf("\t\t***************串的堆實現*********************\n"); printf("\t\t\t1 求字串的長度\n"); printf("\t\t\t2 從主串中提取一個子串\n"); printf("\t\t\t3 比較兩個字串的大小\n"); printf("\t\t\t4 求一個子串在主串中的位置\n"); printf("\t\t\t5 將兩個字串連線成一個新的字串\n"); printf("\t\t\t0 退出系統\n"
); printf("\t\t***************順序棧實現*********************\n"); } //初始化字串 Status StrAssign(HString &T,char * chars) { int len=0; char *c; if(T.ch) free(T.ch); //len=(int)strlen(chars)-1; for(c = chars; *c; ++c) len++; if(!len) { T.ch=NULL; T.length=0; } else { if
(!(T.ch=(char *)malloc(len*sizeof(char)))) exit(OVERFLOW); for(int j=0;j<len;j++) { T.ch[j]=chars[j]; } T.length=len; } return OK; } //清空函式 Status ClearString(HString &S) { if(S.ch) { free(S.ch); S.ch=NULL; } S.length=0; return OK; } //求長度 int StrLength(HString S) { return S.length; } //求子串(第pos個位置,長度為len的子串,SubS拿來裝子串) Status SubString(HString S,HString &SubS,int pos,int len) { if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1) return ERROR; if(SubS.ch) free(SubS.ch); if(len==0) { SubS.ch=NULL; SubS.length=0; } else { SubS.ch=(char*)malloc(len*sizeof(char)); for(int i=0;i<len;i++) { SubS.ch[i]=S.ch[pos-1]; pos++; } SubS.length=len; } return OK; } /*比較也可以寫成這個(避免我的警告) //功能:對2個字串str1和str2逐一進行比較,如果對應位置相等, // 繼續比較下一個字元,否則返回對應位置字元的ASCII的差值 int StrCompare(HString str1, HString str2) { int i; for(i = 0;(i < str1.length && i < str2.length); i++) //2個字串存在從第一個開始的若干相等字串,則比較 { if(str1.str[i]!=str2.str[i]) return(str1.str[i] - str2.str[i]); } return (str1.length-str2.length); //當上面比較完都沒發現不同字元時,此時比較串長 } */ //比較兩個字串的大小(應該可以優化) int StrCompare(HString S,HString H) { int time; time=0; if(S.length>H.length) return BIG; if(S.length<H.length) return LITTLE; if(S.length==H.length) { for(int i=0;i<S.length;i++) { if(S.ch[i]>H.ch[i]) return BIG; if(S.ch[i]<H.ch[i]) return LITTLE; if(S.ch[i]==H.ch[i]) time++; } if(time==S.length) return EQUAL; } } //求一個字串在主串中的位置(要引用上面求子串的函式,書上用pos的意義是從第幾個位置起(有多個擷取後相等情況時) int SubStringLocation(HString S,HString T) { int i=0; HString SubS;//用來擷取的子串串 SubS.ch=NULL; SubS.length=0; while(i<S.length-T.length+1)//擷取位置起的後面一截 { SubString(S,SubS,i,T.length); //這裡注意3個串別寫混了 if(StrCompare(T,SubS)!=EQUAL) { i++; if(i==S.length-T.length+1-1) //防止123456aaafffg fffffff return ERROR; } else return i; //如果有多個子串,存入陣列中輸出陣列即可 } } //連線兩個字串為一個字串 Status StringCat(HString &T,HString S,HString S2) { if(T.ch) free(T.ch); if(!(T.ch=(char *)malloc((S.length+S2.length)*sizeof(char)))) exit(OVERFLOW); for(int i=0;i<S.length;i++) { T.ch[i]=S.ch[i]; } T.length=S.length+S2.length; for( i=S.length;i<T.length;i++) { T.ch[i]=S2.ch[i-S.length];//注意別寫漏掉i-S.length } return OK; } int main() { int choice,pos=0,len=0; HString S,T,Str; S.ch=NULL; S.length=0; T.ch=NULL; //注意必須先初始化,不然沒有值輸出 T.length=0;//注意必須先初始化 Str.ch=NULL; Str.length=0; char s[100],s1[100]; while(1) { menu(); printf("請輸入要選擇的功能:\n"); scanf("%d",&choice); switch(choice) { case 1: { printf("請輸入一個字串:\n"); scanf("%s",s); if(StrAssign(T,s)) printf("字串長度為:%d\n",StrLength(T)); printf("請按回車繼續!\n"); getchar();getchar(); system("cls");break; } case 2: { printf("請輸入主串:\n"); scanf("%s",s); if(StrAssign(S,s)) { printf("請輸入提取子串的位置pos,以及長度len:"); scanf("%d%d",&pos,&len); ClearString(T);//注意釋放,防止再次輸入 if(SubString(S,T,pos,len)==OK) //這裡為什麼要寫OK才行? { for(int i=0;i<T.length;i++) { printf("%c",*(T.ch+i));//指標 } printf("\n"); } else printf("輸入的位置或長度有誤!\n"); } printf("請按回車繼續!\n"); getchar();getchar(); system("cls");break; } case 3: { printf("請輸入兩個字串s和s1:\n"); scanf("%s%s",s,s1); if(StrAssign(S,s) && StrAssign(T,s1)) { if(StrCompare(S,T)==BIG) printf("字串s:%s更大",s); if(StrCompare(S,T)==EQUAL) printf("字串s:%s與字串s1: %s相等",s,s1); if(StrCompare(S,T)==LITTLE) printf("字串s1:%s更大",s1); } printf("請按回車繼續:\n"); getchar();getchar(); system("cls");break; } case 4: { printf("請輸入主串s:\n"); scanf("%s",s); if(StrAssign(S,s)) { printf("請輸入字串s1:\n"); scanf("%s",s1); if(StrAssign(T,s1)) { if(SubStringLocation(S,T)!=ERROR) printf("子串s1在主串s中按從左往右計數的位置(只計算出第相同子串一個位置)為:%d\n",SubStringLocation(S,T)); else printf("主串中沒有該子串!\n"); } } printf("請按回車繼續!\n"); getchar();getchar(); system("cls");break; } case 5: { printf("請輸入第一個字串s:\n"); scanf("%s",s); if(StrAssign(S,s)) { printf("請輸入第二個字串s1:\n"); scanf("%s",s1); if(StrAssign(T,s1)) { if(StringCat(Str,S,T)) { for(int i=0;i<Str.length;i++) printf("%c",*(Str.ch+i)); } printf("\n"); } } printf("請按回車繼續!\n"); getchar();getchar(); system("cls");break; } case 0:printf("成功退出系統!\n");exit(0);break; default:printf("輸入有誤!\n");exit(0);break; } } return 0; }

綜合程式是需要不斷改進的,下面說說我遇到的問題吧:
1.在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

這以上3中常見串問題 大家需要注意。
程式碼中大多數註釋都有,若有錯誤望大家不吝指教,祝大家程式設計愉快,謝謝!。