C Implementation of Dynamic String Array
We know that C ++ supports containers and supports a variety of data types, but C is not the same. C's data type support is really poor, re-encoding is required. For example, if you want to convert a dynamic array of the int type to a dynamic array of the string type, it will be very painful. Today, we use C to write a dynamic string array.
The main purpose is:
1. let's review the dynamic memory allocation method in C (mainly using malloc, realloc, and free). According to our understanding, the new essence in C ++ is malloc + construct, first allocate a piece of memory, and then place a new object on this piece of memory.
2. Try to understand the interface encapsulation design, pointer transmission, and pay attention to memory allocation and release.
Two problems encountered during encoding are recorded as follows:
1. error C2275 used this type as an invalid expression: the main reason is that C requires that the declaration of the variable be defined at the beginning of the field in the region. If it is written to the middle, an error is reported, and C ++ does not have this problem. 2. in the int StringInsertOneByPointer (StringArr * arr, const char * target, pStringNode pos) function, the realloc function modifies the pointer address. If the value of the Sentinel is not corrected in time, an error occurs.
The source code is released below:
Code writing is a bit rough, but the function is basically implemented, and there is still a lot of room for improvement. For example, when searching, we just traverse from start to end as the complexity of the O (n) algorithm, you can design a binary search algorithm O (logn) for the sorted Sequence Based on whether it is sorted or not ).
Similarly, in the sorting section, we simply use the Bubble sorting algorithm. The complexity is O (n ^ 2). You can use the fast sorting O (nlogn) instead ), of course, when the data volume is small, the effect is not obvious. In the case of big data, we can see the difference.
// =================================== [String Array] ================ ========/// @ author: zhyh2010 // @ date: 20150601 // @ version: 1.0 // @ description: implements an array encapsulation of a string to add, delete, insert, modify, sort // =================================[ String Array] ================ ========# include
# Include
# Include
# Include # define SUCCESS 0 # define INPUT_ERROR-1 # define MALLOC_ERROR-2 # define NOT_FIND NULLtypedef struct _ StringNode {int length; char * pStr;} StringNode, * pStringNode; typedef struct _ StringArr {StringNode * pHead; int length; int capacity;} StringArr, * pStringArr; // ====================================== add ===================== ========== int StringAddOne (StringArr * arr, const char * source); // ======================== Delete ===================================int StringDeleteOne (StringArr * arr, const char * target ); // ====================================== search ======================= ========= pStringNode StringSearchFirst (StringArr * arr, const char * target ); // ====================================== insert ====================== ========= int StringInsertOneByPointer (StringArr * arr, const char * target, pStringNode pos); int StringInsertByStr (StringArr * arr, const cha R * target, const char * PosPointer); int StringInsertByID (StringArr * arr, const char * target, int id ); // ======================================= modify ==================== =========== int StringModify (StringArr * arr, const char * target, const char * source ); // =======================================sort ===================== ============ int StringSort (StringArr * arr, int seq ); // ====================================== create ==================== ========= pString Arr StringCreate (); // ==================================== destroy ===================== ======= void StringDestroy (pStringArr parr ); // ================================== test case ======================= ===== void main () {pStringArr pArr = StringCreate (); int ret =-1; pStringNode pres = NOT_FIND; // ================ insert =================== ret = StringInsertByID (pArr, "love ", 10); ret = StringInsertByID (pArr, "new", 0); ret = StringInsertByStr (pAr R, "hi", "love"); ret = StringInsertByStr (pArr, "ho", "new"); ret = StringInsertByStr (pArr, "hi ", "zhyh201012"); ret = StringInsertByStr (pArr, "ho", "ll12 "); // =============== add one =================== ret = StringAddOne (pArr, "hello world"); ret = StringAddOne (pArr, "zhyh2010"); ret = StringAddOne (pArr, "zh"); ret = StringAddOne (pArr, "hihocoder "); ret = StringAddOne (pArr, "ustc"); ret = StringAddOne (PArr, "china"); ret = StringAddOne (pArr, "jp "); // ============ search first ============ pres = StringSearchFirst (pArr, "zhyh2010 "); pres = StringSearchFirst (pArr, "zhy "); // =========== deleteone ================= ret = StringDeleteOne (pArr, "hy "); ret = StringDeleteOne (pArr, "ustc"); ret = StringDeleteOne (pArr, "jp "); // ============= modify ============================= ret = StringModify (pArr, & quot; 123 & quot;, & quot; asldf & quot;); re T = StringModify (pArr, "zhyh2010", "zhyh2010 @ ustc "); // ================ insert =================== ret = StringInsertByID (pArr, "love ", 10); ret = StringInsertByStr (pArr, "ho", "china"); ret = StringInsertByStr (pArr, "hi12", "china"); ret = StringInsertByStr (pArr, "ho2", "china"); ret = StringInsertByStr (pArr, "h3i", "china"); ret = StringInsertByStr (pArr, "h2o", "china "); // ============== sort ========== ============= Ret = StringSort (pArr, 0 ); // ============= destroy ======================== StringDestroy (pArr );} // ====================================== add ===================== ========== int StringAddOne (StringArr * arr, const char * source) {if (arr = NULL | source = NULL) return INPUT_ERROR; // alloc memory if (arr-> capacity <= arr-> length) {if (arr-> pHead = NULL) {// alloc space when phead = NULL pStringNode pNode = (p StringNode) malloc (sizeof (StringNode); if (pNode = NULL) return MALLOC_ERROR; arr-> pHead = pNode; arr-> capacity + = 1 ;} else {// realloc space pStringNode pNode = (pStringNode) realloc (arr-> pHead, sizeof (StringNode) * 2 * arr-> capacity); if (pNode = NULL) return MALLOC_ERROR; arr-> pHead = pNode; arr-> capacity = 2 * arr-> capacity;} int source_len = strlen (source); char * tmp = (char *) malloc (si Zeof (char) * (source_len + 1); if (tmp = NULL) return MALLOC_ERROR; // pStringNode pNode = arr-> pHead + arr-> length; // c2275 C does not allow variable declaration in the middle // StringNode * pNode = & (arr-> pHead) [arr-> length]; arr-> pHead [arr-> length]. length = source_len + 1; arr-> pHead [arr-> length]. pStr = tmp; strcpy (arr-> pHead [arr-> length]. pStr, source); arr-> length + = 1; return SUCCESS ;} // ====================================== delete ====================== ========== Int StringDeleteOne (StringArr * arr, const char * target) {pStringNode pres = (pStringNode) NOT_FIND; if (arr = NULL | target = NULL) return INPUT_ERROR; pres = StringSearchFirst (arr, target); if (pres = (pStringNode) NOT_FIND) return (int) NOT_FIND; free (pres-> pStr); for (; pres! = Arr-> pHead + arr-> length-1; pres ++) * pres = * (pres + 1); pres-> length = 0; pres-> pStr = NULL; arr-> length-= 1; return SUCCESS ;} // ====================================== search ======================= ========= pStringNode StringSearchFirst (StringArr * arr, const char * target) {pStringNode pres = (pStringNode) NOT_FIND; if (arr = NULL | target = NULL) return (pStringNode) INPUT_ERROR; // pStringNode pres = NOT_FIND; for (Int I = 0; I! = Arr-> length; I ++) {if (strcmp (target, arr-> pHead [I]. pStr) = 0) {pres = & arr-> pHead [I]; break;} return pres ;} // ====================================== insert ====================== ========= int StringInsertOneByPointer (StringArr * arr, const char * target, pStringNode pos) {char * tmp = NULL; pStringNode pOld = NOT_FIND; if (arr = NULL | target = NULL | pos = NULL) return INPUT_ERROR; // assert (arr-> capacity = 0); assert (arr-> capacity> 0); if (arr-> capacity <= arr-> length) {pOld = arr-> pHead; arr-> pHead = (pStringNode) realloc (arr-> pHead, sizeof (StringNode) * 2 * arr-> capacity); arr-> capacity = 2 * arr-> capacity; // modify the boundary pos + = arr-> pHead-pOld;} // insert (prefix) tmp = (char *) malloc (sizeof (char) at the position pointed to by the pointer) * (strlen (target) + 1); if (tmp = NULL) return MALLOC_ERROR; for (pStringNode pres = arr-> pHead + arr-> Length-1; pres! = Pos-1; pres --) * (pres + 1) = * pres; pos-> pStr = tmp; strcpy (pos-> pStr, target ); pos-> length = strlen (target) + 1; arr-> length + = 1; return SUCCESS;} int StringInsertByStr (StringArr * arr, const char * target, const char * PosPointer) {pStringNode pres = NOT_FIND; if (arr = NULL | target = NULL | PosPointer = NULL) return INPUT_ERROR; pres = StringSearchFirst (arr, posPointer); return StringI NsertOneByPointer (arr, target, pres);} // id starts from 0 and calculates int StringInsertByID (StringArr * arr, const char * target, int id) {pStringNode pres = NOT_FIND; if (arr = NULL | target = NULL) return INPUT_ERROR; if (id <0) id = 0; if (id> arr-> length) id = arr-> length; if (arr-> length = 0) return StringAddOne (arr, target); pres = arr-> pHead + id; return StringInsertOneByPointer (arr, target, pres);} // = ==================================== Modify ======================== ======= int StringModify (StringArr * arr, const char * target, const char * source) {pStringNode pres = NOT_FIND; pStringNode tmp = NOT_FIND; if (arr = NULL | target = NULL | source = NULL) return INPUT_ERROR; pres = StringSearchFirst (arr, target); if (pres = NULL) return (int) NOT_FIND; tmp = (pStringNode) malloc (sizeof (char) * (strlen (source) + 1) ); If (tmp = NULL) return MALLOC_ERROR; free (pres-> pStr); pres-> pStr = tmp; pres-> length = strlen (source) + 1; strcpy (pres-> pStr, source); return SUCCESS ;} // =======================================sort ===================== ============ int StringSort (StringArr * arr, int seq) {StringNode tmp; if (arr = NULL) return INPUT_ERROR; if (arr-> pHead = NULL | arr-> length = 1) return SUCCESS; # define MAX2MIN 1 # define MIN2MAX 0 seq = (seq> 0 )? MAX2MIN: MIN2MAX; if (seq = MIN2MAX) {// sort by bubble (int I = 0; I! = Arr-> length-1; I ++) {for (int j = 0; j! = Arr-> length-1-I; j ++) {if (strcmp (arr-> pHead [j]. pStr, arr-> pHead [j + 1]. pStr)> 0) {tmp = arr-> pHead [j + 1]; arr-> pHead [j + 1] = arr-> pHead [j]; arr-> pHead [j] = tmp ;}}} else {for (int I = 0; I! = Arr-> length-1; I ++) {for (int j = 0; j! = Arr-> length-1-I; j ++) {if (strcmp (arr-> pHead [j]. pStr, arr-> pHead [j + 1]. pStr) <0) {tmp = arr-> pHead [j + 1]; arr-> pHead [j + 1] = arr-> pHead [j]; arr-> pHead [j] = tmp ;}}return SUCCESS ;} // ====================================== create ==================== ========= pStringArr StringCreate () {pStringArr parr = (pStringArr) malloc (sizeof (StringArr); if (parr = NULL) return parr; parr-> capacity = 0; parr-> length = 0; parr-> pHead = NULL; return parr ;} // ==================================== destroy ===================== ======= void StringDestroy (pStringArr parr) {if (parr = NULL) return; while (parr-> length! = 0) {if (parr-> pHead [parr-> length-1]. pStr! = NULL) {free (parr-> pHead [parr-> length-1]. pStr); parr-> pHead [parr-> length-1]. length = 0; parr-> length -- ;}} if (parr-> pHead! = NULL) free (parr-> pHead); free (parr );}