সি ++ স্ট্রিংয়ে কোনও চরের সমস্ত উপস্থিতি কীভাবে সরাবেন


105

আমি নিম্নলিখিত ব্যবহার করছি:

replace (str1.begin(), str1.end(), 'a' , '')

তবে এটি সংকলন ত্রুটি দিচ্ছে।


9
''প্রকৃতপক্ষে একটি চরিত্র নয়।
এন। 'সর্বনাম' মি।

5
আচ্ছা, আপনি যে ত্রুটিটি পাচ্ছেন তা অবশ্যই নিশ্চিতভাবে সহায়তা করবে।
এসবিআই

4
সুন্দর হোন, এমন অনেকগুলি প্রসঙ্গ আছে যেখানে প্রতিস্থাপন করা একটি উপযুক্ত চিন্তা, কেবল এটিই নয় one
রিচার্ডপ্লানকেট

উত্তর:


176

মূলত, replaceএকটি চরিত্রকে অন্যের সাথে প্রতিস্থাপন করে এবং ''একটি চরিত্র নয়। আপনি যা খুঁজছেন তা হ'ল erase

এই সমস্যাটি দেখুন যা একই সমস্যার উত্তর দেয়। আপনার ক্ষেত্রে:

#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());

বা এটি boostযদি আপনার জন্য একটি বিকল্প হয় তবে ব্যবহার করুন:

#include <boost/algorithm/string.hpp>
boost::erase_all(str, "a");

এই সমস্ত রেফারেন্স ওয়েবসাইটগুলিতে ভালভাবে নথিভুক্ত । তবে আপনি যদি এই ফাংশনগুলি সম্পর্কে না জানতেন তবে আপনি সহজেই হাতে হাতে এই জাতীয় জিনিসগুলি করতে পারেন:

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];

4
আপনি সরবরাহ করা অ্যালগরিদম না O(n^2)?
jww

4
@jww: আমি ধরে নিয়েছি আপনি শেষ কোডের নমুনার কথা বলছেন এবং nএটি মূল স্ট্রিংয়ের দৈর্ঘ্য। প্রতিটি ইনপুট চরিত্রের জন্য, আমি 1 টি অক্ষর পরীক্ষা করি O(1), এবং 0 বা 1 অক্ষর সংযোজন করি। চরিত্র সংযোজন O(1)যথেষ্ট মেমরি সংরক্ষিত, বা O(current_length)যদি একটি নতুন বাফার বরাদ্দ করা হয়। আপনি যদি output.reserve(str.size())লুপের আগে করেন তবে এটি কখনই ঘটে না এবং আপনার বিশ্বব্যাপী O(n)ব্যয় হয়। অন্যথায় অ্যাসিপোটোটিকভাবে, আমার ধারণা O(n . log(n) ), এসটিএল কনটেইনার পুনর্নির্মাণ কৌশলটির কারণে ব্যয় হয়েছে ।
এন্টোইন

5
আমার # অন্তর্ভুক্ত <আলগোরিদিম>
এস মেইডেন

চমৎকার উত্তর. উত্তরে যদি অনেকগুলি সমাধান থাকে তবে এটি সর্বদা ভাল। আমার জন্য, এর সাথে সমাধানটি forসবচেয়ে উপযুক্ত।
দিমিত্রি নিচিপোরেনকো

পছন্দ করুন আপনার যদি প্রিকেট বা খালি খালি আউটপুট থাকে তবে আমি বরং বিবেচনা করব: আউটপুট.রিজার (স্ট্রাইজার সাইজ () + আউটপুট.সাইজ ()); std :: copy_if (str.begin (), str.end (), std :: back_inserter (আউটপুট), [] (চর গ) {রিটার্ন প্রিিকেট (সি);});
জিমিফিকি 22'19

11

অ্যালগরিদম std::replaceকাজ উপাদান প্রতি একটি প্রদত্ত ক্রম উপর (তাই এটা ভিন্ন উপাদানের সঙ্গে উপাদান প্রতিস্থাপন, এবং সঙ্গে এটি প্রতিস্থাপন করতে পারবেন না কিছুই )। তবে কোনও খালি চরিত্র নেই। আপনি যদি একটি ক্রম থেকে উপাদানগুলি সরাতে চান তাহলে, নিম্নলিখিত উপাদানের করা থাকতে হবে সরানো , এবং std::replaceভালো কাজ করে না।

এটি অর্জনের জন্য আপনি std::remove( একসাথেstd::erase ) ব্যবহার করার চেষ্টা করতে পারেন ।

str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());

9

ব্যবহার copy_if:

#include <string>
#include <iostream>
#include <algorithm>
int main() {
    std::string s1 = "a1a2b3c4a5";
    char s2[256];
    std::copy_if(s1.begin(), s1.end(), s2, [](char c){return c!='a';});
    std::cout << s2 << std::endl;
    return 0;
}

3
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;
}

এইভাবে আমি এটি করেছি।

অথবা আপনি এন্টোইন যেমন উল্লেখ করেছেন তেমন করতে পারেন:

এই সমস্যাটি দেখুন যা একই সমস্যার উত্তর দেয়। আপনার ক্ষেত্রে:

#include <algorithm>
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());

1

ফিল্টারিং স্ট্রিংটি পূরণ করার জন্য আপনার কাছে predicateএবং / বা কোনও খালি ফাঁকা outputথাকার ক্ষেত্রে, আমি বিবেচনা করব:

output.reserve(str.size() + output.size());  
std::copy_if(str.cbegin(), 
             str.cend(), 
             std::back_inserter(output), 
             predicate});

মূল প্রশ্নে হলেন প্রিডিকেট [](char c){return c != 'a';}


1

এই কোডটি অক্ষরের পুনরাবৃত্তি সরিয়ে দেয় অর্থাত্, যদি ইনপুটটি aaabbcc হয় তবে আউটপুটটি abc হবে। (এই কোডটি কাজ করার জন্য অ্যারে অবশ্যই বাছাই করা উচিত)

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;

0

অন্যান্য উত্তরের উপর ভিত্তি করে, এখানে আরও একটি উদাহরণ দেওয়া হয়েছে যেখানে আমি একটি নির্দিষ্ট স্ট্রিংয়ে সমস্ত বিশেষ অক্ষর সরিয়েছি:

#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; 
}

ইনপুট বনাম আউটপুট:

Input:ra,..pha
Output:rapha

Input:ovo,
Output:ovo

Input:a.vo
Output:avo

Input:oi?
Output:oi

0

শীর্ষ উত্তরের চেয়ে দ্রুততর সমাধান 70%

        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;
                });
        }

-1

আমি অনুমান করি যে পদ্ধতিটি এসটিডি: কাজগুলি সরিয়ে ফেলুন তবে এতে অন্তর্ভুক্তগুলির সাথে সামঞ্জস্যের কিছু সমস্যা দেওয়া হচ্ছিল তাই আমি এই ছোট্ট ফাংশনটি লিখেছি:

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);
}

শুধু হিসাবে ব্যবহার করুন

মাই স্ট্রিং = অপসারণচরফ্র্যামস্ট্রিং (মাই স্ট্রিং, "অ্যাবসি \ আর");

এবং এটি প্রদত্ত চর তালিকার সমস্ত উপস্থিতি সরিয়ে ফেলবে।

প্রথম ম্যাচের পরে লুপটি ফিরে আসায় এটি আরও কার্যকর হতে পারে, তাই আমরা আসলে তুলনা কম করি।


4
আপনি সঠিক অনুমান। নিজের লেখার চেয়ে বরং আপনি কেন স্ট্যান্ডার্ড সি ++ হেডার ব্যবহার করতে পারবেন না তা আরও ভালভাবে সন্ধান করুন।
xtofl

ওয়েল এটি একটি ব্যক্তিগত মতামত, আপনি বিশেষত যা প্রয়োজন তা লেখার পরিবর্তে 3 য় কোডটি ব্যবহার করা ভাল নয় যা আপনি আসলে তা করেন না বা অভিনয়গুলি জানেন না।
ড্যামিয়েন

4
আমি বুঝেছি তুমি কি বলতে চাচ্ছো. এটি নম্রতা যদিও এটি আমার নিজের চেয়ে বরং পেশাদার পূর্ণকালীন গ্রন্থাগারের লেখকদের দ্বারা পর্যালোচনা করা, পরীক্ষিত, অনুকূলিত সংস্করণটি বেছে নেবে। মান তার রানটাইম জটিলতা উহার কার্যাবলী সেইসাথে: গ্রন্থাগার প্রয়োজনীয় জ্ঞান হিসাবে গণ্য করা যেতে পারে।
xtofl

স্ট্রিংগুলি একপাশে রেখে দেওয়া, এটি একটি সি ++ সমস্যার একটি সি সমাধান। আমি মনে করি না যে এটিকে ভোট দেওয়া উচিত ছিল।
পেঁচানো

-1

আমি এটি এইভাবে করি:

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;
}

মূলত যখনই আমি প্রদত্ত চরটি পাই, আমি অফসেটটি অগ্রসর করি এবং চারটিকে সঠিক সূচীতে স্থানান্তরিত করি। আমি জানি না এটি সঠিক বা দক্ষ কিনা, আমি সি ++ এ (আবারো) শুরু করছি এবং আমি এতে কোনও ইনপুট প্রশংসা করব।


4
4 মাস পরে এই প্রশ্নের দিকে ফিরে তাকানো, আমি কেন জানি না কেন আমি স্টাডি :: মুছা বা এসটিডি :: প্রতিস্থাপন ব্যবহার করিনি।
রিকার্ডো পাইপার

-3
#include <string>
#include <algorithm>
std::string str = "YourString";
char chars[] = {'Y', 'S'};
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());

"আউটস্ট্রিং" রেখে স্ট্রিম থেকে মূলধন ওয়াই এবং এস সরান।

নোট যে removeএকটি আলগোরিদিম এবং শিরোনাম <algorithm>অন্তর্ভুক্ত প্রয়োজন।


হ্যাঁ, আমি মনে করি hte অ্যারে চরগুলি তিনি ফেলে রেখেছিলেন তার উপরে একটি অন্তর্নিহিত লুপ রয়েছে
রিচার্ডপ্লাঙ্কেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.