C ++ এ একটি স্ট্রিংকে পরিবর্তনশীল সংখ্যার বারবার কীভাবে পুনরুক্ত করা যায়?


127

আমি সি ++ এ স্ট্রিংয়ের শুরুতে 'এন' স্পেসগুলি (বা কোনও স্ট্রিং) sertোকাতে চাই। এসটিডি :: স্ট্রিং বা চর * স্ট্রিং ব্যবহার করে এটি করার সরাসরি কোনও উপায় আছে কি?

উদাহরণস্বরূপ পাইথন আপনি সহজভাবে করতে পারেন

>>> "." * 5 + "lolcat"
'.....lolcat'
c++ 

কিউ স্ট্রিং ব্যবহার করে কেউ উত্তর সরবরাহ করবেন?
আকিভা

উত্তর:


175

একটি একক চরিত্র পুনরাবৃত্তি করার বিশেষ ক্ষেত্রে, আপনি ব্যবহার করতে পারেন std::string(size_type count, CharT ch):

std::string(5, '.') + "lolcat"

বিশেষ দ্রষ্টব্য। এটি বহু-চরিত্রের স্ট্রিংগুলির পুনরাবৃত্তি করতে ব্যবহার করা যাবে না।


79
ওপি একটি চরিত্র নয়, একটি স্ট্রিং পুনরাবৃত্তি করতে বলেছিল।
ফ্লোরিয়ান কাউফম্যান

39

পাইথনের * অপারেটর বা পার্লের এক্স অপারেটরের সমতুল্য সি ++ তে স্ট্রিংগুলি পুনরাবৃত্তি করার সরাসরি কোনও মুখ্যমন্ত্রিত উপায় নেই । আপনি যদি একটি একক চরিত্র পুনরাবৃত্তি করেন তবে দ্বি-যুক্তি নির্মাতা (পূর্ববর্তী উত্তরগুলির দ্বারা প্রস্তাবিত) ভাল কাজ করে:

std::string(5, '.')

আপনি কীভাবে কোনও স্ট্রিংটিকে এন বার পুনরাবৃত্তি করতে অস্ট্রিং স্ট্রিম ব্যবহার করতে পারেন তার এটি একটি স্বীকৃত উদাহরণ:

#include <sstream>

std::string repeat(int n) {
    std::ostringstream os;
    for(int i = 0; i < n; i++)
        os << "repeat";
    return os.str();
}

বাস্তবায়নের উপর নির্ভর করে, স্ট্রিং এন বারের সাথে সংলগ্ন করার চেয়ে এটি কিছুটা বেশি দক্ষ হতে পারে।


17

স্ট্রিংয়ের একটি ফর্ম ব্যবহার করুন: sertোকান:

std::string str("lolcat");
str.insert(0, 5, '.');

এটি স্ট্রিং (পজিশন 0) এর শুরুতে "....." (পাঁচটি বিন্দু) সন্নিবেশ করবে।


15
ওপি একটি চরিত্র নয়, একটি স্ট্রিং পুনরাবৃত্তি করতে বলেছিল।
ব্রেন্ট 19

@ ব্রেন্ট ওপি উভয়ের জন্য জিজ্ঞাসা করেছিল - "'এন' স্পেস (বা যে কোনও স্ট্রিং)", এবং তারপরে স্ট্রিং হিসাবে একটি একক সময়ের সাথে তাদের অভিপ্রায়টি প্রদর্শন করে। ইংরেজি অনেক লোকের প্রথম ভাষা নয় তাই আপনার মাঝে মাঝে তাদের সঠিক প্রয়োজনীয়তা অনুমান করা প্রয়োজন এবং বিশ্লেষণ করা হলে, প্রশ্নটি সত্যই জিজ্ঞাসা করছে যে এটি একটি একক চরিত্রের সাহায্যে কীভাবে করা যায়। আমি দুঃখিত আপনি আমার উত্তরটি এটির পক্ষে নিরপেক্ষভাবে যথেষ্ট সাফল্যের সাথে খুঁজে পেয়েছেন।
ক্যামে

13

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি একই জিনিসটি করতে চেয়েছিলাম এবং আমি যা বলেছি এটি একটি সহজ সমাধান বলে মনে করেছি। দেখা যাচ্ছে যে cout.fill () এর সাহায্যে এই ফাংশনটি তৈরি হয়েছে, একটি 'পূর্ণ' ব্যাখ্যার জন্য লিঙ্কটি দেখুন

http://www.java-samples.com/showtutorial.php?tutorialid=458

cout.width(11);
cout.fill('.');
cout << "lolcat" << endl;

আউটপুট

.....lolcat

6
শুধুমাত্র বিন্দু বসানো: পরিবর্তনের শেষ লাইনটি ...cout << "" << endl;
musefan

9

ওপি দ্বারা উপলব্ধ উদাহরণস্বরূপ উদ্দেশ্য পূরণকল্পে std :: STRING এর ctor যথেষ্ট; std::string(5, '.')। তবে, কেউ যদি std :: স্ট্রিংয়ের একাধিকবার পুনরাবৃত্তি করতে কোনও ফাংশন সন্ধান করছে:

std::string repeat(const std::string& input, unsigned num)
{
    std::string ret;
    ret.reserve(input.size() * num);
    while (num--)
        ret += input;
    return ret;
}

8

কমোডোর জায়েজার যেমন ইঙ্গিত করেছেন, আমি মনে করি না যে অন্য উত্তরগুলির কোনও উত্তরই এই প্রশ্নের উত্তর দেয় না; প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে কোনও অক্ষর নয়, একটি স্ট্রিং পুনরাবৃত্তি করতে হয়।

কমোডোরের দেওয়া উত্তরটি সঠিক হলেও এটি বেশ অযোগ্য। এখানে একটি দ্রুত বাস্তবায়ন করা হচ্ছে, ধারণাটি প্রথমে স্ট্রিংটি তাত্পর্যপূর্ণভাবে বাড়িয়ে কপি করা অপারেশন এবং মেমরির বরাদ্দকে হ্রাস করতে হবে:

#include <string>
#include <cstddef>

std::string repeat(std::string str, const std::size_t n)
{
    if (n == 0) {
        str.clear();
        str.shrink_to_fit();
        return str;
    } else if (n == 1 || str.empty()) {
        return str;
    }
    const auto period = str.size();
    if (period == 1) {
        str.append(n - 1, str.front());
        return str;
    }
    str.reserve(period * n);
    std::size_t m {2};
    for (; m < n; m *= 2) str += str;
    str.append(str.c_str(), (n - (m / 2)) * period);
    return str;
}

operator*পাইথন সংস্করণের আরও কিছু পেতে আমরা একটি সংজ্ঞাও দিতে পারি:

#include <utility>

std::string operator*(std::string str, std::size_t n)
{
    return repeat(std::move(str), n);
}

আমার মেশিনে এটি কমোডোর প্রদত্ত বাস্তবায়নের চেয়ে প্রায় 10x দ্রুত এবং একটি নিষ্পাপ 'অ্যাপেন্ড এন - 1 বার' সমাধানের চেয়ে প্রায় 2x দ্রুত ।


আপনার বাস্তবায়ন 'অনুলিপি ছোট করে না'। মনে রাখবেন যে +=আপনার জন্য লুপটি অভ্যন্তরীণভাবে কোনও ধরণের লুপ রয়েছে যা str.size()পুনরাবৃত্তি করে। str.size()প্রতিটি বাহ্যিক লুপ পুনরাবৃত্তিতে বৃদ্ধি পায়, সুতরাং প্রতিটি বাহ্যিক পুনরাবৃত্তির পরে অভ্যন্তরীণ লুপটিকে আরও পুনরাবৃত্তি করতে হয়। আপনার এবং নিষ্পাপ 'উভয় অনুলিপি অনুলিপি' অনুলিপি n * period। প্রাথমিকের কারণে আপনার বাস্তবায়ন কেবল একটি মেমরি বরাদ্দ করে reserve। আমার ধারণা আপনি আপনার বাস্তবায়নটিকে একটি ছোট strএবং একটি বড় nদিয়ে প্রমাণ করেছেন তবে বড় strএবং ছোটের সাথেও নয় n
ফ্লোরিয়ান কাউফম্যান

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

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

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

1
@ ফ্লোরিয়ানকফম্যান: rep movsbকমপক্ষে মাঝারি থেকে বড় কপিগুলির জন্য অনুলিপি করার অন্যতম কার্যকর উপায় হল x86- এ এর মাইক্রো কোডেড প্রয়োগের কিছুটা অবিচ্ছিন্ন স্টার্টআপ ওভারহেড রয়েছে (এএমডি এবং ইন্টেল উভয় ক্ষেত্রে), যেমন স্যান্ডিব্রিজে, 15 থেকে 40 ডলার চক্র, এবং 64 বি ক্যাশে লাইন প্রতি 4 চক্র (সেরা কেস) । ছোট অনুলিপিগুলির জন্য, একটি এসএসই লুপ সেরা কারণ এটির স্টার্টআপ ওভারহেড নেই। তবে তারপরে এটি শাখার ভুল বিধিগুলির বিষয়।
পিটার কর্ডেস

6

আপনার নিজের স্ট্রিম ম্যানিপুলেটরটি লেখা উচিত

cout << বহু (5) << "যাই হোক না কেন <<" লোলক্যাট ";


15
একটি স্ট্রিম ম্যানিপুলেটর লেখা খুব সহজ কিছু করার খুব জটিল উপায়!
জিরো

10
সি ++ হ'ল খুব সাধারণ কিছু করার খুব জটিল উপায়।
জেডিপিচাম

5

ITNOA

এটি করার জন্য আপনি সি ++ ফাংশন ব্যবহার করতে পারেন।

 std::string repeat(const std::string& input, size_t num)
 {
    std::ostringstream os;
    std::fill_n(std::ostream_iterator<std::string>(os), num, input);
    return os.str();
 }

1
পৃথিবীতে "ITNOA" এর অর্থ কী? অনলাইনে এর কোনও রেফারেন্স খুঁজে পাচ্ছেন না।
27:24
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.