运算符重载比较函数
bool operator==(const string& s1, const string& s2) { return strcmp(s1.c_str(), s2.c_str())==0; } bool operator>(const string& s1, const string& s2) { return strcmp(s1.c_str(), s2.c_str()); } bool operator<(const string& s1, const string& s2) { return !(s1 > s2 && s1 == s2); } bool operator<=(const string& s1, const string& s2) { return !(s1 > s2); } bool operator>=(const string& s1, const string& s2) { return !(s1 < s2); } bool operator!=(const string& s1, const string& s2) { return !(s1 == s2); }
注意这里为什么要搞成全局的呢??
void test10() { string str1; string str2; str1 += "abc"; str2 += "aba"; cout << (str1 == str2) << endl; cout << ("aba" == str2) << endl;//2 cout << (str2== "aba") << endl; }
因为第二种的话不满足类成员做左操作数,全局的话就可以,而第三个是会搞一个类型转换.
void test10() { string str1; string str2; str1 += "abc"; str2 += "aba"; cout << (str1 == str2) << endl; cout << ("aba" == str2) << endl; cout << (str2== "aba") << endl; cout << (str1>str2) << endl; cout << (str1 >=str2) << endl; cout << (str1<str2) << endl; cout << (str1 <=str2) << endl; cout << (str1!=str2) << endl; }
运算符重载流插入
ostream& operator<<(ostream& out, const string& s) { for (auto e : s)//遍历一个一个输出 { out << e; } return out; }
有返回值是为了可以连续流插入
运算符重载流提取
版本一:
istream& operator>>(istream& in, string& s) { char ch; in >> ch;//读取字符到ch while (ch != ' ' && ch != '\n')//读到‘ ’或‘\n’结束输入 {s += ch;//将ch加进去 in >> ch;//循环读取 } return in; }
这样写会有一个问题,就是cin和scanf一样默认‘\n’和‘ ’是分割符不会进行读取,所以ch不会是空格或换行,所以陷入死循环.
版本2:
c语言中可以用getchar来读取,而c++中存在get就可以读空格
istream& operator>>(istream& in, string& s) { char ch; in.get(ch); while (ch != ' ' && ch != '\n') { s += ch; in.get(ch); } return in; }
void test11() { string str1; string str2; cin >> str1;//>>str2;//>>str2; cout << str1; //cout << str1.capacity(); }
版本3
由于我们在s+=ch,会出现频繁扩容,影响效率,我们应该怎么解决呢??
我们可以提前开好空间,但是不知道应该开多大.假如说我们开128个
istream& operator>>(istream& in, string& s) { char ch; in.get(ch); s.reserve(128); while (ch != ' ' && ch != '\n') { s += ch; in.get(ch); } return in; }
void test11() { string str1; string str2; cin >> str1;//>>str2;//>>str2; //cout << str1; cout << str1.capacity(); }
两个数据开128就会有极大的浪费,多一点还好
版本4
istream& operator>>(istream& in, string& s) { s.clear();//可能我们s里面之前有数据,但是流提取是要覆盖的 char ch; ch = in.get(); char buff[128]; int i = 0; while (ch != ' ' && ch != '\n') { buff[i++] = ch; if (i == 127) { buff[127] = '\0'; s += buff; i = 0; } ch = in.get(); } if (i > 0) { buff[i] = '\0'; s += buff; } return in; }
这里感觉可以类比冯诺依曼体系,buff就相当于内存,先将输入的值放在内存buff里面,等到装满了,在一次性给s,减少搬运次数.避免了一次空间开的很大,而数据只有几个
clear
void clear() { _size = 0; _str[0] = '\0'; }
c_str
将const string* 转化为const char*
const char* c_str() const { return _str; }
cout不能直接处理自定义类型string,但是可以使用c_str将string转成常量字符串,内置类型就可以直接打印
源码
.h
#pragma once #define _CRT_SECURE_NO_WARNINGS using namespace std; #include<assert.h> #include<iostream> #include<algorithm> namespace zjw { class string { public: typedef char* iterator; typedef const char* const_iterator; iterator begin() { return _str; } iterator end() { return _str + _size; } const_iterator begin() const { return _str; } const_iterator end() const { return _str + _size; } string(const char* str = "") :_size(strlen(str)) { _capacity = _size; _str = new char[_capacity + 1]; strcpy(_str, str); } ~string() { delete[]_str; _str = nullptr; _size = _capacity = 0; } size_t size() { return _size; } size_t capacity() { return _capacity; } char& operator[](size_t pos) { assert(pos < _size); return _str[pos]; } const char& operator[](size_t pos) const { assert(pos < _size); return _str[pos]; } void reserve(size_t n) { if (n > _capacity) { char* tmp = new char[n + 1]; strcpy(tmp, _str); delete[]_str; _str = tmp; _capacity = n; } } void push_back(char ch) { if (_capacity == _size) { reserve(_capacity == 0 ? 4 : _capacity * 2); } _str[_size] = ch; _size++; _str[_size] = '\0'; } void append(const char* str) { size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str); _size += len; //_str[_size] = '\0'; } string& operator+=(char ch) { push_back(ch); return *this; } string& operator+=(const char* str) { append(str); return *this; } void insert(size_t pos, char ch) { assert(pos <= _size); if (_capacity == _size) { reserve(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + 1; while (end > pos) { _str[end] = _str[end - 1]; end--; } _str[pos] = ch; _size++; } const char* c_str() const { return _str; } void earse(size_t pos, size_t len = npos) { assert(pos < _size); if (len == npos || pos > _size - len) { _str[pos] = '\0'; _size = pos; } else { strcpy(_str + pos, _str + pos + len); _size -= len; } } bool empty() { return _size == 0; } void resize(size_t n, char ch = '\0') { if (n <= _size) { _str[n] = '\0'; _size = n; } else { reserve(n); for (size_t i = _size; i < n; i++) { _str[i] = ch; } _size = n; } } void insert(size_t pos, const char* str) { size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; end--; } strncpy(_str + pos, str, len); _size += len; } size_t find(char ch, size_t pos = 0) { for (int i = pos; i < _size; i++) { if (_str[i] == ch) return i; } return npos; } size_t find(const char* sub, size_t pos = 0) const { assert(pos < _size); const char* ptr = strstr(_str + pos, sub); if (ptr != nullptr) { return ptr - _str; } else { return npos; } } string substr(size_t pos = 0, size_t len = npos) const { string substr; if (pos > _size - len) { for (int i = pos; i <= _size; i++) { substr += _str[i]; } } else { for (int i = pos; i < pos + len; i++) { substr += _str[i]; } substr += '\0'; } return substr; } void swap(string& str) { std::swap(_str, str._str); std::swap(_size, str._size); std::swap(_capacity, str._capacity); } string(const string& s) { string tmp(s._str); swap(tmp); } string& operator=(string tmp) { swap(tmp); return *this; } string& operator=(const string& s) { char* tmp = new char[s._capacity + 1]; strcpy(tmp, s._str); delete[] _str; _str = tmp; _size = s._size; _capacity = s._capacity; return *this; } void clear() { _size = 0; _str[0] = '\0'; } friend istream& operator>>(istream& in, string& s); public: static const int npos; private: char* _str; int _size; int _capacity; }; const int string::npos = -1; void swap(string& x, string& y) { x.swap(y); cout << "没使用库里的" << endl; } istream& operator>>(istream& in, string& s) { s.clear(); char ch; ch = in.get(); char buff[128]; int i = 0; while (ch != ' ' && ch != '\n') { buff[i++] = ch; if (i == 127) { buff[127] = '\0'; s += buff; i = 0; } ch = in.get(); } if (i > 0) { buff[i] = '\0'; s += buff; } return in; } //istream& operator>>(istream& in, string& s) //{ // // char ch; // // in.get(ch); // // s.reserve(128); // while (ch != ' ' && ch != '\n') // { // // // s += ch; // in.get(ch); // } // // // // // return in; //} bool operator==(const string& s1, const string& s2) { return strcmp(s1.c_str(), s2.c_str())==0; } bool operator>(const string& s1, const string& s2) { return strcmp(s1.c_str(), s2.c_str()); } bool operator<(const string& s1, const string& s2) { return !(s1 > s2 && s1 == s2); } bool operator<=(const string& s1, const string& s2) { return !(s1 > s2); } bool operator>=(const string& s1, const string& s2) { return !(s1 < s2); } bool operator!=(const string& s1, const string& s2) { return !(s1 == s2); } ostream& operator<<(ostream& out, const string& s) { for (auto e : s) { out << e; } return out; } //istream& operator>>(istream& in, string& s) //{ // s.clear(); // char ch; // // ch = in.get(); // //in >> ch; // s.reserve(128); // while (ch != ' ' && ch != '\n') // { // // s += ch; // ch = in.get(); // //in >> ch; // } // return in; // // // // //} void test1() { string str; str += 'a'; str += 'b'; str += "beijing"; string::iterator it = str.begin(); while (it != str.end()) { cout << *it << " "; it++; } } void test2() { string str; str.push_back('a'); str.push_back('a'); str.push_back('b'); str.push_back('a'); str.push_back('a'); string::iterator it = str.begin(); while (it != str.end()) { cout << *it << " "; it++; } cout << str[2]; } void test3() { string str; str.append("stringbj"); for (auto& e : str) { cout << e << " "; } } void print_string(const string it) { string::const_iterator res = it.begin(); while (res != it.end()) { cout << *res << " "; ++res; } } void test4() { string str; str += "abc"; str.append("stringbj"); string::iterator it = str.begin(); while (it != str.end()) { cout << *it << " "; it++; } //str.insert(0, 'g'); for (auto& e : str) { cout << e << " "; } cout << endl; // str.earse(1,string::npos);*/ /* for (auto e : str) { cout << e << " "; }*/ // print_string(str); } void test5() { string str; str.push_back('a'); str.push_back('a'); str.push_back('b'); str.resize(10); /* string::iterator it = str.begin(); while (it != str.end()) { cout << *it << " "; it++; }*/ cout << str.c_str(); } void test6() { string str; str.push_back('a'); str.push_back('a'); str.push_back('b'); str.insert(2, "hello"); cout << str.c_str(); } void test7() { string str; str.push_back('a'); str.push_back('a'); str.push_back('b'); str.insert(2, "hello"); cout << endl; int ret = str.find('b', 0); cout << ret; } void test8() { string str; str += "beijing huanyingni zhangjiawang"; int ret = str.find("zhangjiawang"); cout << ret; } void test9() { string str; str += "beijing huanyingni zhangjiawang"; string op = str.substr(0, 10); cout << op.c_str(); } void test10() { string str1; string str2; str1 += "abc"; str2 += "aba"; cout << (str1 == str2) << endl; cout << ("aba" == str2) << endl; cout << (str2== "aba") << endl; cout << (str1>str2) << endl; cout << (str1 >=str2) << endl; cout << (str1<str2) << endl; cout << (str1 <=str2) << endl; cout << (str1!=str2) << endl; } void test11() { string str1; string str2; cin >> str1;//>>str2;//>>str2; //cout << str1; cout << str1.capacity(); } void test12() { string str1; string str2; str1 += "hello"; str2+="nihao"; cout << "str1:"<<str1 << endl; cout << "str2:"<<str2 << endl; str1.swap(str2); cout << "str1:" << str1 << endl; cout << "str2:" << str2 << endl; } void test13() { string str1; string str2; str1 += "hello"; str2 += "nihao"; cout << "str1:" << str1 << endl; cout << "str2:" << str2 << endl; swap(str1, str2); cout << "str1:" << str1 << endl; cout << "str2:" << str2 << endl; } void test14() { string str2; str2 += "nihao"; string str1(str2); } }
.cpp
#include"标头.h" int main() { zjw::test11(); }