串是非常重要的,比如搜索引擎对用户输入内容的匹配等等都用到有关串的知识,下面先给出串的C语言算法说明,最后给出C++封装好的例子。
C语言算法说明
定义串的数据类型
const int MAX_N = 100; //串的数据类型 struct SqString { //数据 char data[MAX_N]; //串长 int length; };生成串
//生成串s,cstr[]字符数组有外部传入 void StrAssign(SqString s, char cstr[]){ int i; for (i = 0; cstr[i] != '\0'; i++){ s.data[i] = cstr[i]; } s.length = i; }
//复制串,将串t赋值给串s void StrCopy(SqString &s, SqString t){ int i; //串内容按字符逐个赋值 for (i = 0; i < t.length; i++){ s.data[i] = t.data[i]; } //复制串长 s.length = t.length; }
//判断两个串是否相等 bool isEqual(SqString s, SqString t){ //长度是否相等 if (s.length != t.length){ return false; } //内容是否相等 else{ int i; for (i = 0; i < s.length; i++){ //不等则返回false,结束 if (s.data[i] != t.data[i]){ return false; } } //否则相等 return true; } }求串长度
//求串长度 int StrLength(SqString s){ return s.length; }
//串连接,将串s和串t连接,生成新串str,串str为局部变量 SqString Concat(SqString s, SqString t){ SqString str; //新串长度 str.length = s.length + t.length; int i; //赋值第一个串s给串str for (i = 0; i < s.length; i++){ str.data[i] = s.data[i]; } //赋值第二个串t给串str for (i = 0; i < t.length; i++){ str.data[s.length + i] = t.data[i]; } return str; }
求子串,从位置i开始的连续j个字符,生成新串并返回,若串首地址,若参数错误则返回空串
//求子串,从第i个位置开始的j个字符 SqString SubStr(SqString s, int i, int j){ SqString str; str.length = 0; //下标起始点与位置起始点差1,j==0时生成空串,j<=时无实际意义 if (i <= 0 || i>s.length || j <= 0 || i + j - 1 < s.length){ return str; } else{ int k; //连续赋值生成新串 for (k = i - 1; k < i + j - 1; k++){ str.data[k - (i - 1)] = s.data[k]; } //串长 str.length = j; return str; } }插入串,生成新串并返回串首地址,若参数不正确则生成空串
//插入串,将串s2插入到串s1的第i个位置开始后的N个字符,返回新串 SqString InsertStr(SqString s1, int i, SqString s2){ int j; SqString str; str.length = 0; //参数不正确时返回空串 if (i <= 0 || i > s1.length+1){ return str; } //s1前i个元素赋值给str for (j = 0; j < i - 1; j++){ str.data[j] = s1.data[j]; } //s2赋值给str for (j = i - 1; j < s2.length; j++){ str.data[j] = s2.data[j]; } //s1剩下的所有元素赋值给str for (j = s2.length + i - 1; j < s1.length; j++){ str.data[j] = s1.data[j]; } str.length = s1.length + s2.length; return str; }删除串从位置i开始的连续j个字符,并生成新串,若参数不正确则返回空串
//删除从第i位置开始的j长度的字符串,返回串,参数不正确的时候返回空串 SqString DeleteStr(SqString s, int i, int j){ SqString str; str.length = 0; if (i <= 0 || i>s.length || j <= 0 || i + j - 1 > s.length){ return str; } else{ int k; //赋值前i-1个字符 for (k = 0; i < i - 1; k++){ str.data[k] = s.data[k]; } //跳过中间j个子字符,赋值其后剩下的字符 for (k = i + j - 1; k < s.length; k++){ str.data[k-j] = s.data[k]; } str.length = s.length - j; return str; } }串替换,若参数不正确返回空串,否则生成新串并返回串首地址
//替换一段字符串,将s中第i个位置开始后j个字符替换成串t,返回新串,参数不正确时返回空串 SqString ReplaceStr(SqString s, int i, int j, SqString t){ //被替换的字符串长度和t串长度不一定相等 SqString str; str.length = 0; if (i <= 0 || i > s.length || j<0 || j>s.length - i + 1){ return str; } else{ int k; //赋值前i个元素 for (k = 0; k < i - 1; k++){ str.data[k] = s.data[k]; } //插入t串 for (k = 0; k < t.length; k++){ str.data[k + i - 1] = t.data[k]; } //赋值s串中跳过j个字符串,剩下的串 for (k = i+j - 1; k < s.length; k++){ str.data[t.length + (i - 1) + (k - (i + j - 1))] = s.data[k]; } str.length = s.length - j + t.length; return str; } }
//输出串 void DisplayStr(SqString s){ int i; //空串处理 if (s.length == 0){ cout << "Empty." << endl; } //否则输出串 else{ for (i = 0; i < s.length; i++){ cout << s.data[i]; } cout << endl; } }
/* 顺序串的实现C++ */ #include<iostream> using namespace std; const int MAX_N = 100; //定义数据类型 class SqStr { public: char data[MAX_N]; int length; }; //串 class String { public: String(){} ~String(){} //生成串 void StrAssign(char cstr[]){ int i; for (i = 0; cstr[i] != '\0'; i++){ S.data[i] = cstr[i]; } S.length = i; } //复制串 void StrCopy(String t){ int i; //串赋值 for (i = 0; i < t.GetS()->length; i++){ S.data[i] = t.GetS()->data[i]; } //串长度赋值 S.length = t.GetS()->length; } //是否相等 bool StrEqual(String t){ //长度不等 if (S.length != t.GetS()->length){ return false; } else{ int i; for (i = 0; i < S.length; i++){ //内容不等 if (S.data[i] != t.GetS()->data[i]){ return false; } } //否则相等 return true; } } //求长度 int STrLength(){ return S.length; } //串连接 SqStr Concat(String t){ SqStr str; str.length = S.length + t.GetS()->length; int i; //赋值S for (i = 0; i < S.length; i++){ str.data[i] = S.data[i]; } //赋值t for (i = S.length; i < S.length + t.GetS()->length; i++){ str.data[i] = t.GetS()->data[i - S.length]; } return str; } //求子串,返回从S串的位置i开始连续j个字符,返回新串,参数不正确时返回空串 SqStr SubStr(int i, int j){ SqStr str; str.length = 0; //下标与位置差1 if (i <= 0 || i>S.length || j <= 0 || i + j - 1 > S.length){ return str; } else{ int k; for (k = i - 1; k < i + j - 1; k++){ str.data[k-(i-1)] = S.data[k]; } str.length = j; return str; } } //插入串,将s1插入到S中的位置i开始,返回新串,参数不正确时返回空串 SqStr InsertStr(String s1, int i){ SqStr str; str.length = 0; //i 为位置,与数组下标差1 if (i <= 0 || i > S.length + 1){ return str; } else{ int j; //插入S前i-1个字符 for (j = 0; j < i - 1; j++){ str.data[j] = S.data[j]; } //插入串s1 for (j = 0; j < s1.GetS()->length; j++){ str.data[j + i - 1] = s1.GetS()->data[j]; } //插入剩下的S串 for (j = i - 1; j < S.length; j++){ str.data[(i - 1) + s1.GetS()->length + (j - (i - 1))] = S.data[j]; } str.length = S.length + s1.GetS()->length; return str; } } //删除S串中位置i开始的连续j个字符,生成新串并返回,参数不正确时返回空串 SqStr DeleteStr(int i, int j){ SqStr str; str.length = 0; //j<0无意义,不删除任何字符,j==0即删除0个字符串,仍为空串 if (i <= 0 || i > S.length || j <= 0 || i + j - 1 > S.length){ return str; } else{ int k; //赋值S前i-1个字符 for (k = 0; k < i - 1; k++){ str.data[k] = S.data[k]; } //跳过j个字符,赋值剩下的字符 for (k = i - 1 + j; k < S.length; k++){ str.data[k - j] = S.data[k]; } str.length = S.length - j; return str; } } //替换串,将S中的位置i开始的j个字符替换成串t,生成新串并返回,参数不正确返回空串 SqStr ReplaceStr(int i, int j, String t){ SqStr str; str.length = 0; //j<0没有实际意义,j==0,即将i-1后的0个字符替换 if (i <= 0 || i > S.length || j<0 || i + j - 1>S.length){ return str; } else{ int k; //赋值S的前i-1个字符 for (k = 0; k < i - 1; k++){ str.data[k] = S.data[k]; } //插入t串 for (k = 0; k < t.GetS()->length; k++){ str.data[i - 1 + k] = t.GetS()->data[k]; } //S串跳过j个字符后插入剩下所有 for (k = i - 1 + j; k < S.length; k++){ str.data[(i - 1) + t.GetS()->length + (k - (i - 1 + j))] = S.data[k]; } str.length = S.length - j + t.GetS()->length; return str; } } //输出串(不带参数) void DisplayStr(){ //空串处理 if (S.length == 0){ cout << "Empty." << endl; } //否则输出串 else{ int i; for (i = 0; i < S.length; i++){ cout << S.data[i]; } cout << endl; } } //输出串(带参数) void DisplayStr(SqStr str){ if (str.length == 0){ cout << "Empty." << endl; } else{ int i; for (i = 0; i < str.length; i++){ cout << str.data[i]; } cout << endl; } } private: SqStr S; //获取串首地址 SqStr * GetS(){ return &S; } }; int main() { int n, i, locate, strlength; char a[MAX_N]; //生成串 cout << "Create String." << endl; cout << "Input n:"; cin >> n; cout << "Input " << n << " characters." << endl; for (i = 0; i < n; i++){ cin >> a[i]; } a[i] = '\0'; String str1; str1.StrAssign(a); //输出串 cout << "Dispaly string." << endl; str1.DisplayStr(); //串长度 cout << "String Length." << endl; cout << str1.STrLength() << endl; //拷贝串 cout << "String Copy." << endl; cout << "Input n:"; cin >> n; cout << "Input " << n << " characters." << endl; for (i = 0; i < n; i++){ cin >> a[i]; } a[i] = '\0'; String str2; str2.StrAssign(a); str1.StrCopy(str2); str1.DisplayStr(); //获取子串 cout << "Get SubStr." << endl; cout << "Input locate, string length:"; cin >> locate >> strlength; str1.DisplayStr(str1.SubStr(locate, strlength)); //插入串 cout << "Insert string." << endl; cout << "Input n:"; cin >> n; cout << "Input " << n << " characters." << endl; for (i = 0; i < n; i++){ cin >> a[i]; } a[i] = '\0'; str2.StrAssign(a); cout << "Input locate:"; cin >> locate; str1.DisplayStr(str1.InsertStr(str2, locate)); //连接串 cout << "Concat string." << endl; cout << "Input n:"; cin >> n; cout << "Input " << n << " characters." << endl; for (i = 0; i < n; i++){ cin >> a[i]; } a[i] = '\0'; str2.StrAssign(a); str1.DisplayStr(str1.Concat(str2)); //是否相等 cout << "Is Equal." << endl; if (str1.StrEqual(str2)){ cout << "YES." << endl; } else{ cout << "NO." << endl; } //删除串 cout << "Delete." << endl; cout << "Input locate, string length:"; cin >> locate >> strlength; str1.DisplayStr(str1.DeleteStr(locate,strlength)); //替换串 cout << "Repalce." << endl; cout << "Input locate, string length:"; cin >> locate >> strlength; str1.DisplayStr(str1.ReplaceStr(locate, strlength, str2)); return 0; }