সি ++ তে স্ট্রিং :: স্ট্রিং থেকে স্পেসগুলি সরান


222

সি ++ এর স্ট্রিং থেকে ফাঁকা স্থান সরিয়ে নেওয়ার পছন্দের উপায়টি কী? আমি সমস্ত চরিত্রের মধ্য দিয়ে লুপ করতে এবং একটি নতুন স্ট্রিং তৈরি করতে পারলাম, তবে এর থেকে আরও ভাল উপায় কি আছে?

উত্তর:


257

সবচেয়ে ভাল কাজটি হল অ্যালগরিদম remove_ifএবং ইস্পেস ব্যবহার করা :

remove_if(str.begin(), str.end(), isspace);

এখন অ্যালগরিদম নিজেই ধারকটি পরিবর্তন করতে পারে না (কেবলমাত্র মানগুলি সংশোধন করে), সুতরাং এটি প্রকৃতপক্ষে মানগুলিকে চারপাশে বদলে দেয় এবং একটি পয়েন্টারটি ফিরে আসে যেখানে শেষ হওয়া উচিত। সুতরাং কন্টেইনারটির দৈর্ঘ্যটি সংশোধন করার জন্য আমাদের স্ট্রিং :: মুছতে হবে:

str.erase(remove_if(str.begin(), str.end(), isspace), str.end());

আমাদের এও লক্ষ্য করা উচিত যে মুছে ফেলা_আইফ ডেটার সর্বাধিক একটি অনুলিপি তৈরি করবে। এখানে একটি নমুনা বাস্তবায়ন:

template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
    T dest = beg;
    for (T itr = beg;itr != end; ++itr)
        if (!pred(*itr))
            *(dest++) = *itr;
    return dest;
}

54
যেহেতু 'ইস্পেস' এর ওভারলোড রয়েছে তাই আপনার সম্ভবত জেনেরিক কোডটি ব্যবহার করতে হবে :: আইসস্পেস (সি প্রয়োগকরণ যা কোনও লোকেল নেয় না) বা ক্রিপ্টিক টেম্পলেট ইনস্ট্যান্টেশন ত্রুটির সাথে অভ্যর্থনা জানায়।
ব্লেইন

4
সমস্ত - উপরের পদ্ধতিটি থেকে সাবধান থাকুন (দুটি একক লাইন, শিষ্ট সংস্করণ নয়, যদিও এটি একই সমস্যা হতে পারে)। আমি বুঝতে পারি না যে এটি সর্বদা সঠিক নয় without উদাহরণস্বরূপ, আপনি যদি স্ট্রিংটি "1 + 1" পাস করেন তবে এটি "1 + 11" ফেরত দেয়। আমি নীচে @ রোপেলোর পদ্ধতিতে স্যুইচ করেছি এবং এটি এই ক্ষেত্রে ভাল কাজ করেছে। শুভ কোডিং!
জোব

6
@ জো উত্তরে স্পষ্টভাবে উল্লেখ করা হয়েছে যে eraseপরে আপনাকে কল করতে হবে । এটি সঠিক ফলাফল ফিরিয়ে দেবে।
কনরাড রুডলফ

31
-1 এর ব্যবহারটি isspaceমূল 7-বিট ASCII ব্যতীত সমস্ত চরিত্রের সেটগুলির জন্য ইউবি। সি 99 .7.4 / 1। খুব খারাপ পরামর্শ হওয়া সত্ত্বেও এটি এখন অবধি votes১ টি ভোটে উন্নীত হয়েছে তা আমাকে অবাক করে দেয় না
চিয়ার্স এবং এইচটিএইচ - Alf

16
কেবলমাত্র পুনরাবৃত্তি করার জন্য, এই উত্তরের isspaceকোডটি স্বাক্ষর করার প্রাক-অনুশীলন ডিফল্ট পছন্দ সহ, সমস্ত অ-এসসিআইআই অক্ষরের জন্য নেতিবাচক মানগুলি ( ইওফ থেকে পৃথক) করে char। সুতরাং এটির অপরিবর্তিত আচরণ রয়েছে । আমি এটি পুনরাবৃত্তি করছি কারণ আমি এই সত্যটি শব্দকে ডুবিয়ে দেওয়ার ইচ্ছাকৃত প্রচেষ্টা সন্দেহ করি।
চিয়ার্স এবং এইচটিএইচ - আলফ

100
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());

31
ক্যানোনিকাল মোছা / মুছে ফেলার জন্য আমার আপ-ভোট ওয়ান লাইনারে তৈরি করা যেতে পারে: str.erase (std :: ਹਟਾ (str.begin (), str.end (), ''), str.end ());
বেলিন

11
দ্রষ্টব্য: <algorithm>এটি কাজ করার জন্য আপনাকে অন্তর্ভুক্ত করতে হবে।
তারা

37

গেমদেব থেকে

string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());

22
এটি স্ট্যান্ডার্ড :: ইস্পেসের লোকেল-গ্রহণ ওভারলোডগুলির কারণে মান-অনুসারে কার্যকরকরণগুলি সংকলন করবে না। আপনাকে :: isspace ব্যবহার করতে হবে বা std :: bind2nd এর সাথে কিছু অপঠনযোগ্য মেকিফিকেশন করতে হবে। জেনেরিক কোডটি কি সুন্দর নয়?
বেলিন

এছাড়াও নোট করুন যে কোনও অক্ষর যদি নেতিবাচক হয় (উদাহরণস্বরূপ যখন চরটি স্বাক্ষরিত হয় তখন একটি ইউটিএফ 8 চর), ::isspaceইউবি হয়।
মার্টিন বোনার

30

আপনি কি বুস্ট স্ট্রিং অ্যালগো ব্যবহার করতে পারেন? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573

erase_all(str, " "); 

3
এটি remove_if(str.begin(), str.end(), isspace);যে ম্যাট প্রাইজের উল্লেখ করেছে তার চেয়ে ধীর । কেন জানি না। প্রকৃতপক্ষে, সমস্ত বুস্ট স্টাফ, যেগুলির এসটিএল বিকল্প রয়েছে, সংশ্লিষ্ট জিসিসি'র চেয়ে ধীরে ধীরে (আমি পরীক্ষিত সমস্ত)। তাদের মধ্যে কিছু ধীরে ধীরে ধীরে ধীরে! (আনর্ডার্ড_ম্যাপ সন্নিবেশে 5 বার পর্যন্ত) হতে পারে এটি ভাগ করা পরিবেশের সিপিইউ ক্যাশে বা এর মতো অন্য কোনও কারণে।
ইথেরিয়লোনে


15

চরটি অপসারণের জন্য আপনি এই সমাধানটি ব্যবহার করতে পারেন:

#include <algorithm>
#include <string>
using namespace std;

str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());

1
স্ট্যান্ডার্ড নেমস্পেস ব্যবহার করে # স্ট্রিং।
স্ল্যাকমার্ট

এই সমাধানটি আমার পক্ষে সঠিক। শীর্ষ এক নয়।
জেসন লিউ

1
নেমস্পেস স্ট্যান্ড ব্যবহার করা এড়ানো উচিত। stackoverflow.com/questions/1452721/…
infinitezero

12

হাই, আপনি এরকম কিছু করতে পারেন। এই ফাংশনটি সমস্ত স্পেস মুছে ফেলে।

string delSpaces(string &str) 
{
   str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
   return str;
}

আমি আর একটি ফাংশন করেছি, যা সমস্ত অপ্রয়োজনীয় স্পেস মুছে ফেলে।

string delUnnecessary(string &str)
{
    int size = str.length();
    for(int j = 0; j<=size; j++)
    {
        for(int i = 0; i <=j; i++)
        {
            if(str[i] == ' ' && str[i+1] == ' ')
            {
                str.erase(str.begin() + i);
            }
            else if(str[0]== ' ')
            {
                str.erase(str.begin());
            }
            else if(str[i] == '\0' && str[i-1]== ' ')
            {
                str.erase(str.end() - 1);
            }
        }
    }
    return str;
}

8
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
        size_t position = 0;
        for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
        {
                str.replace(position ,1, toreplace);
        }
        return(str);
}

এটা ব্যবহার করো:

string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");

7

আপনি যদি সহজে ম্যাক্রো দিয়ে এটি করতে চান তবে এখানে একটি:

#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())

এটি ধরে নিয়েছে আপনি #include <string>অবশ্যই করেছেন।

এটি যেমন কল:

std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>

5
আপনি কেন এর জন্য ম্যাক্রো ব্যবহার করবেন?
দানি

1
সাধারণ কাজের জন্য কম কিবোর্ড টাইপ করা।
ভোলোমাইক 13

3
কল-সাইটের জন্য সমান সংক্ষিপ্ত একটি স্ট্রিংয়ের লভ্যালু-রেফারেন্স গ্রহণ করে একটি ফাংশন কল করছে । ম্যাক্রোগুলি তাদের আর্গুমেন্টগুলির সাথে ইন্টারঅ্যাক্ট করার (অবিলম্বে পার্শ্ব প্রতিক্রিয়াগুলি) আশ্চর্যজনক আচরণ করতে পারে তবে আরও খারাপ, তারা যদি কোনও ত্রুটির সাথে জড়িত থাকে তবে তাদের নাম সংকলক বার্তায় প্রকাশিত হয় না, তাদের প্রয়োগ হয়।
ক্রিস উজদাভিনিস

2

আমি নীচের কাজটি প্রায় দীর্ঘকাল ধরে ব্যবহার করেছি - এর জটিলতার বিষয়ে নিশ্চিত নই।

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());

আপনি যখন চরিত্র ' 'এবং কিছু - ব্যবহারের জন্য মুছতে চান

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());

একইভাবে কেবল ||যদি আপনি মুছে ফেলতে চান এমন অক্ষরগুলির সংখ্যা 1 না বাড়ান

অন্যদের দ্বারা উল্লিখিত হিসাবে মুছা মুছা মুছে ফেলা ভাল মনে হয়।


1
string removeSpaces(string word) {
    string newWord;
    for (int i = 0; i < word.length(); i++) {
        if (word[i] != ' ') {
            newWord += word[i];
        }
    }

    return newWord;
}

এই কোডটি মূলত একটি স্ট্রিং নেয় এবং এর প্রতিটি চরিত্রের মাধ্যমে পুনরাবৃত্তি করে। তারপরে এটি পরীক্ষা করে যে স্ট্রিংটি একটি সাদা জায়গা কিনা তা যদি না থাকে তবে অক্ষরটি একটি নতুন স্ট্রিংয়ে যুক্ত করা হয়।


1
   #include <algorithm>
   using namespace std;

   int main() {
       .
       .
       s.erase( remove( s.begin(), s.end(), ' ' ), s.end() );
       .
       .
   }

উৎস:

এই ফোরাম থেকে রেফারেন্স নেওয়া ।


1
এটি ইতিমধ্যে এই উত্তরটির চেয়ে বেশি কিছু যোগ করে না । আপনার উত্তরটিকে উচ্চমান এবং এই প্রশ্নটি বজায় রাখার পক্ষে আরও কী কী ব্যাখ্যা বা বিশদ যুক্ত করতে পারেন?
দাস_গীক

আমি মনে করি এটি আরও সহজ , 'কারণ এটি একটি বিবৃতিতে একই কাজ করে।
জন

2
গ্রেট! তারপরে সেই যুক্তিটিকে সরাসরি আপনার উত্তরে ব্যাখ্যা হিসাবে রাখুন । মূল প্রশ্নটি এগারো বছরেরও বেশি পুরনো এবং অন্য গ্রহণযোগ্য, ভাল-উত্তোলিত উত্তরের তুলনায় আপনার উত্তরটি গোলমাল হিসাবে দেখা যেতে পারে। এই ব্যাখ্যাটি থাকা আপনার উত্তর সরিয়ে ফেলা থেকে রক্ষা করতে সহায়তা করবে।
দাস_জিক

যে হবে ভাল কিন্তু আমি পাই নি যে কিভাবে আমি করা উচিত যে আমার উত্তর মধ্যে ... যে আমার উত্তর বেশী ভালো এই উত্তর? আপনি আমার উত্তরটি সম্পাদনা করতে পারলে খুব আনন্দ হবে be
জন

2
দুর্ভাগ্যক্রমে, আপনার লিখিত সামগ্রীটি যুক্ত করার জন্য উত্তরটি সম্পাদনা করা নিজেই সম্পাদনা নির্দেশিকাগুলির বিরুদ্ধে যাবে এবং আমার সম্পাদনাটি সম্ভবত পরে অস্বীকার বা ঘূর্ণিত হয়ে যাবে। উত্তরটি সম্পাদনা করার জন্য আপনি এই মন্তব্যের প্রথম লিঙ্কটি ব্যবহার করতে পারেন। এটি সম্পূর্ণরূপে গ্রহণযোগ্য যে আপনি নিজের উত্তরটি অন্য যে কোনওটির চেয়ে ভাল বলে মনে করেন এবং এর পক্ষে ন্যায়সঙ্গততা সরবরাহ করেন। সম্প্রদায় সিদ্ধান্ত নেবে যে আপনি সঠিকভাবে উন্নীত হবেন বা ডাউনভোটিং করে whether
দাস_গীক

0

সি ++ ২০ এ আপনি বিনামূল্যে ফাংশন এসটিডি :: মুছতে পারেন

std::string str = " Hello World  !";
std::erase(str, ' ');

সম্পূর্ণ উদাহরণ:

#include<string>
#include<iostream>

int main() {
    std::string str = " Hello World  !";
    std::erase(str, ' ');
    std::cout << "|" << str <<"|";
}

আমি মুদ্রণ | যাতে স্পষ্ট হয় যে শুরুতে স্থানটিও সরানো হয়েছে।

দ্রষ্টব্য: এটি কেবল স্থানটি সরিয়ে দেয়, হোয়াইটস্পেস হিসাবে বিবেচিত প্রতিটি সম্ভাব্য অক্ষর নয়, https://en.cppreferences.com/w/cpp/string/byte/isspace দেখুন


0

ট্যাব এবং লাইন ব্রেক (সি ++ 11) এর মতো সমস্ত শ্বেতস্পেস অক্ষরগুলি সরিয়ে দেয় :

string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");

এক দশক আগে আপনি কেন @ ম্যাট-প্রাইসের গৃহীত উত্তরগুলির চেয়ে এই পদ্ধতির প্রস্তাব দিবেন?
জেরেমি কেনে

সমস্ত সমাধান এখানে উপস্থাপন করা যাক। হয়তো কারও এই সমাধান প্রয়োজন হবে।
AnselmRu

আমি এর বিরুদ্ধে তর্ক করছি না। আমি বলছি যে পার্থক্যগুলি এবং তারা কী পরিস্থিতিতে তাদের পক্ষে উপযুক্ত হতে পারে তা ব্যাখ্যা করে বিভিন্ন পদ্ধতির মূল্যায়ন করা সহজতর করে তোলে।
জেরেমি কেনে

1
সম্ভবত এই সমাধানটি সবচেয়ে অর্থনৈতিক নয়, তবে এটি আপনাকে কেবল ফাঁকা স্থান নয়, সমস্ত সাদা বর্ণের অক্ষর থেকে মুক্তি দিতে সহায়তা করে ।
AnselmRu


-1
string removespace(string str)
{    
    int m = str.length();
    int i=0;
    while(i<m)
    {
        while(str[i] == 32)
        str.erase(i,1);
        i++;
    }    
}

3
আপনি কোডের উত্তরগুলির জন্য একটি সংক্ষিপ্ত বিবরণ যোগ করার পক্ষে এটি সাধারণত পছন্দ হয়।
arcyqwerty

1
@ সর্বশেষ - length()একটি size_tনা, একটি প্রদান করে interase()একটি size_typeনা , একটি নেয় int। সূচক সর্বদা বর্ধিত হওয়ার কারণে টানা দুটি স্পেসের মুখোমুখি হলে ফাংশনটি সম্ভবত ব্যর্থ হবে। যদি একটি স্থান সরিয়ে ফেলা হয়, তবে লুপটি স্ট্রিংয়ের সীমানার বাইরে পড়বে। আপনার এই উত্তরটি সম্ভবত মুছে ফেলা উচিত কারণ এর জন্য প্রচুর সহায়তার প্রয়োজন।
jww

-3

আমি ভয় পাচ্ছি যে এটি আমার পক্ষে সবচেয়ে ভাল সমাধান। তবে আপনি কিছুটা গতি বাড়ানোর জন্য ন্যূনতম প্রয়োজনীয় মেমরিটি প্রাক-বরাদ্দ করতে রিজার্ভ () ব্যবহার করতে পারেন। আপনি একটি নতুন স্ট্রিং দিয়ে শেষ করবেন যা সম্ভবত সংক্ষিপ্ত হবে তবে এটি একই পরিমাণ মেমরি গ্রহণ করে তবে আপনি পুনরায় স্থানগুলি এড়াতে পারবেন।

সম্পাদনা: আপনার পরিস্থিতির উপর নির্ভর করে, এটি চারপাশে ঝাঁকুনির চেয়ে কম ওভারহেড নিতে পারে।

আপনার আলাদা পদ্ধতির চেষ্টা করা উচিত এবং আপনার পক্ষে ভাল কি তা দেখতে হবে: আপনার কোনও কার্য সম্পাদনের সমস্যা নাও থাকতে পারে।


সরানো_এফ প্রতিটি মানের সর্বাধিক একটি অনুলিপি করে। সুতরাং সত্যিই কি করা প্রয়োজন তুলনায় অনেক বেশি ওভারহেড নেই।
ম্যাট দাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.