Informatică, întrebare adresată de vegamid3253, 8 ani în urmă

ESTE URGENT!!!VA ROG! Se dau două șiruri de caractere care conțin doar litere. Să se afișeze toate aparițiile primului șir în cel de-al doilea.
Date de intrare
De pe prima linie se va citi primul șir, iar de pe a doua linie se va citi al doilea șir.
Date de ieșire
Pe ecran se vor afișa pozițiile pe care primul șir apare în cel de-al doilea. Pozițiile vor fi afișate în ordine crescătoare. Pozițiile șirului sunt numerotate începând de la 1.
Restricții
Șirurile vor conține minim 1 caracter și maxim 10 000 de caractere fiecare
Exemplu
Date de intrare
ana
banana
Date de ieșire
2 4.

Răspunsuri la întrebare

Răspuns de Apollyon
1

Răspuns:

#include <iostream>

#include <fstream>

#include <vector>

#include <string>

int main()

{

   std::vector<std::size_t> pozitiiSubSir;

   std::ifstream ifstream("siruri.in");

   if (!ifstream.good())

       exit(EXIT_FAILURE);

   std::string stringInitial, stringulCautat;

   std::getline(ifstream, stringulCautat);

   std::getline(ifstream, stringInitial);

   ifstream.close();

   std::size_t indexGasit = stringInitial.find(stringulCautat);

   while (indexGasit != std::string::npos)

   {

       pozitiiSubSir.push_back(indexGasit + 1);

       indexGasit = stringInitial.find(stringulCautat, indexGasit + stringulCautat.size() - 1);

   }

   for (auto &indexCurent : pozitiiSubSir)

       std::cout << indexCurent << std::endl;

   return 0;

}

Explicație:

Asta cred că e una dintre cele mai simpluțe metode.

O să ai un vector în care o să memorezi pozițiile la care au fost găsite substring-urile în interiorul string-ului principal ( nici nu ai nevoie de un vector, poți direct să le dai cout, aici e alegerea ta ).

Deschizi fișierul cu std::ifstream, dacă l-ai deschis cu succes, treci mai departe, altfel termini programul.

Ai două variabile, stringInițial și stringulCautat.

Apelezi de 2 ori std::getline(...) ( pentru că ai două linii ). Prima linie o salvezi în stringulCautat, a doua linie o salvezi în stringInitial după închizi ifstream-ul creat pentru că nu mai ai nevoie de el.

Acuma std::string fiind un obiect al clasei string are anumite metode implementate deja, una dintre ele este find(...) care caută dacă într-un string inițial există un substring. Dacă da, returnează indexul la care începe acel substring, de exemplu când apelăm prima dată

    stringInitial.find(stringulCautat);

în banana căutăm ana și găsim primul substring începând de la indexul 1 pe care-l salvăm în indexGasit.

Șmecheria” acuma e că pot exista mai multe substring-uri ( dacă te uiți, mai apare odată „ana” începând cu indexul 3 ) de asta o să ai un while care se repetă până când indexGăsit e diferit de npos ( care e o valoare returnată de funcția find(...) atunci când nu mai găseste substring-uri )

În while adaugi index-ul găsit + 1 ( deoarece îți zice că pozițiile sunt numerotate începând de la 1 ). Dacă nu adunam 1 am fi avut 1 ( că atâta returnează funcția ) dar nouă ne trebuie 2 și reapelezi funcția find tot cu același substring doar că de data asta începi să cauți de la index găsit ( care este 1 ) + dimensiunea substringului căutat ( care este 3 ) - 1 ( adică începem fix de unde apare al doilea subșir ( te poți uita peste cuvinte și o să-ți dai seama 100% care-i „șpilu” ).

La final afișezi pozițiile la care apare subșirul în șirul principal.


Apollyon: mai poți verifica dacă
((stringInitial.size() >= 1 && stringInitial.size() <= 10000) && (stringCautat.size() >= 1 && stringCautat.size() <= 10000))

Dacă nu se îndeplinește condiția poți termina programul.
Alte întrebări interesante