Data structure (C implementation) ------- string
A string (string for short) can be considered as a special linear table. Its particularity lies in that the data element type of a linear table is always character-like, and the string data object red bean is a character set.
A string is a finite sequence consisting of 0 or more characters. It is generally recorded as: s = "s1 s2 s3 .... sn ", where, s is the string name, the Character Sequence enclosed in double quotation marks is called the string value, si (1 <= I <= n) is called the string element, it can be letters, numbers, or other characters. It is the basic unit of a string. The number of characters n is the length of a string.
Several terms in the string:
1. Empty string: A string composed of 0 characters is called an empty string. The empty string does not contain any character and its length is 0.
2. substring: a substring consisting of any consecutive characters in a string is called a substring of the string. An empty string is a substring of any string.
3. Main string: The corresponding name of the string containing the child string.
4. the position of the substring in the main string: the sequence number of a character is the position of the character in the string, the position of a substring in the primary string is expressed by the position of the first character in the primary string.
5. Two strings are equal: they are equal only when the two strings are of the same length and the characters at each corresponding position are equal.
String Representation: 1. Sequential string storage representation:
The sequential storage structure of a string is short for sequential strings. character sequences in a sequential string are stored in a group of continuous storage units in sequence. There are three methods to implement sequential strings:
(1) Fixed Length character array
In the sequential string storage structure, assign a fixed size storage area for each defined string variable according to the predefined size, as described below:
// Long character array description # define MAXSIZE 100 typedef char SString [MAXSIZE];
(2) string-length character array
// String length character array # define MAXSIZE 100 typedef struct {char ch [MAXSIZE]; int length;} SqString;
(3) Heap allocation of strings (I .e. dynamic array) Storage description
// String Heap allocation storage description typedef struct {char * ch; // if it is a non-empty string, the storage area is allocated by string length; otherwise, ch is NULLint length; // String Length} HString;
2. Chain storage representation of strings:
Similar to the chain storage structure of a linear table, the chain table method can also be used to store string values. There are two methods:
(1) chain structure type description:
// String chain Storage Structure Description typedef struct node {char str; struct node * next;} CNode, * LinkString;
(2) blockchain storage type description:
// String structure type description # define NODESIZE 3 typedef struct node {char ch [NODESIZE]; struct node * next;} SNode, * LinkStr; LinkStr head;
3. String index storage representation:
The string can also be represented by an index. There are two methods:
(1) string index table with length:
// Index table with length # define MAXSIZE 100 typedef struct {char name [MAXSIZE]; int length; char * startadr;} LSNode;
(2) index table with the last pointer of the string:
// String index table with the last pointer # define MAXSIZE 100 typedef struct {char name [MAXSIZE]; int length; char * startadr; char * endadr;} ENode;
The above three storage structures are introduced to represent strings. Each storage structure can be described in several different ways. There are also many implementation methods for strings, however, no matter how many types of strings are available, the basic operating principle of strings remains unchanged, and only the processing method is changed. Therefore, there is no need to learn all the methods, here, the most commonly used dynamic array is used to describe the string, and various operations on the string are implemented in this way.
Basic operations:
All the basic operations here are based on the above dynamic array, that is, the Heap Structure to describe the string, and the code is directly given, which contains comments.
// String Heap allocation storage description typedef struct {char * ch; // if it is a non-empty string, the storage area is allocated by string length; otherwise, ch is NULLint length; // String length} HString; // Initialize an empty sequence string void Str_Init (HString * S) {S-> ch = NULL; S-> length = 0 ;} // clear the sequence string void Str_Clear (HString * S) {if (S-> ch) {free (S-> ch); Str_Init (S );}} // determine whether the sequence string is null int Str_IsEmpty (HString * S) {return S-> length = 0;} // obtain the length of the string int Str_GetLength (HString * S) {return S-> length;} // The value of the sequence string void Str_Assign (HString * S, char * chars) {int I = 0, J; char * c = chars; // first clear the sequence string S Str_Clear (S); // obtain the length of the value assignment string while (* c) {I ++; c ++;} // if the length of the value assignment string is greater than 0, assign the value if (I> 0) {S-> ch = (char *) malloc (3 * sizeof (char); for (j = 0; j <I; j ++) {S-> ch [j] = chars [j];} s-> length = I ;}// copy the sequence string. Copy T to Svoid Str_Copy (HString * S, HString * T) {int I; // first clear the sequence string S Str_Clear (S); S-> length = T-> length; if (S-> length) {S-> ch = (char *) malloc (sizeof (char) * S-> length); for (I = 0; I <S-> length; I ++) S-> ch [I] = T-> ch [I] ;}/// the sequential string connection. After T is connected to S, void Str_Concat (HString * S, HString * T) {// temporarily store the S string HString temp; int I, j; Str_Init (& temp); Str_Assign (& temp, S-> ch); // clear SStr_Clear (S ); // re-allocate space for S-> length = temp. length + T-> length; S-> ch = (char *) malloc (sizeof (char) * S-> length ); // assign temp and T to Sfor (I = 0; I <temp. length; I ++) S-> ch [I] = temp. ch [I]; for (j = 0; j <T-> length; j ++) S-> ch [I ++] = T-> ch [j]; // release temp (temp. ch);} // sequential string If S> T, return a value greater than 0, less than, then return a value less than 0 int Str_Compare (HString * S, HString * T) {int I; for (I = 0; 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 ;} // obtain the substring and use Sub to return void Str_GetSub (HString * S, int pos, int len, HString * Sub) {int I; // determine the validity of position and length if (pos <1 | pos> S-> length | len <0 | len> S-> length-pos + 1) {printf ("the position or length of the substring is invalid! \ N "); exit (-1);} else {Str_Clear (Sub); if (len) {Sub-> ch = (char *) malloc (len * sizeof (char); for (I = 0; I <len; I ++) sub-> ch [I] = S-> ch [pos + I-1]; Sub-> length = len ;}}} // locate the first position int Str_GetSubIndex (HString * S, HString * Sub, int pos) {int I, j; // first determine the validity of the position if (pos <1 | pos> S-> length) {printf ("The position is invalid! \ N "); exit (-1);} if (Str_IsEmpty (S) {printf (" the sequence string is empty! \ N "); return-1;} if (Str_IsEmpty (Sub) {printf (" null for the stator string, empty for any substring! \ N "); return 0 ;}for (I = pos-1; I <S-> length-Sub-> length + 1; I ++) {for (j = 0; j <Sub-> length; j ++) if (S-> ch [I + j]! = Sub-> ch [j]) break; // If a substring is found, j = sub-> lengthif (j = Sub-> length) return I + 1 ;} // if not found, return-1; return-1;} // Insert the substring void Str_Insert (HString * S, int pos, HString * T) in the sequence string) {int I; HString temp; if (pos <1 | pos> S-> length) {printf ("the location is invalid! \ N "); exit (-1);} if (Str_IsEmpty (T) {printf (" the substring is empty! \ N "); exit (0);} Str_Init (& temp); temp. length = S-> length + T-> length; printf ("% d \ n", temp. length); temp. ch = (char *) malloc (sizeof (char) * temp. length); for (I = 0; I <pos; I ++) temp. ch [I] = S-> ch [I]; for (; I <pos + T-> length; I ++) temp. ch [I] = T-> ch [I-pos]; for (; I <temp. length; I ++) temp. ch [I] = S-> ch [I-T-> length]; // clears string S and assigns the temp value to SStr_Clear (S ); s-> ch = temp. ch; S-> length = temp. length;} // Delete the substring void Str_D from the sequence string EleteSub (HString * S, int pos, int len) {int I; HString temp; // determine the validity of position and length if (pos <1 | pos> S-> length | len <0 | len> S-> length-pos + 1) {printf ("the position or length of the substring is invalid! \ N "); exit (-1);} if (Str_IsEmpty (S) {printf (" the sequence string is empty! \ N "); exit (0);} Str_Init (& temp); temp. length = S-> length-len; temp. ch = (char *) malloc (sizeof (char) * temp. length); for (I = 0; I <pos-1; I ++) temp. ch [I] = S-> ch [I]; for (; I <temp. length; I ++) temp. ch [I] = S-> ch [I + len]; // clears string S and assigns the temp value to SStr_Clear (S); S-> ch = temp. ch; S-> length = temp. length ;}// print the sequence string void Str_Print (HString * S) {int I = 0; if (Str_IsEmpty (S) {printf ("the sequence string is empty! \ N "); exit (0);} elseprintf (" % s \ n ", S-> ch );}