PDA

Tam Sürümünü Görmek İçin : C++ string inde string i boşluk içermeyecek hale getirmek


kkirtac
29/08/2006, 22:58
arkadaşlar merhaba : örnekte verdigim gibi boşluklar içeren bir string teki boşlukları yok edip düz bir string oluşturmak için çabalayıp durdum sonunda çalışan bişey yaptım ama fazla uğraştım gibime geliyor, örnek bir string :

a man a plan a canal panama

elde etmek istedigim format : amanaplanacanalpanama

ben kendi çözümümü yazayım , farklı ya da daha pratik çözümü olan arkadaşlar da yazarsa memnun olurum , kolay gelsin.

string str ;
cout << "stringi giriniz: " << endl ;
getline(cin, str) ;
int posctr = 0 ; //bosluk sayisini tutuyor
int positions[100] ; //bosluklarin pozisyonlarini tutuyor
int pos = str.find(" ") ;
positions[0] = 0 ;
while( pos != string::npos )
{
positions[++posctr] = pos ;
pos = str.find(" ", pos+1) ;

}
positions[++posctr] = str.length();
string str1 ;
str1+=str[0];
for(int j=0 ; j < posctr ; j++)
for(int k=positions[j]+1; k<=positions[j+1]-1 ; k++ )
str1+=str[k] ;
:garip:


vs
29/08/2006, 23:18
ben pek string class ının özelliklerini kullanmayı bilmiyorum o yüzden biraz c-style oldu:


#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main(){
char cumle[100];
string yenicumle;
gets(cumle);

for(int i=0;cumle[i]!='\0';i++)
if(cumle[i]!=' ') yenicumle+=cumle[i];

cout<<yenicumle;

getchar(); return 0;
}

kkirtac
29/08/2006, 23:37
çok kısa net ve akıllıca , teşekkürler :)

acehreli
30/08/2006, 03:15
Bunun icin iki yol daha gorebiliyorum:

1) Eger elimizdeki dizgiyi degistiriyorsak; once std::remove islevini, hemen ardindan da string::erase uye islevini kullanabiliriz.

2) Eger sonucta yeni bir dizgi elde edeceksek; dogrudan std::remove_copy islevini kullanabiliriz.

Bir ornek program:


#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

/**
* Verilen satiri bir baslikla birlikte gosterir
*/
void goster(string const & baslik, string const & satir)
{
cout << baslik << ": " << satir << '\n';
}

/**
* Kaynak ve sonuc string'leri gosterir
*/
void goster_kaynak_ve_sonuc(string const & baslik,
string const & kaynak,
string const & sonuc)
{
goster(baslik + " (kaynak)", kaynak);
goster(baslik + " (sonuc) ", sonuc);
}

/**
* Verilen dizgiden verilen karakteri cikartir. remove islevi ne tur bir
* yapi uzerinde calistigini bilmedigi icin, dizgi'den karakter
* eksiltemez. Onun icin, bizim daha sonradan string::erase islevini
* cagirmamiz gerekir.
*
* Bunu is hic string::iterator yazmadan, geleneksel olarak tek hamlede
* soyle de yazilir:
*
* dizgi.erase(remove(dizgi.begin(), dizgi.end(), karakter));
*/
void dene_remove_sonra_erase(string dizgi, char istenmeyen)
{
cout << "\n[ remove, sonra erase ]\n";
goster("once (dizgi)", dizgi);

// Karakterler cikartilinca yeni sonumuzun nerede oldugunu aklimizda tutalim
string::iterator yeni_son = remove(dizgi.begin(), dizgi.end(), istenmeyen);

// Yeni sondan eski sona kadar olan karakterleri silelim
dizgi.erase(yeni_son, dizgi.end());

goster("sonra (dizgi)", dizgi);
}

/**
* Bu islev, verilen kaynak string icindeki butun karakterleri,
* istenmedigi belirtilen karakter haric olmak uzere yeni bir dizgiye
* kopyaliyor.
*/
void dene_remove_copy(const string & kaynak, char istenmeyen)
{
string sonuc;

cout << "\n[ remove_copy ]\n";
goster_kaynak_ve_sonuc("once ", kaynak, sonuc);

remove_copy(kaynak.begin(), kaynak.end(), // <-- nereden?
back_inserter(sonuc), // <-- nereye?
istenmeyen); // <-- ne haric?

goster_kaynak_ve_sonuc("sonra", kaynak, sonuc);
}

void dene(string const & ornek, char istenmeyen)
{
dene_remove_sonra_erase(ornek, istenmeyen);
dene_remove_copy(ornek, istenmeyen);
}

int main()
{
dene("a man a plan a canal panama", ' ');
}



Daha genel olarak, eger istenmeme kosulu daha karmasiksa, o zaman da std::remove_copy_if kullanilabilir. Bu ornekte kistas olarak 'sesli' adli islev kullaniliyor:


#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

/**
* Verilen karakter sesliyle 'true', degilse 'false' dOndUrur.
* [Turkceye uydugunu soyleyemeyecegim :)]
*/
bool sesli(char karakter)
{
bool sonuc = false;

switch (karakter) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
sonuc = true;
break;

default:
sonuc = false;
break;
}

return sonuc;
}

string sesliler_olmadan(string const & kaynak)
{
string sonuc;
remove_copy_if(kaynak.begin(), kaynak.end(), // <-- nereden?
back_inserter(sonuc), // <-- nereye?
sesli); // <-- kistas?
return sonuc;
}


int main()
{
cout << sesliler_olmadan("biz heybelide mehtaba cikar, armut toplardik");
}


Ali

acehreli
30/08/2006, 08:42
Yukarida bir aciklama satirinda bir yanlisim oldugunu farkettim:


dizgi.erase(remove(dizgi.begin(), dizgi.end(), karakter));


yazmistim. Dogrusu soyle olacak:


dizgi.erase(remove(dizgi.begin(), dizgi.end(), karakter), dizgi.end());


Ali

kkirtac
30/08/2006, 13:10
çok faydalı, teşekkürler :)

kkirtac
01/09/2006, 17:32
aynı sonucu elde edebilecegimiz bir diger yontem cstring kutuphanesine ait strtok fonksiyonunu kullanmak...örnek aşağıdaki gibi.

#include <iostream>
using std::cout;
using std::endl;

#include <cstdlib>

#include <cstring> // prototype for strtok
using std::strtok;

#include <string>
using std::string;

int main()
{
char cumle[] = "Bu cumle dort bosluktan olusmaktadir";
char *kelimeIsaretcisi;
string boslukYok ;

cout << "Bosluklari yokedilecek string :\n\n" << cumle << "\n\n" ;

// kelimelere ayirmaya basla
kelimeIsaretcisi = strtok( cumle, " " );

// Isaretci NULL olana kadar ayirmaya devam et
while ( kelimeIsaretcisi != NULL )
{
boslukYok += kelimeIsaretcisi ;
kelimeIsaretcisi = strtok( NULL, " " ); // sonraki kelimeyi al
} // end while

cout << "bosluksuz string : " << boslukYok << endl ;

system("PAUSE") ;

return 0;
} // end main