Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

poziom 3 rozdział 28

Ostatnio zmodyfikowano 2015-10-15 22:03
Autor Wiadomość
1programista
Temat założony przez niniejszego użytkownika
poziom 3 rozdział 28
» 2015-10-14 21:35:17
Witam.
Mimo że już było to zadanie na forum nie widziałem rozwiązania mojego problemu.
Zad. domowe
Napisz program, który z podanego łańcucha znaków usunie powtarzające się spacje występujące obok siebie i zastąpi wszystkie znaczniki <b> oraz </b> znacznikami oraz . Tekst, który powstanie w wyniku przeprowadzenia wspomnianych operacji wypisz na ekran.
Mój kod jeszcze nie w pełni skończony:

#include<iostream>
#include <string>
std::string konwertuj( std::string & sTekst )
{
    std::string sWynik;
    //TODO: tu nale¿y napisaæ kod realizuj¹cy zadanie
    size_t pozycja, k;
    int i=0;
    pozycja = sTekst.find(" ");
    do
   {
     k=pozycja;
     pozycja = sTekst.find(" " ,pozycja+1 );
    if(k +1== pozycja)
    sTekst.erase(pozycja,1);
    i++;
   }while(/*pozycja != std::string::npos &&*/ i< 200 );
   sWynik=sTekst;
   std::cout<<" pozycja= "<<pozycja<<" pozycja2= "<<k<<" ilosc powt= "<<i;
   i=0;
   pozycja=0;
   do
   {
       pozycja = sTekst.find("</b>");
       if(pozycja != std::string::npos)
       {
        sTekst.insert(pozycja,"[/b]");
        sTekst.erase(pozycja+4,4);
       }
       i++;
   }while(pozycja != std::string::npos && i<200);
   std::cout<<std::endl<<"pozycja= "<<pozycja;
    return sWynik;
}
int main()
{
    std::string tekst = "<b>to jest </b> testowy            napis     <b>:)";
    std::cout << konwertuj( tekst ) << std::endl;
    return 0;
}


Musiałem wstawić dodatkowe zmienne "i" aby pętla się zakończyła.
Dlaczego zmienna "pozycja" przybiera kosmiczną wartość mimo że pętla się wykona max 200 razy?
Dlaczego std::string::npos nie kończy pętli przecież według kursu metoda (w pętli) .find() na obiekcie sTekst przykład:
"pozycja = sTekst.find(" " ,pozycja+1 );" zakończy się kiedyś std::string::npos ?
P-138582
carlosmay
» 2015-10-14 22:22:27
Musiałem wstawić dodatkowe zmienne "i" aby pętla się zakończyła.
 nie musiałeś, bez i czy z i szukasz poza napisem.

Dlaczego zmienna "pozycja" przybiera kosmiczną wartość mimo że pętla się wykona max 200 razy?
ponieważ następny szukany znak znajduje tak daleko.

Dlaczego std::string::npos nie kończy pętli przecież według kursu metoda (w pętli) .find() na obiekcie sTekst przykład:
 kończy, tylko nie w tym miejscu co chcesz.

pozycja = sTekst.find(" " ,pozycja+1 );" zakończy się kiedyś std::string::npos
 tak, tylko trzeba odpowiednio szukać. Dobrym dowodem na działanie
std::string::npos
 jest kończenie się programu (nie zapętla się) po usunięciu 'i'.
P-138583
1programista
Temat założony przez niniejszego użytkownika
» 2015-10-15 16:06:33
Dzięki za odpowiedź.
Carlosmay miałeś rację co do usunięcia dodatkowych zmiennych " i " widocznie coś z moim komp. nie tak bo się zawieszał.
Poprawiłem kod:
C/C++
#include<iostream>
#include <string>
std::string konwertuj( std::string & sTekst )
{
    std::string sWynik;
    size_t pozycja, k;
    int i = 0;
    pozycja = sTekst.find( " " );
    do
    {
        k = pozycja;
        pozycja = sTekst.find( " ", pozycja + 1 );
        if( k + 1 == pozycja )
             sTekst.erase( pozycja, 1 );
       
        i++;
    } while( /*pozycja != std::string::npos && */ i < 200 );
   
    std::cout << " pozycja= " << pozycja << " pozycja2= " << k << " ilosc powt= " << i << std::endl;
    i = 0;
    pozycja = 0;
    do
    {
        pozycja = sTekst.find( "<" );
        if( pozycja != std::string::npos )
        {
            sTekst.insert( pozycja, "[" );
            sTekst.erase( pozycja + 1, 1 );
        }
        i++;
    } while( pozycja != std::string::npos /*&& i<200 */ );
   
    do
    {
        pozycja = sTekst.find( ">" );
       
        if( pozycja != std::string::npos )
             sTekst.insert( pozycja, "]" );
       
        sTekst.erase( pozycja + 1, 1 );
    } while( pozycja != std::string::npos );
   
    std::cout << std::endl << "pozycja= " << pozycja << std::endl << std::endl;
   
    sWynik = sTekst;
    return sWynik;
}
int main()
{
    std::string tekst = "<b>to jest </b> testowy            napis     <b>:)";
    std::cout << konwertuj( tekst ) << std::endl;
    return 0;
}

Tylko że po usunięciu "i" w warunku   while(/*pozycja != std::string::npos && */i< 200);
program nie usuwa długich spacji.
W drugiej części programu nie wiem dlaczego usuwa mi na początku znak " [ "  ?
Myślałem że metoda .find() działa tylko na zakresie tekstu zmiennej  "sTekst"  załóżmy że zmienna  "sTekst"  ma 100 znaków
to zmienna  "pozycja" przyjmuje wartości od 0 do 99 a tu "pozycja"  wychodzi poza zakres.
Jeszcze raz proszę kogoś o wyjaśnienie łopatologiczne ;) jak to z tym jest.
 
P-138598
carlosmay
» 2015-10-15 18:13:26
Strasznie długi i zawiły kod.
Masz zredukować wielokrotną spację do jednego znaku.
Najłatwiej szukasz podwójnej spacji i usuwasz znak z pozycji 'pozycja'.
Następnie uruchamiasz szukanie od 'pozycja'. W ten sposób znajdziesz od razu następne, aż zostanie jedna, którą pominie i przejdzie szukać dalej.

P-138620
carlosmay
» 2015-10-15 18:23:28
C/C++
pozycja = sTekst.find( " " );
do
{
    k = pozycja;
    pozycja = sTekst.find( " ", pozycja + 1 );
    if( k + 1 == pozycja )
         sTekst.erase( pozycja, 1 );
 Tutaj szukasz znaku, nic z nim nie robisz i znów  szukasz?
Zmienna 'k' nie jest ci do niczego potrzebna.
Jeśli używasz pętli 'do while' nie musisz szukać przed pętla
i myślę, że łatwiej będzie z 'while'.
P-138623
1programista
Temat założony przez niniejszego użytkownika
» 2015-10-15 20:37:42
Szukam znaku i przypisuję jego pozycję do zmiennej 'k' aby później porównać czy następna spacja jest koło siebie (przy 'k')
Zrobię tak jak mi radzisz od razu z podwójnej spacji
C/C++
#include<iostream>
#include <string>
std::string konwertuj( std::string & sTekst )
{
    std::string sWynik;
    size_t pozycja;
    int i = 0;
   
    do
    {
       
        pozycja = sTekst.find( "  " );
        if( pozycja != std::string::npos )
             sTekst.erase( pozycja, 1 );
       
        i++;
    } while( pozycja != std::string::npos );
   
   
    sWynik = sTekst;
    return sWynik;
}
int main()
{
    std::string tekst = "<b>to jest </b> testowy            napis     <b>:)";
    std::cout << konwertuj( tekst ) << std::endl;
    return 0;
}
Ok działa dzięki.:)
Muszę gdzieś doczytać o mechanizmie wyszukiwania metody .find()bo te zmienne pozycja są kosmiczne
P-138643
carlosmay
» 2015-10-15 22:03:21
int i = 0;
 czy zmiennej 'i' do czegoś używasz?

sWynik = sTekst;
 a ten zabieg lepiej dać na początek, żeby pracować na kopii danych.
Teraz działasz na oryginale i na koniec robisz kopię zmodyfikowanych danych
(możesz od razu zwrócić
return sTekst;
P-138662
« 1 »
  Strona 1 z 1