Модернизация механизма поиска для работы со стандартным классом string.

Рубрика: C++, Дата: 25 March, 2013, Автор:
Tags:

Модернизируйте механизм поиска для работы со стандартным классом string. Заметьте, что вы не можете модернизировать класс string.

Механизм который нужно модернизировать находится по ссылке: http://www.kselax.ru/2013/03/mexaniz-regulyarnyx-vyrazhenij-dlya-poiska-v-strokax-tipa-string/ 

Чтобы долго не мучится мы просто добавим в функцию String::rv() вторым параметром string переменную которую если мы будем передавать, то поиск будет в ней вестись если нет, то в самом классе, то есть по умолчанию ей зададим параметр-метку, если он будет, то мы будем осуществлять поиск в классе String, если нет то поиск осуществляется в строке.

Опять скопируем полностью сам класс String файл String.h:

//opredelenie
#ifndef STRING_H
#define STRING_H
#include <iostream>
using std::ostream;
using std::istream;
#include <string>
using std::string;

class String
{
	friend class String_iter;
	struct Srep; //predctavlenie (representation)
	Srep* rep;//ykazatel6 na klacc Srep xranit dannue
	class Cref; //cculka na char
	
	//dl9 izmeneni9 ctroki iz substr
	int substrN;//nachalo
	int substrK;//konec

public:
	class Range{};//dl9 icklyuchenii
	//...
	
	//konctryktor po ymolchaniyu
	String();//String a;
	
	//konctryktor preobrazovani9
	String(const char*);//String x("abc");
	
	//konctryktor kopii
	String(const String&);//String x(s);
	
	//peregryzka pricvaivani9 strok char*
	String& operator=(const char*);//x="abc";
	
	//peregryzka pricvaivani9 strok String
	String& operator=(const String&);//x=b;
	//dectryktor mojet icpol6zovatc9 dl9 ydaleni9 dinamicheckoi pam9ti
	~String();
	//...
	//...
	//nabor fynkcii dl9 peregryzki indekca
	
	//proverka vuxoda za predelu indekca
	void check(int i)const;
	
	//vozvrachaet cimvol ctroki po indekcy (bez proverki vuxoda za predelu)
	char read(int i) const;
	
	//perezapicuvaet cimvol (bez proverki na vuxod za predelu indekca)
	void write(int i, char c);
	
	//peregryzka dl9 chteni9 i zapici ne konctantnux ob6ektov
	Cref operator[](int i);
	
	//vuzuvaetc9 dl9 konctantnux ob6ektov
	char operator[](int i)const;
	
	//vozvrachaet razmer ctroki
	int size()const;
	
	//...
	//dopolnitel6nue fynkcii raccmotrim pojje
	//...
	String& operator+=(const String&);
	String& operator+=(const char*);
	
	friend ostream& operator<<(ostream&, const String&);
	friend istream& operator>>(istream&, String&);
	
	friend bool operator==(const String& x, const char* s);
	
	friend bool operator==(const String& x, const String& y);
	
	friend bool operator!=(const String& x, const char* s);
	
	friend bool operator!=(const String& x, const String& y);
	
	//fynkci9 dl9 vudeleni9 podctroki
	string sub(int, int);
	
	//fynkci9 dl9 izmeneni9 podctroki
	String& substr(int, int);
	
	//vozvrat ctroki v vide Ci
	char* data();
	
	//mex reg. vurajenii
	bool rv(const char*, string="!");
};

//konkatenaci9 ctrok
String operator+(const String&, const String&);
String operator+(const String&, const char*);

#endif

файл String.cpp:

//opredelenie klacca String
#include <cstring>
using std::strcpy;
using std::strlen;
using std::strcat;
using std::strstr;
#include <cstdlib>
using std::exit;

#include "String.h"

//vlojenui klacc dl9 predctavleni9

//klacc dl9 predctavleni9 ctroki
struct String::Srep
{
	char* s;//ykazatel6 na element
	int sz;//kol-vo cimvolov
	int n;//cchetchik cculok
	
	//konctryktor po ymolchaniyu
	Srep(int nsz, const char* p)//nsz-kol.cimvolov , p - ykazatel6 na ctroky
	{
		n=1;//cculka ravno 1.
		sz=nsz;//kolichectvo cimvolov inicializaci9
		s=new char[sz+1];//plyuc terminal6nui nyl6 (vudelenie pam9ti)
		strcpy(s,p);//proizvodim kopirovanie
	}
	
	//dectryktor
	~Srep(){delete[]s;}//proicxodit ydalenie dinamicheckoi pam9ti
	
	//cozdaet kopiyu ob6ekta naprimer pri izmenenii cimvola ctroki
	Srep* get_own_copy()//klonirovat6 pri neobxodimocti
	{
		//ecli toko odna cculka
		if(n==1)return this; 
		n--;
		return new Srep(sz,s);
	}
	
	//vuzovaetc9 dl9 izmeneni9 ctroki ob6ekta
	void assign(int nsz,const char* p)
	{
		//ecli razmer cimvolov covpadaet, to ne vudel9em dinamichecki
		if(sz!=nsz)
		{
			delete[]s;
			sz=nsz;
			s=new char[sz+1];
		}
		strcpy(s,p);//proizvodim zameny ctroki
	}

private://predotvrachaem kopirovanie; 
	Srep(const Srep&);//konctryktor kopii
	Srep& operator=(const Srep&);//operator pricvaivani9
};

//klacc dl9 imitacii cimvola char
class String::Cref //cculka na s[i]
{
friend class String;
	
	String& s;
	int i;
	
	Cref(String& ss, int ii)
	:s(ss),i(ii){}
	Cref(const Cref& r)
	:s(r.s),i(r.i){}
	Cref();//ne opredel9etc9 (ne icpol6zyetc9)
	
public:
	operator char() const
	{
		s.check(i);
		return s.read(i);
	}//vudaet znachenie
	
	void operator=(char c)
	{
		s.write(i,c);
	}//izmen9et znachenie
};

//opredelenie functions

//konctryktor po ymolchaniyu
String::String()
:substrN(0),substrK(0)
{
	rep=new Srep(0,"");//ymolchatel6noe znachenie-pycta9 ctroka
}

//konctryktor kopii
String::String(const String& x)
:substrN(0),substrK(0)
{
	x.rep->n++;//yvelichivaem kolichectvo cculok
	rep=x.rep;//razdel9emoe predctavlenie
}

//dectryktor;
String::~String()//proicxodit ydalenie vudelennoi pam9ti ecli nety cculok
{
	if(--rep->n==0) delete rep;
}

//peregryzka operatora pricvaivani9 
String& String::operator=(const String& x)// a=b; a.operator=(b);
{
	x.rep->n++;//zachita ot "st=st"
	//ecli cculkok 0, toect6 ne cculaetc9 bol6we nikto na etot ob6ekt, to ydal9m pam9t6
	if(--rep->n==0)delete rep;
	rep=x.rep;//razdel9emoe predctavlenie (ykazatel6 raven drygomy yk, toect6 bez kopirovani9
	return *this;
}

//konctryktor preobrazovani9 c argymentom const char* pozvol9et String a("abc"); 
String::String(const char* s)
:substrN(0),substrK(0)
{
	rep=new Srep(strlen(s),s);
}

//peregryzka operator= dl9 const char, pozvol9et a="abc";
String& String::operator=(const char* s)
{
	if(substrN==0&&substrK==0)
	{
		if(rep->n==1)//ecli net cculok, to izmen9em predctavlenie
			rep->assign(strlen(s),s);//icpol6zye ctarui Srep
		else//ect6 ewe cculki, to procto ymen6waem kolichectvo cculok
		{
			rep->n--;
			rep=new Srep(strlen(s),s);//icpol6zyem novui Srep
		}
		return *this;
	}
	else
	{
		substrN=0;
		substrK=0;
		cout <<"delaem drygyyu"<<endl;
		//formiryem novyyu ctroky
		string result;
		for(int i=0;i<substrN;i++)
		{
			result+=rep->s[i];
		}
		
		for(int i=0;s[i]!='\0';i++)
		{
			result+=s[i];
		}
		
		for(int i=substrK+1;rep->s[i]!='\0';i++)
		{
			result+=rep->s[i];
		}
		//cout <<"result= "<<result<<endl;
		
		//obnovl9em
		if(rep->n==1)//ecli net cculok, to izmen9em predctavlenie
			rep->assign(strlen(result.data()),result.data());//icpol6zye ctarui Srep
		else//ect6 ewe cculki, to procto ymen6waem kolichectvo cculok
		{
			rep->n--;
			rep=new Srep(strlen(result.data()),result.data());//icpol6zyem novui Srep
		}
		return *this;
		
	}
}

//nabor fynkcii dl9 peregryzki indekca
	
//proverka vuxoda za predelu indekca 
void String::check(int i)const
{
	if(i<0||rep->sz<=i)
		throw Range();
}

//vozvrachaet cimvol ctroki po indekcy (bez proverki vuxoda za predelu)
char String::read(int i) const
{
	return rep->s[i];
}

//perezapicuvaet cimvol (bez proverki na vuxod za predelu indekca)
void String::write(int i, char c)
{
	rep=rep->get_own_copy();
	rep->s[i]=c;
}

//peregryzka dl9 chteni9 i zapici ne konctantnux ob6ektov
String::Cref String::operator[](int i)
{
	check(i);
	return Cref(*this,i);
}

//vuzuvaetc9 dl9 konctantnux ob6ektov
char String::operator[](int i)const
{
	check(i);
	return rep->s[i];
}

//vozvrachaet razmer ctroki
int String::size()const
{
	return rep->sz;  
}

//dryz69 klacca

String& String::operator+=(const String& a)
{
	char* b=new char[rep->sz+a.rep->sz+1];//dobavl9em cimvol konca ctroki
	strcpy(b,rep->s);
	strcat(b,a.rep->s);
	rep->assign(rep->sz+a.rep->sz,b);
	delete b;//vucvobodit6 icpol6zovanyyu pam9t6
	return *this;
}
String& String::operator+=(const char* a)
{
	char* b=new char[rep->sz+strlen(a)+1];//dobavl9em cimvol konca ctroki
	strcpy(b,rep->s);
	strcat(b,a);//konkatenaci9 char*
	rep->assign(rep->sz+strlen(a),b);
	delete b;//ydalit6 pam9t6
	return *this;
}

//operatoru cravneni9

bool operator==(const String& x, const char* s)
{
	return strcmp(x.rep->s,s)==0;
}

bool operator==(const String& x, const String& y)
{
	return strcmp(x.rep->s,y.rep->s)==0;
}

bool operator!=(const String& x, const char* s)
{
	return strcmp(x.rep->s,s)!=0;
}

bool operator!=(const String& x, const String& y)
{
	return strcmp(x.rep->s,y.rep->s)!=0;
}

//peregryzka cout i cin
ostream& operator<<(ostream& a, const String& b)
{
	a <<b.rep->s;
	return a;
}
istream& operator>>(istream& a, String& b)
{
	--(b.rep->n); //otnimaem cculky
	char* s=new char[400];
	a >>s;
	b=s;//typoe pricvaivanie
	delete s;//ydal9em crazy je pam9t6		
	return a;
}

String operator+(const String& a, const String& b)
{
	cout <<"vuzvan operator +"<<endl;
	String c;
	c+=a;
	c+=b;
	return c;
}

String operator+(const String& a, const char* b)
{
	cout <<"vuzvan operator + char"<<endl;
	String c;
	c+=a;
	c+=b;
	return c;
}

//fynkci9 dl9 vudeleni podctroki
string String::sub(int a, int b)
{
	cout <<"mu v substr"<<endl;
	string s;
	if(a>=0&&b<rep->sz)
	{
		for(int i=a;i<=b;i++)
			s+=rep->s[i];
	}
	else
		throw Range();
	return s;
}
//fynkci9 dl9 izmeneni9 podctroki
String& String::substr(int a, int b)
{
	if(a>=0&&b<rep->sz)
	{
		substrN=a;
		substrK=b;
		return *this;
	}
	else
		throw Range();
}

//vozvrat ctroki v vide Ci
char* String::data()
{
	char* b=new char[strlen(rep->s)+1];
	strcpy(b,rep->s);
	return b;
}

//mex reg. vurajenii
bool String::rv(const char* s, string a)
{
	if(a=="!")
	{
		//cout <<"mu v rv "<<s<<endl;
		cout <<s<<endl;
		if(strstr(rep->s,s)==0)
			return false;
	}
	else
	{
		//cout <<"vedem poick v ctroke"<<endl;
		if(strstr(a.data(),s)==0)
			return false;
	}
	
	return true;
}

и файл main.cpp:

//reg. vurajeni9 v klacca String
#include <iostream>
using std::cout;
using std::endl;

#include "String.cpp"

int main()
{
	String b="Hellow world gacpada";
	cout <<b<<endl;
	if(b.rv("ell"))
	{
		cout <<"Naideno vxojdenie"<<endl;
	}
	
	if(b.rv("eld"))
	{
		cout <<"Naideno vxojdenie"<<endl;
	}
	else
	{
		cout <<"ne Naideno vxojdenie"<<endl;
	}
	
	string k;
	k="gacpada gacpada gacpada";
	if(b.rv("eld",k))
	{
		cout <<"Naideno vxojdenie"<<endl;
	}
	else
	{
		cout <<"ne Naideno vxojdenie"<<endl;
	}
	
	return 0;
}

Как мы видим ничего более сложного я придумывать не стал. Да и не к чему оно.

Решаем следующую задачку.

rss