启迪思维:字符串(1)

一:概念

字符串是几乎在所有编程语言中可以实现的非常重要和有用的数据类型,尽管形式字符串可以有任意(但有限)的长度,实际语言的字符串的长度经常被限制到一个人工极大值。一般的说,有两种类型的字符串数据类型:“定长字符串”,它有固定的极大长度并且不管是否达到了这个极大值都使用同样数量的内存;和“变长字符串”,它的长度不是专断固定的并且依赖于实际的大小使用可变数量的内存。现在编程语言中的多数字符串是变长字符串,变成字符串对内存分配策略要求很高。

二:表示法

 一种常用的表示法是使用一个字符代码的数组,下图仅仅为了更好理解字符串,实际字符串在内存不是这样结构(一般用ASCII表示,它的长度可以使用一个结束符(一般是NUL,ASCII代码是0,在C编程语言中使用这种方法)。或者在前面加入一个整数值来表示它的长度),如下图

三:各种语言中实现

C:没有字符串这个数据类型,而是使用字符数组来保存字符串;

C++:为解决C中处理字符串一些不足(心内存是否足够、字符串长度等等)C++提供string类;

Java:提供一个不可变的String(final)类;

四:代码分析(C++)

(1)符串中作为一种基本数据类型,用到的非常频繁(截取、复制、查找)字符串是各类书籍里边讲20/80原则中20,所有各种语言对字符串实现都非常高效

(2)复制作为替换、构造、追加、底层实现,各个语言对复制操作都是调用系统的方法,比如java处理字符串复制也用

(public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length));

1、构造函数 

 1 //申明空字符串变量时候初始化变量
 2 //1、在实际开发工作,最好能做到变量申明时就做初始化工作,
 3 //如果先申明空字符串变量、在赋值,相当于多一次赋值工作
 4 UString::UString():ch(0),lenght(0) {
 5 }
 6 
 7 //字符串数组做初始化变量
 8 UString::UString(const char* str) {
 9     //这是一个inline的函数,更多inline的知识请点击链接
10     StrCpChar(str,strlen(str));
11 }
12 //字符串数组做初始化变量,
13 UString::UString(const char* str,const size_t &len) {
14     //这是一个inline的函数,更多inline的知识请点击链接
15     StrCpChar(str,len);
16 }
2、析构字符串
 1 //析构函数
 2 UString::~UString() {
 3     Clear();
 4 }
 5 /**
 6  *清空字符串,并且回收内存
 7  */
 8 void UString::Clear(){
 9 
10     if(ch != 0){
11         //删除字符串并释内存,这样做很危险
12         delete[] ch;
13         ch = 0;
14     }
15 
16     length = 0;
17 }
18 /**
19  * 判断字符串是否为空
20  */
21 bool UString::IsEmpty()const{
22     return length == 0;
23 }

3、插入字符串 

 1 /**
 2  * 在字符串指定位置插入新的字符串(仅仅为更深入学习字符串,在实际中仅作为Replace底层实现)
 3  * @param s 准备插入的字符串
 4  * @param pos 开始位置
 5  * @return ture表示插入成功,false插入失败
 6  */
 7 void UString::StrInsert(const size_t &pos,const UString &s){
 8     const char *msg = "";
 9     if(pos < 0){
10         msg = "UString index out of range:";
11     }
12     if(pos > length){
13         msg = "UString index out of range:";
14     }
15     if(msg != ""){
16         std::__throw_out_of_range(__N(msg));
17     }
18 
19     //计算原字符串和新插入字符串长度
20     size_t len = s.length + length;
21     char *p = new char[len];
22 
23     //插入原字符串pos前的字符串到新空间
24     for(size_t i = 0; i < pos; ++i){
25         p[i] = ch[i];
26     }
27 
28     //插入目标字符串到新空间
29     for(size_t i = 0; i < s.length; ++i){
30         p[pos + i] = s.ch[i];
31     }
32 
33     //插入原字符串pos后面的字符串到新空间
34     for(size_t i = pos; i < length; i++){
35         p[i + s.length] = ch[i];
36     }
37 
38     //删除原字符串并释放内存(很危险)
39     delete[] ch;
40 
41     //设置新拼接的字符串
42     ch = p;
43     length = len;
44 
45 }

插入字符串过程如下图:

4、删除字符串 

 1 /**
 2  * 从指定的位置删除指定长度字符串(仅仅为更深入学习字符串,在实际中仅作为Replace底层实现)
 3  * @param pos 开始位置
 4  * @param len 字符串长度
 5  * @return ture表示插入成功,false插入失败
 6  */
 7 void UString::StrDelete(const size_t &pos,const size_t &len){
 8 
 9     const char *msg = "";
10     if(pos < 0){
11         msg = "UString index out of range:";
12     }
13     if(pos > length){
14         msg = "UString index out of range:";
15     }
16     if(len < 0){
17         msg = "UString index out of range:";
18     }
19     if(length-pos < len){
20         msg = "UString index out of range:";
21     }
22 
23     if(msg != ""){
24         std::__throw_out_of_range(__N(msg));
25     }
26 
27     size_t i = 0;
28     char *p = new char[length - len];
29 
30     //插入原字符串pos前的字符串到新空间
31     for(i = 0; i < pos; ++i){
32         p[i] = ch[i];
33     }
34 
35     //插入原字符串pos后面的字符串到新空间
36     for(i = pos; i < length-len; ++i){
37         p[i] = ch[i + len];
38     }
39 
40     //删除原字符串并释放内存(很危险)
41     delete[] ch;//Clear();
42 
43     //字符串长度
44     ch = p;
45     length = length - len;
46 
47 }

5、替换字符串; 

/**
 * 替换字符串(1、查找原字符串;2、删除原字符串;3、插入新字符串)
 * @param oldStr 原字符串
 * @param newStr 新字符串
 */
void UString::Replace(const UString &oldStr,const UString &newStr){

    size_t i = 0;
    //处理一个字符串中有多个相同oldStr
    while(i != -1){

        //查找原字符串
        i = IndexOf(oldStr,i);
        if(i != -1){
            //删除原字符串
            StrDelete(i,oldStr.length);
            //插入新字符串
            StrInsert(i,newStr);
            //改变i值查询一个oldStr字符串
            i = i + oldStr.length;
        }

    }

}

6、追加字符串 

 1 /**
 2  * 给目标字符串追加字符串
 3  * @param s 需要追加字符串
 4  */
 5 void UString::StrAppend(const UString &s){
 6 
 7     //重新计算字符串长度
 8     size_t len  = length + s.length;
 9 
10     //申请新空间
11     char *p =  new char[len];
12 
13     //复制老空间的数据到新生产的空间里
14     for(size_t i = 0; i < length; i++){
15         p[i] = ch[i];
16     }
17 
18     //把需要追加的字符串追加新空间里
19     for(size_t i = 0; i < s.length; i++){
20         p[i + length] = s.ch[i];
21     }
22     //删除老数据并释放内存,这样做很危险
23     delete[] ch;
24     ch = p;
25 
26     //更新字符串长度
27     length = len;
28 
29 }

7、比较字符串 

 1 /**
 2  *比较两个字符串是否相等,true:相等,flase:不相等
 3  */
 4 bool UString::IsCompare(const UString &s)const{
 5 
 6     if(s.length && length){
 7         //取长度较小的字符串长度,做比较循环长度
 8         //size_t 在C++中,设计 size_t 就是为了适应多个平台的 ,很多开源项目中都用是这个
 9         size_t len = s.length > length ? length:s.length;
10 
11         //循环比较每一个字符
12         for(size_t i = 0; i < len; i++){
13             if(ch[i] != s.ch[i]){
14                 return false;
15             }
16         }
17 
18         return true;
19     }
20 
21     return false;
22 }

8、截取字符串 

 1 /**
 2  * 截取字符串函数,从给定的位置截取指定长度的字符串
 3  * @param s 源字符串
 4  * @param pos 开始位置
 5  * @param len 截取长度
 6  * @return 截取后的字符串
 7  */
 8 void UString::SubString(UString &s,const size_t &pos,const size_t &len){
 9 
10     //错误消息
11     const char *msg = "";
12 
13     //写一个通用的方法,需要关注三个地方;
14     //1、明确的注释(漂亮的方法名和参数名);2、高效易懂的程序代码(更偏重高效);3、准确的异常信息
15     //在出现不能满足该方法的参数时,立马抛出异常,不应该返回false,这样会给程序带来很隐晦的bug
16     //下面处思想和java中String的SubString方法的API一样,不幸是char不能拼接字符串,更好的思路还在学习中
17     if(pos < 0){
18         msg = "UString index out of range:";
19     }
20     if(length < pos){
21         msg = "UString index out of range:";
22     }
23     if(len < 0){
24         msg = "UString index out of range:";
25     }
26     if(length + 1 - pos < len){
27         msg = "UString index out of range:";
28     }
29 
30     if(msg != ""){
31         //C++提供异常处理方法,如果出错立马停住(return;)并且抛出异常
32         std::__throw_out_of_range(__N(msg));
33     }
34 
35     //循环截取源字符串
36     char *p = new char[len];
37     for(size_t i = 0; i < len; ++i){
38         p[i] = ch[pos+i];
39     }
40 
41     //设置截取后的字符串
42     s.ch = p;
43     s.length = len;
44 }
45 /**
46  * 截取字符串函数,从给定的位置截取后面的所有字符串
47  * @param s 源字符串
48  * @param pos 开始位置
49  * @return 截取后的字符串
50  */
51 void UString::SubString(UString &s,const size_t &pos){
52     return this->SubString(s,pos,length-pos);
53 }

 9、查找字符串位置 

 1 /**
 2  * 从指定的位置开始查找指定的字符串,
 3  * @param s 需要查找字符串
 4  * @param pos 指定位置
 5  */
 6 size_t UString::IndexOf(const UString &s,const size_t &pos){
 7 
 8     const char *msg = "";
 9     if(pos < 0){
10         msg = "UString index out of range:";
11     }
12     if(pos > length){
13         msg = "UString index out of range:";
14     }
15     if(msg != ""){
16         std::__throw_out_of_range(__N(msg));
17     }
18 
19     UString r;
20     size_t index = -1;
21 
22     //
23     for(size_t i = pos; i < length - s.length + 1; ++i){
24 
25         SubString(r,i,s.length);
26 
27         if(r.IsCompare(s)){
28             index = i;
29             break;
30         }
31 
32     }
33 
34     return index;
35 }
36 /**
37  * 从指定的位置开始查找指定的字符串,
38  */
39 size_t UString::IndexOf(const UString &s){
40     return IndexOf(s,0);
41 }

10、运行结果

测试各个方法代码 

View Code
 1 void UString::test(){
 2     UString t("hello sunysen!"),p,s;
 3     t.StrCout();
 4 
 5     std::cout<<"-----------------copy begin--------------------"<<std::endl;
 6     p.StrCopy(t);
 7     p.StrCout();
 8     std::cout<<"-----------------copy end--------------------"<<std::endl;
 9 
10     std::cout<<"-----------------sub begin--------------------"<<std::endl;
11     t.SubString(s,1);
12     s.StrCout();
13 
14     t.SubString(s,1,1);
15     s.StrCout();
16     std::cout<<"-----------------sub end--------------------"<<std::endl;
17 
18     std::cout<<"-----------------delete begin--------------------"<<std::endl;
19     t.StrDelete(2,2);
20     t.StrCout();
21     std::cout<<"-----------------delete end--------------------"<<std::endl;
22 
23     std::cout<<"-----------------insert begin--------------------"<<std::endl;
24     t.StrInsert(2,UString("ll"));
25     t.StrCout();
26     std::cout<<"-----------------insert end--------------------"<<std::endl;
27 
28     std::cout<<"-----------------index begin--------------------"<<std::endl;
29     std::cout<<"hello index = "<<t.IndexOf("hello")<<std::endl;
30     std::cout<<"-----------------end begin--------------------"<<std::endl;
31 
32     std::cout<<"-----------------replace begin--------------------"<<std::endl;
33     t.Replace("hello","hellor");
34     t.StrCout();
35     std::cout<<"-----------------replace end--------------------"<<std::endl;
36 
37     t.StrAppend(" hello sunysen!");
38     t.StrCout();
39 }

 

11、完整代码

UString.h源代码如下:

View Code
 1 /*
 2  * UString.h
 3  *
 4  *  Created on: Mar 24, 2013
 5  *      Author: sunysen
 6  */
 7 
 8 #ifndef USTRING_H_
 9 #define USTRING_H_
10 
11 #include "string.h"
12 
13 class UString {
14 private:
15     char *ch;
16     size_t length;
17 public:
18     UString();
19 
20     UString(const char* str);
21 
22     UString(const UString &s);
23 
24     UString(const char* str,const size_t &len);
25 
26     ~UString();
27 
28     UString& StrAssign(const UString &s);
29 
30     void Clear();
31 
32     void StrCopy(const UString &s);
33 
34     bool IsEmpty()const;
35 
36     bool IsCompare(const UString &s)const;
37 
38     size_t Length(const UString &s) const;
39 
40     void Concat(const UString &s,const UString &s2);
41 
42     void SubString(UString &s,const size_t &pos,const size_t &len);
43 
44     void SubString(UString &s,const size_t &pos);
45 
46     UString SubString(const size_t &pos,const size_t &len);
47 
48     void StrCout();
49 
50     void StrInsert(const size_t &pos,const UString &s);
51 
52     void StrDelete(const size_t &pos,const size_t &len);
53 
54     size_t IndexOf(const UString &s,const size_t &pos);
55 
56     size_t IndexOf(const UString &s);
57 
58     void Replace(const UString &OldStr,const UString &newStr);
59 
60     void StrAppend(const UString &s);
61 
62     inline void StrCpChar(const char* str,const size_t &len){
63         ch =  new char[len];
64 
65         //这样方式赋值效率很低,跟多请参考C++提供char_traits.h文件
66         for(size_t i = 0; i < len; ++i){
67             ch[i] = str[i];
68         }
69 
70         length = len;
71     };
72 
73     void test();
74 
75 };
76 
77 #endif /* USTRING_H_ */

UString.cpp源代码如下:

View Code
  1 /*
  2  * UString.cpp
  3  *
  4  *  Created on: Mar 24, 2013
  5  *      Author: sunysen
  6  */
  7 
  8 #include "UString.h"
  9 #include <iostream>
 10 
 11 //申明空字符串变量时候初始化变量
 12 //1、在实际开发工作,最好能做到变量申明时就做初始化工作,
 13 //如果先申明空字符串变量、在赋值,相当于多一次赋值工作
 14 UString::UString():ch(0),lenght(0) {
 15 }
 16 
 17 //字符串数组做初始化变量
 18 UString::UString(const char* str) {
 19     //这是一个inline的函数,更多inline的用户请点击
 20     StrCpChar(str,strlen(str));
 21 }
 22 //字符串数组做初始化变量,
 23 UString::UString(const char* str,const size_t &len) {
 24     //这是一个inline的函数,更多inline的用户请点击
 25     StrCpChar(str,len);
 26 }
 27 
 28 //字符串数组做初始化变量,
 29 UString::UString(const UString &s) {
 30 
 31     length = s.length;
 32     ch = new char[length];
 33 
 34     for(size_t i = 0; i < length; ++i){
 35         ch[i] = s.ch[i];
 36     }
 37 
 38 }
 39 //析构函数
 40 UString::~UString() {
 41     Clear();
 42 }
 43 /**
 44  *清空字符串,并且回收内存
 45  */
 46 void UString::Clear(){
 47 
 48     if(ch != 0){
 49         //删除字符串并释内存,这样做很危险
 50         delete[] ch;
 51         ch = 0;
 52     }
 53 
 54     length = 0;
 55 }
 56 /**
 57  * 判断字符串是否为空
 58  */
 59 bool UString::IsEmpty()const{
 60     return length == 0;
 61 }
 62 
 63 /**
 64  *比较两个字符串是否相等,true:相等,flase:不相等
 65  */
 66 bool UString::IsCompare(const UString &s)const{
 67 
 68     if(s.length && length){
 69         //取长度较小的字符串长度,做比较循环长度
 70         //size_t 在C++中,设计 size_t 就是为了适应多个平台的 ,很多开源项目中都用是这个
 71         size_t len = s.length > length ? length:s.length;
 72 
 73         //循环比较每一个字符
 74         for(size_t i = 0; i < len; i++){
 75             if(ch[i] != s.ch[i]){
 76                 return false;
 77             }
 78         }
 79 
 80         return true;
 81     }
 82 
 83     return false;
 84 }
 85 
 86 /**
 87  * 截取字符串函数,从给定的位置截取指定长度的字符串
 88  * @param s 源字符串
 89  * @param pos 开始位置
 90  * @param len 截取长度
 91  * @return 截取后的字符串
 92  */
 93 void UString::SubString(UString &s,const size_t &pos,const size_t &len){
 94 
 95     //错误消息
 96     const char *msg = "";
 97 
 98     //写一个通用的方法,需要关注三个地方;
 99     //1、明确的注释(漂亮的方法名和参数名);2、高效易懂的程序代码(更偏重高效);3、准确的异常信息
100     //在出现不能满足该方法的参数时,立马抛出异常,不应该返回false,这样会给程序带来很隐晦的bug
101     //下面处思想和java中String的SubString方法的API一样,不幸是char不能拼接字符串,更好的思路还在学习中
102     if(pos < 0){
103         msg = "UString index out of range:";
104     }
105     if(length < pos){
106         msg = "UString index out of range:";
107     }
108     if(len < 0){
109         msg = "UString index out of range:";
110     }
111     if(length + 1 - pos < len){
112         msg = "UString index out of range:";
113     }
114 
115     if(msg != ""){
116         //C++提供异常处理方法,如果出错立马停住(return;)并且抛出异常
117         std::__throw_out_of_range(__N(msg));
118     }
119 
120     //循环截取源字符串
121     char *p = new char[len];
122     for(size_t i = 0; i < len; ++i){
123         p[i] = ch[pos+i];
124     }
125 
126     //设置截取后的字符串
127     s.ch = p;
128     s.length = len;
129 }
130 /**
131  * 截取字符串函数,从给定的位置截取后面的所有字符串
132  * @param s 源字符串
133  * @param pos 开始位置
134  * @return 截取后的字符串
135  */
136 void UString::SubString(UString &s,const size_t &pos){
137     return this->SubString(s,pos,length-pos);
138 }
139 
140 /**
141  * 在字符串指定位置插入新的字符串(仅仅为更深入学习字符串,在实际中仅作为Replace底层实现)
142  * @param s 准备插入的字符串
143  * @param pos 开始位置
144  */
145 void UString::StrInsert(const size_t &pos,const UString &s){
146     const char *msg = "";
147     if(pos < 0){
148         msg = "UString index out of range:";
149     }
150     if(pos > length){
151         msg = "UString index out of range:";
152     }
153     if(msg != ""){
154         std::__throw_out_of_range(__N(msg));
155     }
156 
157     //计算原字符串和新插入字符串长度
158     size_t len = s.length + length;
159     char *p = new char[len];
160 
161     //插入原字符串pos前的字符串到新空间
162     for(size_t i = 0; i < pos; ++i){
163         p[i] = ch[i];
164     }
165 
166     //插入目标字符串到新空间
167     for(size_t i = 0; i < s.length; ++i){
168         p[pos + i] = s.ch[i];
169     }
170 
171     //插入原字符串pos后面的字符串到新空间
172     for(size_t i = pos; i < length; i++){
173         p[i + s.length] = ch[i];
174     }
175 
176     //删除原字符串并释放内存(很危险)
177     delete[] ch;
178 
179     //设置新拼接的字符串
180     ch = p;
181     length = len;
182 
183 }
184 /**
185  * 从指定的位置删除指定长度字符串(仅仅为更深入学习字符串,在实际中仅作为Replace底层实现)
186  * @param pos 开始位置
187  * @param len 字符串长度
188  */
189 void UString::StrDelete(const size_t &pos,const size_t &len){
190 
191     const char *msg = "";
192     if(pos < 0){
193         msg = "UString index out of range:";
194     }
195     if(pos > length){
196         msg = "UString index out of range:";
197     }
198     if(len < 0){
199         msg = "UString index out of range:";
200     }
201     if(length-pos < len){
202         msg = "UString index out of range:";
203     }
204 
205     if(msg != ""){
206         std::__throw_out_of_range(__N(msg));
207     }
208 
209     size_t i = 0;
210     char *p = new char[length - len];
211 
212     //插入原字符串pos前的字符串到新空间
213     for(i = 0; i < pos; ++i){
214         p[i] = ch[i];
215     }
216 
217     //插入原字符串pos后面的字符串到新空间
218     for(i = pos; i < length-len; ++i){
219         p[i] = ch[i + len];
220     }
221 
222     //删除原字符串并释放内存(很危险)
223     delete[] ch;//Clear();
224 
225     //字符串长度
226     ch = p;
227     length = length - len;
228 
229 }
230 
231 size_t UString::IndexOf(const UString &s,const size_t &pos){
232 
233     const char *msg = "";
234     if(pos < 0){
235         msg = "UString index out of range:";
236     }
237     if(pos > length){
238         msg = "UString index out of range:";
239     }
240     if(msg != ""){
241         std::__throw_out_of_range(__N(msg));
242     }
243 
244     UString r;
245     size_t index = -1;
246 
247     for(size_t i = pos; i < length - s.length + 1; ++i){
248 
249         SubString(r,i,s.length);
250 
251         if(r.IsCompare(s)){
252             index = i;
253             break;
254         }
255 
256     }
257 
258     return index;
259 }
260 
261 size_t UString::IndexOf(const UString &s){
262     return IndexOf(s,0);
263 }
264 /**
265  * 替换字符串(1、查找原字符串;2、删除原字符串;3、插入新字符串)
266  * @param oldStr 原字符串
267  * @param newStr 新字符串
268  */
269 void UString::Replace(const UString &oldStr,const UString &newStr){
270 
271     size_t i = 0;
272     //处理一个字符串中有多个相同oldStr
273     while(i != -1){
274 
275         //查找原字符串
276         i = IndexOf(oldStr,i);
277         if(i != -1){
278             //删除原字符串
279             StrDelete(i,oldStr.length);
280             //插入新字符串
281             StrInsert(i,newStr);
282             //改变i值查询一个oldStr字符串
283             i = i + oldStr.length;
284         }
285 
286     }
287 
288 }
289 void UString::StrAppend(const UString &s){
290 
291     size_t len  = length + s.length;
292 
293     char *p =  new char[len];
294 
295     for(size_t i = 0; i < length; i++){
296         p[i] = ch[i];
297     }
298 
299     for(size_t i = 0; i < s.length; i++){
300         p[i + length] = s.ch[i];
301     }
302     delete[] ch;
303     ch = p;
304     length = len;
305 
306 }
307 
308 void UString::StrCout(){
309     if(ch != 0){
310         for(size_t i = 0; i < length; ++i){
311             std::cout<<ch[i];
312         }
313         std::cout<<"\n"<<std::endl;
314     }
315 }
316 
317 void UString::StrCopy(const UString &s){
318 
319     ch = new char[s.length];
320 
321     if(ch != 0){
322         for(size_t i = 0; i < s.length; ++i){
323             ch[i] = s.ch[i];
324         }
325     }
326 
327     length = s.length;
328 }
329 void UString::test(){
330     UString t("hello sunysen!"),p,s;
331     t.StrCout();
332 
333     std::cout<<"-----------------copy begin--------------------"<<std::endl;
334     p.StrCopy(t);
335     p.StrCout();
336     std::cout<<"-----------------copy end--------------------"<<std::endl;
337 
338     std::cout<<"-----------------sub begin--------------------"<<std::endl;
339     t.SubString(s,1);
340     s.StrCout();
341 
342     t.SubString(s,1,1);
343     s.StrCout();
344     std::cout<<"-----------------sub end--------------------"<<std::endl;
345 
346     std::cout<<"-----------------delete begin--------------------"<<std::endl;
347     t.StrDelete(2,2);
348     t.StrCout();
349     std::cout<<"-----------------delete end--------------------"<<std::endl;
350 
351     std::cout<<"-----------------insert begin--------------------"<<std::endl;
352     t.StrInsert(2,UString("ll"));
353     t.StrCout();
354     std::cout<<"-----------------insert end--------------------"<<std::endl;
355 
356     std::cout<<"-----------------index begin--------------------"<<std::endl;
357     std::cout<<"hello index = "<<t.IndexOf("hello")<<std::endl;
358     std::cout<<"-----------------end begin--------------------"<<std::endl;
359 
360     std::cout<<"-----------------replace begin--------------------"<<std::endl;
361     t.Replace("hello","hellor");
362     t.StrCout();
363     std::cout<<"-----------------replace end--------------------"<<std::endl;
364 
365     t.StrAppend(" hello sunysen!");
366     t.StrCout();
367 }

六:环境

1、运行环境:Ubuntu 10.04 LTS+VMware8.0.4+gcc4.4.3

2、开发工具:Eclipse+make

七:题记

1、上面仅仅简单介绍字符串常用操作,还有更多知识需要阅读系统自带的String类(字符串查找、重复的字符串处理、高效字符串赋值),

2、上面的代码难免有bug,如果你发现代码写的有问题,请你帮忙指出,让我们一起进步,让代码变的更漂亮和更健壮;

3、我自己能手动写上面代码,离不开郝斌、高一凡、侯捷、严蔚敏等老师的书籍和视频指导,在这里感谢他们;

4、鼓励自己能坚持把更多数据结构方面的知识写出来,让自己掌握更深刻,也顺便冒充下"小牛"

 

欢迎继续阅读“启迪思维:数据结构和算法”系列

posted @ 2013-04-11 21:00  sunysen  阅读(366)  评论(3编辑  收藏  举报