我们知道C++是支持容器的, 对于各种数据类型都能有很好的支持,但是C不一样, C的数据类型支持真的很差,一旦换一种类型,又得重新编码,比如从int型的动态数组 转到string类型的动态数组,会发现这是件非常痛苦的事情。今天手贱,用C实现一下字符串动态数组的编写。
主要目的是:
1. 回顾一下,C中的动态内存分配方法,(主要就是malloc, realloc, free的使用), 按照我们的理解C++中的 new 本质也就是 malloc + construct, 先分配一片内存, 然后在这片内存上placement new 一个对象。
2. 体会一下接口的封装设计,指针的传递, 注意内存的分配和释放。
编码过程中遇到的两个问题,记录如下:
1.error C2275 将此类型用作表达式非法:
主要原因, C中要求变量的声明定义在区域的段首,若写到中间会报错, 而C++不存在这个问题
2. int StringInsertOneByPointer(StringArr * arr, const char * target, pStringNode pos)
函数中由于realloc函数会对指针地址修改, 若此时没有及时修正哨兵的值, 会存在错误。
下面放出源代码:
代码写的有些粗糙, 只是基本实现了功能, 还有很大的改进空间,比如搜索的时候, 我们只是从头到尾进行遍历 是O(n)的算法复杂度, 可以根据是否已经排序,设计出针对已经排序后序列的二分查找算法 O(logn)。
同样的,排序那段,我们只是简单的使用冒泡排序算法, 复杂度为 O(n^2), 可以改用快速排序 O(nlogn), 当然这些在数据量小的时候,效果不明显, 在大数据情况下,就可以看出差别了。
// =====================【字符串的数组】==================
// @ author : zhyh2010
// @ date : 20150601
// @ version : 1.0
// @ description : 实现一个字符串的数组封装,实现增加,删除,插入,修改,排序
// =====================【字符串的数组】==================
#include
#include
#include
#include
#define SUCCESS 0 #define INPUT_ERROR -1 #define MALLOC_ERROR -2 #define NOT_FIND NULL typedef 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 char * 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 ======================== pStringArr StringCreate(); // ===================== destroy ======================= void StringDestroy(pStringArr parr); // ==================== 测试用例 ====================== 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(pArr, "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 = Strin