Skip to content

Commit a05d36f

Browse files
committed
Day 63 My own string library implementation
1 parent 282e92a commit a05d36f

File tree

7 files changed

+546
-3
lines changed

7 files changed

+546
-3
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -g -pedantic")
1313

1414
foreach( sourcefile ${SOURCES} )
1515
get_filename_component( demo_name ${sourcefile} NAME_WE )
16+
if (${demo_name} STREQUAL "pstring")
17+
add_library(pstring ${sourcefile})
18+
continue()
19+
endif()
20+
if (${demo_name} STREQUAL "pUnitTest")
21+
add_library(pUnitTest ${sourcefile})
22+
continue()
23+
endif()
1624
add_executable( ${demo_name} ${sourcefile} )
25+
if (${demo_name} STREQUAL "pstring_test")
26+
target_link_libraries (${demo_name} pstring pUnitTest)
27+
endif()
28+
continue()
29+
endif()
1730
endforeach( sourcefile ${SOURCES} )
1831

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
| Current Status| Stats |
88
| :------------: | :----------: |
9-
| Total Problems | 91 |
10-
| Current Streak | 62 days |
11-
| Longest Streak | 62 ( August 17, 2015 - October 17, 2015 ) |
9+
| Total Problems | 92 |
10+
| Current Streak | 63 days |
11+
| Longest Streak | 63 ( August 17, 2015 - October 18, 2015 ) |
1212

1313
</center>
1414

@@ -49,6 +49,7 @@ Include contains single header implementation of data structures and some algori
4949
| Linux Kernel Double LinkedList Implementation | [double_linked_list.h](include/double_linked_list.h) |
5050
| Generic Graph Implementation (Adjacency List) | [graph.h](include/graph.h) |
5151
| Heap Sort Implementation | [heap_sort.h](include/heap_sort.h)|
52+
| My own string library implementation | [pstring.h](include/pstring.h) [pstring.cpp](include/pstring.cpp)|
5253

5354
###Bit Manipulation Problems
5455
| Problem | Solution |
@@ -119,6 +120,7 @@ Include contains single header implementation of data structures and some algori
119120
| Implementation of Robin-Karp algorithm for string search | [robinKarpStringMatching.cpp](string_problmes/robinKarpStringMatching.cpp) |
120121
| Find next permutation of a given string, ie. rearrange the given string sucht a way that is next lexicographically greater string than given string | [next_permutation.cpp](string_problems/next_permutation.cpp)|
121122
| Implementation of Z algorithm for pattern matching | [z.cpp](string_problems/z.cpp)|
123+
| Test cases for self created string library | [pstring_test.cpp](string_problems/pstring_test.cpp)|
122124

123125
### Common Data Structure and logic problems
124126
| Problem | Solution |

include/pUnitTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// BWUTest.cpp
2+
// A simple unit test class
3+
// by Bill Weinman <http://bw.org/>
4+
// Copyright (c) 2014-2015 The BearHeart Group LLC
5+
//
6+
7+
#include "pUnitTest.h"
8+
9+
UTest::UTest( const char * _test_str ) {
10+
init(_test_str);
11+
}
12+
13+
void UTest::init( const char * _tstr ) {
14+
_test_str = _tstr;
15+
_pass_count = _fail_count = 0;
16+
}
17+
18+
void UTest::test ( const char * description, const int flag ) {
19+
const char * pf = nullptr;
20+
if (flag) {
21+
pf = __ut_pstr;
22+
++_pass_count;
23+
} else {
24+
pf = __ut_fstr;
25+
++_fail_count;
26+
}
27+
if(!_summary_flag) printf("%s: %s -> %s\n", _test_str, description, pf);
28+
}
29+
30+
void UTest::report() const {
31+
printf("%s: pass: %ld, fail: %ld\n", _test_str, pass_count(), fail_count());
32+
fflush(stdout);
33+
}

include/pUnitTest.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// BWUTest.h
2+
// A simple unit test class
3+
4+
#ifndef __PSTRING_UTEST__
5+
#define __PSTRING_UTEST__
6+
7+
#include <cstdio>
8+
9+
#define _UTest_VERSION "1.0.0"
10+
11+
const static char * __ut_pstr = "pass";
12+
const static char * __ut_fstr = "fail";
13+
14+
class UTest {
15+
unsigned long int _pass_count = 0;
16+
unsigned long int _fail_count = 0;
17+
bool _summary_flag = false;
18+
19+
const char * _test_str = nullptr;
20+
21+
UTest( UTest & ); // no copy constructor
22+
UTest operator = ( UTest & ); // no assignment operator
23+
UTest(){} // no default constructor
24+
public:
25+
static const char * version() { return _UTest_VERSION; }
26+
27+
UTest( const char * );
28+
void init ( const char * );
29+
bool summary ( bool flag ) { return _summary_flag = flag; }
30+
bool summary ( ) { return _summary_flag; }
31+
unsigned long int pass_count() const { return _pass_count; }
32+
unsigned long int fail_count() const { return _fail_count; }
33+
void test ( const char * description, const int flag );
34+
void report() const;
35+
};
36+
37+
#endif /* defined(__PSTRING_UTEST__) */

include/pstring.cpp

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/**
2+
* A string library for practice
3+
* Ravi Mandliya
4+
*/
5+
6+
#include "pstring.h"
7+
8+
using String = algo::String;
9+
10+
String::String( ) {
11+
_reset();
12+
}
13+
14+
String::String( const char * s ) {
15+
_copy_str(s);
16+
}
17+
18+
String::String( const String & str ) {
19+
_copy_str(str);
20+
}
21+
22+
String::String( String && other ) noexcept {
23+
_reset();
24+
_str = other._str;
25+
_str_len = other._str_len;
26+
other._str = nullptr;
27+
other._str_len = 0;
28+
other._reset();
29+
}
30+
31+
String::~String() {
32+
_reset();
33+
}
34+
35+
void String::_alloc_cstr(size_t sz) {
36+
if ( _str ) {
37+
_reset();
38+
}
39+
_str_len = ( sz > algo::_PSTRING_MAX_LEN ) ? algo::_PSTRING_MAX_LEN : sz;
40+
_str = new char[_str_len + 1]();
41+
}
42+
43+
void String::_reset() {
44+
if ( _str ) {
45+
delete [] _str;
46+
}
47+
_str = nullptr;
48+
_str_len = 0;
49+
}
50+
51+
void String::_swap( String & other ) {
52+
std::swap( _str, other._str );
53+
std::swap( _str_len, other._str_len );
54+
}
55+
56+
const char * String::c_str() const {
57+
return _str;
58+
}
59+
60+
void String::_copy_str( const char * s ) {
61+
if ( s ) {
62+
size_t sz = strnlen( s, algo::_PSTRING_MAX_LEN );
63+
_alloc_cstr( sz );
64+
strncpy( _str, s, sz );
65+
}
66+
}
67+
68+
bool String::_have_value() const {
69+
if ( _str ) {
70+
return true;
71+
}
72+
return false;
73+
}
74+
75+
size_t String::_char_find( const char & match, size_t pos ) const {
76+
if ( pos >= _str_len ) {
77+
return algo::npos;
78+
}
79+
for ( size_t i = 0; _str[i + pos]; ++i ) {
80+
if ( _str[i] == match ) {
81+
return i;
82+
}
83+
}
84+
return algo::npos;
85+
}
86+
87+
void String::_char_replace( const char & match_char,
88+
const char & replace_char) {
89+
for ( size_t i = 0; _str[i]; ++i ) {
90+
if ( _str[i] == match_char ) {
91+
_str[i] = replace_char;
92+
return;
93+
}
94+
}
95+
}
96+
97+
String & String::operator = ( String other ) {
98+
_swap(other);
99+
return *this;
100+
}
101+
102+
String & String::operator += ( const char * s ) {
103+
if ( s ) {
104+
size_t len1 = strlen(s);
105+
if ( len1 < 1 ) {
106+
return *this;
107+
}
108+
size_t new_len = len1 + _str_len;
109+
new_len = (new_len > algo::_PSTRING_MAX_LEN ) ? algo::_PSTRING_MAX_LEN : new_len;
110+
char * buf = new char[new_len + 1];
111+
if (_str_len && _str ) {
112+
memcpy(buf, _str, _str_len);
113+
}
114+
memcpy(buf + _str_len, s, len1);
115+
_copy_str( buf );
116+
delete[] buf;
117+
}
118+
return * this;
119+
}
120+
121+
String & String::operator += ( const String & s ) {
122+
operator+=( s.c_str() );
123+
return * this;
124+
}
125+
126+
const char String::operator [] (const size_t index) const {
127+
if ( index >= this->length() ) return 0;
128+
return _str[index];
129+
}
130+
131+
bool String::operator == ( const String & s ) const {
132+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) == 0 ) {
133+
return true;
134+
}
135+
else return false;
136+
}
137+
138+
bool String::operator != ( const String & s ) const {
139+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) != 0 ) {
140+
return true;
141+
}
142+
else return false;
143+
}
144+
145+
bool String::operator >= ( const String & s ) const {
146+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) >= 0 ) {
147+
return true;
148+
}
149+
else return false;
150+
}
151+
152+
bool String::operator <= ( const String & s ) const {
153+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) <= 0 ) {
154+
return true;
155+
}
156+
else return false;
157+
}
158+
159+
bool String::operator < ( const String & s ) const {
160+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) < 0 ) {
161+
return true;
162+
}
163+
else return false;
164+
}
165+
166+
bool String::operator > ( const String & s ) const {
167+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) > 0 ) {
168+
return true;
169+
}
170+
else return false;
171+
}
172+
173+
String::operator const char * () const {
174+
return this->c_str();
175+
}
176+
177+
String String::lower() const {
178+
String rs = *this;
179+
for ( size_t i = 0; rs._str[i]; ++i ) {
180+
rs._str[i] = tolower(rs._str[i]);
181+
}
182+
return rs;
183+
}
184+
185+
String String::upper() const {
186+
String rs = *this;
187+
for ( size_t i = 0; rs._str[i]; ++i ) {
188+
rs._str[i] = toupper(rs._str[i]);
189+
}
190+
return rs;
191+
}
192+
193+
const char & String::front() const {
194+
return _str[0];
195+
}
196+
197+
const char & String::back() const {
198+
return _str[_str_len - 1];
199+
}
200+
201+
String String::substr( size_t pos, size_t len ) const {
202+
String rs;
203+
char * buf;
204+
if ( len + 1 > algo::_PSTRING_MAX_LEN ||
205+
( pos + len ) > algo::_PSTRING_MAX_LEN ) {
206+
return rs;
207+
}
208+
if ( _str_len - pos < len ) {
209+
return rs;
210+
}
211+
if (!_str) {
212+
return rs;
213+
}
214+
buf = new char[ len + 1 ]();
215+
memcpy( buf, _str + pos, len );
216+
rs = buf;
217+
delete[] buf;
218+
return rs;
219+
}
220+
221+
size_t String::find( const char * s, size_t pos ) const {
222+
size_t index = algo::npos;
223+
if ( pos >= _str_len ) {
224+
return index;
225+
}
226+
char * sub = strstr( _str + pos, s );
227+
if ( sub ) {
228+
return ( sub - _str );
229+
}
230+
return algo::npos;
231+
}
232+
233+
size_t String::find( const String & match, size_t pos ) const {
234+
return find( match.c_str(), pos);
235+
}
236+
237+
size_t String::find( char c, size_t pos ) const {
238+
return _char_find(c, pos);
239+
}
240+
241+
String String::replace( size_t pos, size_t len, const char * str ) {
242+
String res;
243+
if ( ( pos >= _str_len ) || ( pos + len >= _str_len ) ) {
244+
return res;
245+
}
246+
String s1 = pos > 0 ? substr( 0, pos ) : "" ;
247+
String s2 = str;
248+
String s3 = substr( pos + len, _str_len - (pos+len));
249+
String s4 = s1 + s2 + s3;
250+
return s4;
251+
}
252+
253+
String String::replace( size_t pos, size_t len, const String & str) {
254+
return replace(pos, len, str.c_str());
255+
}
256+
257+
int String::compare( const char * str ) const {
258+
return strncmp( this->c_str(), str, algo::_PSTRING_MAX_LEN );
259+
}
260+
261+
int String::compare( const String & str ) const noexcept {
262+
return strncmp( this->c_str(), str.c_str(), algo::_PSTRING_MAX_LEN );
263+
}
264+
265+
String algo::operator + ( const String & lhs, const String & rhs ) {
266+
String ans = lhs;
267+
ans += rhs;
268+
return ans;
269+
}
270+
271+
String algo::operator + ( const String & lhs, const char * rhs ) {
272+
String ans = lhs;
273+
ans += rhs;
274+
return ans;
275+
}

0 commit comments

Comments
 (0)