Ben şunu kullanıyorum:
replace (str1.begin(), str1.end(), 'a' , '')
Ancak bu derleme hatası veriyor.
Ben şunu kullanıyorum:
replace (str1.begin(), str1.end(), 'a' , '')
Ancak bu derleme hatası veriyor.
Yanıtlar:
Temel olarak, replace
bir karakteri başka bir karakterle değiştirir ve ''
bir karakter değildir. Aradığınız şey erase
.
Aynı soruna cevap veren bu soruya bakın . Senin durumunda:
#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Veya boost
bu sizin için bir seçenekse kullanın , örneğin:
#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");
Bütün bunlar referans web sitelerinde iyi bir şekilde belgelenmiştir . Ancak bu işlevleri bilmiyorsanız, bu tür şeyleri elle kolayca yapabilirsiniz:
std::string output;
output.reserve(str.size()); // optional, avoids buffer reallocations in the loop
for(size_t i = 0; i < str.size(); ++i)
if(str[i] != 'a') output += str[i];
O(n^2)
mi?
n
orijinal dize uzunluğu. Her giriş karakteri için 1 karakter testi yapıyorum O(1)
ve 0 veya 1 karakter ekliyorum. Karakter eklemek O(1)
yeterli bellek ayrılmışsa veya O(current_length)
yeni bir tampon ayrılmışsa. Döngüden output.reserve(str.size())
önce yaparsanız , bu asla olmaz ve küresel bir O(n)
maliyetiniz olur. Aksi takdirde asimptotik olarak, maliyetin O(n . log(n) )
STL konteyner yeniden tahsis stratejisinden kaynaklandığını tahmin ediyorum .
for
en uygun olanıdır.
Algoritma , belirli bir sıradaki öğe başınastd::replace
çalışır (bu nedenle, öğeleri farklı öğelerle değiştirir ve hiçbir şeyle değiştiremez ). Ama boş karakter yok . Bir diziden öğeleri kaldırmak istiyorsanız, aşağıdaki öğelerin taşınması gerekir ve bu şekilde çalışmaz.std::replace
Bunu başarmak için std::remove
( ile birliktestd::erase
) kullanmayı deneyebilirsiniz .
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
string RemoveChar(string str, char c)
{
string result;
for (size_t i = 0; i < str.size(); i++)
{
char currentChar = str[i];
if (currentChar != c)
result += currentChar;
}
return result;
}
Ben böyle yaptım.
Veya Antoine'ın bahsettiği gibi yapabilirsiniz:
Aynı soruna cevap veren bu soruya bakın . Senin durumunda:
#include <algorithm> str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
Filtrelenmiş dizeyle doldurmak için bir predicate
ve / veya boş olmayan seçeneğiniz varsa, şunları output
dikkate alırım:
output.reserve(str.size() + output.size());
std::copy_if(str.cbegin(),
str.cend(),
std::back_inserter(output),
predicate});
Orijinal soruda yüklem [](char c){return c != 'a';}
Bu kod, karakterlerin tekrarını kaldırır, yani giriş aaabbcc ise çıktı abc olacaktır. (bu kodun çalışması için dizinin sıralanması gerekir)
cin >> s;
ans = "";
ans += s[0];
for(int i = 1;i < s.length();++i)
if(s[i] != s[i-1])
ans += s[i];
cout << ans << endl;
Diğer yanıtlara dayanarak, belirli bir dizedeki tüm özel karakterleri kaldırdığım bir örnek daha var:
#include <iostream>
#include <string>
#include <algorithm>
std::string chars(".,?!.:;_,!'\"-");
int main(int argc, char const *argv){
std::string input("oi?");
std::string output = eraseSpecialChars(input);
return 0;
}
std::string eraseSpecialChars(std::string str){
std::string newStr;
newStr.assign(str);
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < chars.length(); j++ ){
if(str.at(i) == chars.at(j)){
char c = str.at(i);
newStr.erase(std::remove(newStr.begin(), newStr.end(), c), newStr.end());
}
}
}
return newStr;
}
Giriş ve Çıkış:
Input:ra,..pha
Output:rapha
Input:ovo,
Output:ovo
Input:a.vo
Output:avo
Input:oi?
Output:oi
En iyi cevaptan% 70 Daha Hızlı Çözüm
void removeCharsFromString(std::string& str, const char* charsToRemove)
{
size_t charsToRemoveLen = strlen(charsToRemove);
std::remove_if(str.begin(), str.end(), [charsToRemove, charsToRemoveLen](char ch) -> bool
{
for (int i = 0; i < charsToRemoveLen; ++i) {
if (ch == charsToRemove[i])
return true;
}
return false;
});
}
Sanırım std: remove yöntemi çalışıyor, ancak kapsayıcılarla bazı uyumluluk sorunları veriyordu, bu yüzden bu küçük işlevi yazdım:
string removeCharsFromString(const string str, char* charsToRemove )
{
char c[str.length()+1]; // + terminating char
const char *p = str.c_str();
unsigned int z=0, size = str.length();
unsigned int x;
bool rem=false;
for(x=0; x<size; x++)
{
rem = false;
for (unsigned int i = 0; charsToRemove[i] != 0; i++)
{
if (charsToRemove[i] == p[x])
{
rem = true;
break;
}
}
if (rem == false) c[z++] = p[x];
}
c[z] = '\0';
return string(c);
}
Sadece kullan
myString = removeCharsFromString (myString, "abc \ r");
ve verilen karakter listesinin tüm oluşumunu kaldıracaktır.
Döngü ilk eşleşmeden sonra döndüğü için bu biraz daha verimli olabilir, bu yüzden aslında daha az karşılaştırma yapıyoruz.
Ben böyle yaparım:
std::string removeAll(std::string str, char c) {
size_t offset = 0;
size_t size = str.size();
size_t i = 0;
while (i < size - offset) {
if (str[i + offset] == c) {
offset++;
}
if (offset != 0) {
str[i] = str[i + offset];
}
i++;
}
str.resize(size - offset);
return str;
}
Temel olarak, ne zaman belirli bir karakter bulsam, ofseti ilerletirim ve karakteri doğru dizine yerleştiririm. Bunun doğru mu yoksa verimli mi olduğunu bilmiyorum, (yine) C ++ 'dan başlıyorum ve bu konudaki herhangi bir girdiyi takdir ediyorum.
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
Büyük Y ve S'yi str'den kaldırarak "bizimtring'imizi" bırakır.
Bunun remove
bir algoritma olduğunu ve başlığın <algorithm>
dahil edilmesi gerektiğini unutmayın .
''
aslında bir karakter değil.