Е овако.
Написао сам једно од могућих решења, али оно може бити и једноставније. Код за овако једноставан задатак изгледа овако компликовано јер сам га писао баш по С++, користећи класе и остало. Може да буде и једноставнији ако је решење ближе С-у него С++. Користио сам неки старији компајлер код кога не постоји string као тип па је и то додатно проширило код. И додао сам да програм не буде "осетљив" на величину слова (није case sensitive). То је добро ако је тражена реч на почетку реченице, па почиње великим словом, а ти си куцао мало слово у претрази.
Програм ради онако како си тражио, прво се унесе реченица, затим реч, потом следи провера да ли та реч постоји у реченици, ако не постоји испише се порука, а ако постоји изврши се замена и испише нова реченица.
Све је то помало допринело комплексности и дужини кода.
Пример:
Ulaz:
Druga drugarica ceka druga i drugare.
- prva rec: druga
- druga rec: mesec
Izlaz:
Mesec drugarica ceka mesec i drugare.
Прво ћу поставити цео код, а онда испод следе објашњења.
Kod:
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#define DUZ 201
class String {
public:
String () { linija = new char [DUZ]; }
~String () { delete [] linija; linija = NULL; }
int pronadji (String& rec);
void zameni (String& prva_rec, String& druga_rec);
private:
char* linija;
friend ostream& operator<< (ostream& it, String& s)
{ if (s.linija) it << s.linija; return it; }
friend istream& operator>> (istream& ut, String& s)
{ ut.getline(s.linija, DUZ); return ut; }
};
int String::pronadji (String& rec) {
int i, j;
String pomocni, pom_rec, reci;
i = 0;
do {
if (linija[i] >= 'A' && linija[i] <= 'Z')
pomocni.linija[i] = linija[i] + 'a' - 'A';
else pomocni.linija[i] = linija[i];
} while (linija[i++] != '\0');
i = 0;
do {
if (rec.linija[i] >= 'A' && rec.linija[i] <= 'Z')
pom_rec.linija[i] = rec.linija[i] + 'a' - 'A';
else pom_rec.linija[i] = rec.linija[i];
} while (rec.linija[i++] != '\0');
for (i = 0; pomocni.linija[i] != '\0'; i++) {
j = 0;
while (pomocni.linija[i] >= 'a' && pomocni.linija[i] <= 'z')
reci.linija[j++] = pomocni.linija[i++];
reci.linija[j] = '\0';
if (strcmp (reci.linija, pom_rec.linija) == 0) return 1;
}
return 0;
}
void String::zameni (String& prva_rec, String& druga_rec) {
int i, j, k, l;
String reci, pom_rec;
String novi;
i = 0;
do {
if (isupper(prva_rec.linija[i]))
pom_rec.linija[i] = prva_rec.linija[i] + 'a' - 'A';
else pom_rec.linija[i] = prva_rec.linija[i];
} while (prva_rec.linija[i++] != '\0');
for (i = 0, l = 0; linija[i] != '\0'; i++) {
j = 0;
k = i;
while (isupper(linija[k]) || islower(linija[k]))
if (isupper(linija[k]))
reci.linija[j++] = linija[k++] + 'a' - 'A';
else reci.linija[j++] = linija[k++];
reci.linija[j] = '\0';
if (strlen(reci.linija) > 0)
if (strcmp (reci.linija, pom_rec.linija) == 0) {
i = k;
for (j = 0; j < strlen(druga_rec.linija); l++, j++)
novi.linija[l] = druga_rec.linija[j];
}
else
for (; i < k; i++, l++)
novi.linija[l] = linija[i];
novi.linija[l++] = linija[i];
}
novi.linija[l] = '\0';
if (islower(novi.linija[0])) novi.linija[0] = novi.linija[0] + 'A' - 'a';
delete [] linija;
linija = novi.linija;
novi.linija = NULL;
}
int main () {
String recenica;
String prva_rec, druga_rec;
cout << "\nUlaz:" << endl;
cin >> recenica;
cout << "- prva rec: ";
cin >> prva_rec;
if (recenica.pronadji(prva_rec)) {
cout << "- druga rec: ";
cin >> druga_rec;
recenica.zameni(prva_rec, druga_rec);
cout << "\nIzlaz:\n" << recenica << endl;
}
else cout << "\nIzlaz:\nRec " << prva_rec << " se ne nalazi u recenici.";
return 0;
}
Kod:
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#define DUZ 201
Прва датотека коју укључујемо је датотека за улаз и излаз која нам омогућава да уносимо и добијамо податке.
Друга је за неке функције за рад са стринговима.
Трећа нам треба због функција за проверу да ли су слова велика, или мала.
На крају је дефинисана максимална дужина стринга (речи, или реченице).
Kod:
class String {
public:
String () { linija = new char [DUZ]; }
~String () { delete [] linija; linija = NULL; }
int pronadji (String& rec);
void zameni (String& prva_rec, String& druga_rec);
private:
char* linija;
friend ostream& operator<< (ostream& it, String& s)
{ if (s.linija) it << s.linija; return it; }
friend istream& operator>> (istream& ut, String& s)
{ ut.getline(s.linija, DUZ); return ut; }
};
Класа String.
Има конструктор који ће при креирању објекта типа
String направити динамички низ карактера (
char) дужине
DUZ.
Следећи је деструктор који се имплицитно активира при уништавању објекта типа
String. Нпр. када се излази из функције у којој је створен такав објекат, тај објекат ће бити уништен. Тада се позива деструктор. Деструктор у овом случају уништава динамички низ карактера.
Имамо две јавне методе за проналажење одређене речи и замену одређене речи другом речи. Речи су типа
String. У класи се не може користити тип те класе, већ показивач, или у овом случају референца (
&) на ту класу.
Постоји један приватан атрибут који се зове
linija и који је типа
char* - показивач на карактер.
linija ће показивати на динамички низ карактера при креирању објекта типа
String.
На крају су две пријатељске глобалне функције за унос стринга и његово исписивање. Није битно у ком се делу налазе:
public,
private, или
protected који овде немамо. Ове две функције омогућавају да се стрингови уносе и исписују на следећи начин:
Kod:
String recenica;
cin >> recenica;
cout << recenica;
Kod:
int String::pronadji (String& rec) {
int i, j;
String pomocni, pom_rec, reci;
i = 0;
do {
if (linija[i] >= 'A' && linija[i] <= 'Z')
pomocni.linija[i] = linija[i] + 'a' - 'A';
else pomocni.linija[i] = linija[i];
} while (linija[i++] != '\0');
i = 0;
do {
if (rec.linija[i] >= 'A' && rec.linija[i] <= 'Z')
pom_rec.linija[i] = rec.linija[i] + 'a' - 'A';
else pom_rec.linija[i] = rec.linija[i];
} while (rec.linija[i++] != '\0');
for (i = 0; pomocni.linija[i] != '\0'; i++) {
j = 0;
while (pomocni.linija[i] >= 'a' && pomocni.linija[i] <= 'z')
reci.linija[j++] = pomocni.linija[i++];
reci.linija[j] = '\0';
if (strcmp (reci.linija, pom_rec.linija) == 0) return 1;
}
return 0;
}
Ово је дефиниција функције за проналажење реци у реченици.
int String:: pronadji (String& rec)
Функција враћа
0 ако реч не постоји у реченици, а
1 ако постоји. С++ има логички тип
bool и треба користити
true и
false, али као што сам рекао, користио сам стари компајлер.
String:: означава да функција, тј. метода припада класи
String. Ово је разрешавање досега.
Функција има један аргумент типа референца на
String.
int i, j;
String pomocni, pom_rec, reci;
Имамо две целобројне променљиве и три стринга.
Прво ћемо реченицу уписати у
pomocni са свим малим словима. Затим се у
pom_rec уписује реч коју тражимо, такође са свим малим словима. У
reci се уписује једна по једна реч из реченице и пореди са траженом речи све док се она не пронађе.
i = 0;
do {
if (linija >= 'A' && linija <= 'Z')
pomocni.linija = linija + 'a' - 'A';
else pomocni.linija = linija;
} while (linija[i++] != '\0');
i = 0;
do {
if (rec.linija >= 'A' && rec.linija <= 'Z')
pom_rec.linija = rec.linija + 'a' - 'A';
else pom_rec.linija = rec.linija;
} while (rec.linija[i++] != '\0');
Први код преписује реченицу у pomocni, а други тражену реч у pom_rec.
Обрати пажњу да pom_rec и остали стрингови нису заиста прави стрингови. То су објекти типа класе String, која садржи динамички низ карактера linija. Та linija је заправо прави стринг, када се на крај дода знак за крај стринга '\0'.
for (i = 0; pomocni.linija != '\0'; i++) {
j = 0;
while (pomocni.linija >= 'a' && pomocni.linija <= 'z')
reci.linija[j++] = pomocni.linija[i++];
reci.linija[j] = '\0';
if (strcmp (reci.linija, pom_rec.linija) == 0) return 1;
}
return 0;
Овде се врши претрага. Прво се препише једна реч из pomocni у reci, а затим се reci пореди са pom_rec. Ако се поклапају функција враћа 1. Када се стигне до краја pomocni, тј. када се све речи упореде са pom_rec, значи да није било поклапања и враћа се 0.