কোনও ভেক্টরের সামগ্রী কীভাবে মুদ্রণ করবেন?


281

আমি সি ++ তে কোনও ভেক্টরের সামগ্রী মুদ্রণ করতে চাই, আমার কাছে যা আছে তা এখানে:

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;

int main()
{
    ifstream file("maze.txt");
    if (file) {
        vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
        vector<char> path;
        int x = 17;
        char entrance = vec.at(16);
        char firstsquare = vec.at(x);
        if (entrance == 'S') { 
            path.push_back(entrance); 
        }
        for (x = 17; isalpha(firstsquare); x++) {
            path.push_back(firstsquare);
        }
        for (int i = 0; i < path.size(); i++) {
            cout << path[i] << " ";
        }
        cout << endl;
        return 0;
    }
}

আমি কীভাবে ভেক্টরের সামগ্রীগুলি স্ক্রিনে মুদ্রণ করব?


1
কেন এটা কাজ করছে না"?
ডিফল্ট

উত্তর:


392

আপনার প্রশ্নের জবাব বিশুদ্ধভাবে, আপনি একটি পুনরাবৃত্তি ব্যবহার করতে পারেন:

std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

আপনি যদি লুপের জন্য ভেক্টরের সামগ্রীগুলি পরিবর্তন করতে চান তবে তার iteratorপরিবর্তে ব্যবহার করুন const_iterator

তবে এ সম্পর্কে আরও অনেক কিছু বলা যায়। আপনি যদি কেবল উত্তরটি ব্যবহার করতে পারেন তবে আপনি এখানে থামতে পারেন; অন্যথায়, পড়ুন।

অটো (সি ++ 11) / টাইপডেফ

এটি অন্য কোনও সমাধান নয়, তবে উপরের iteratorসমাধানটির পরিপূরক । আপনি যদি সি ++ 11 স্ট্যান্ডার্ড (বা তারপরে) ব্যবহার করেন তবে আপনি autoপাঠযোগ্যতার সাহায্যে কীওয়ার্ডটি ব্যবহার করতে পারেন :

for (auto i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

তবে এর iধরণটি অবিচ্ছিন্ন হবে (যেমন, সংকলক std::vector<char>::iteratorপ্রকার হিসাবে ব্যবহার করবে i)।

এই ক্ষেত্রে, আপনি কেবল একটি typedef(সি ++ 11 এর মধ্যে সীমাবদ্ধ নয় এবং যাইহোক ব্যবহারের জন্য খুব দরকারী) ব্যবহার করতে পারেন:

typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

বিপরীত

লুপটিতে নিজের অবস্থানটি রেকর্ড করতে আপনি অবশ্যই একটি পূর্ণসংখ্যার প্রকারটি ব্যবহার করতে পারেন for:

for(int i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

আপনি যদি এটি করতে যাচ্ছেন তবে ধারকটির সদস্য প্রকারগুলি উপলব্ধ এবং উপযুক্ত হলে এটি ব্যবহার করা ভাল। এই কাজের জন্য std::vectorডাকা একটি সদস্য প্রকার আছে size_type: এটি sizeপদ্ধতি দ্বারা ফিরে আসা টাইপ ।

// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

iteratorসমাধানের উপরে কেন এটি ব্যবহার করবেন না ? সাধারণ ক্ষেত্রে আপনার পক্ষেও হতে পারে তবে মূল বিষয়টি হ'ল iteratorশ্রেণি এমন একটি বিষয় যা আরও জটিল জটিল বস্তুগুলির জন্য এই কাজটি করার জন্য ডিজাইন করা হয়েছে যেখানে এই সমাধানটি আদর্শ হতে চলেছে না।

লুপের জন্য পরিসীমা ভিত্তিক (সি ++ 11)

দেখুন Jefffrey এর সমাধান । সি ++ 11 এ (এবং তারপরে) আপনি নতুন পরিসীমা-ভিত্তিক forলুপটি ব্যবহার করতে পারেন , যা দেখতে এটির মতো দেখাচ্ছে:

for (auto i: path)
  std::cout << i << ' ';

যেহেতু pathআইটেমগুলির ভেক্টর (স্পষ্টভাবে std::vector<char>), বস্তুটি iভেক্টরের আইটেমের ধরণের (যেমন, স্পষ্টতই, এটি ধরণের char)। অবজেক্টটির iএকটি মান রয়েছে যা pathবস্তুর আসল আইটেমের অনুলিপি । সুতরাং, iলুপের সমস্ত পরিবর্তনগুলি নিজের মধ্যে সংরক্ষণ করা হয় না path। উপরন্তু, যদি আপনি সত্য যে তোমাদের মধ্যে কপি মান পরিবর্তন পাবে না চান জোরদার করা চাই iলুপ, আপনি ধরণ জোর করতে পারেন iহতে const charভালো:

for (const auto i: path)
  std::cout << i << ' ';

আপনি যদি আইটেমগুলিতে পরিবর্তন করতে চান তবে আপনি pathএকটি রেফারেন্স ব্যবহার করতে পারেন:

for (auto& i: path)
  std::cout << i << ' ';

এবং আপনি যদি সংশোধন করতে না চান, এমনকি যদি pathঅবজেক্টগুলির অনুলিপি ব্যয়বহুল হয় তবে আপনার মান দ্বারা অনুলিপি না করে কনস্ট রেফারেন্স ব্যবহার করা উচিত:

for (const auto& i: path)
  std::cout << i << ' ';

এসটিডি :: কপি

দেখুন যিহোশূয়ের উত্তরstd::copyআউটপুট স্ট্রিমে ভেক্টরের সামগ্রীগুলি অনুলিপি করতে আপনি এসটিএল অ্যালগরিদম ব্যবহার করতে পারেন । এটি যদি আপনি এটির সাথে স্বাচ্ছন্দ্য বোধ করেন তবে এটি একটি মার্জিত সমাধান (এবং কেবল এটি কোনও ভেক্টরের সামগ্রীগুলি মুদ্রণের ক্ষেত্রে নয়) এটি খুব দরকারী।

এসটিডি :: for_each

দেখুন ম্যাক্স এর সমাধান । ব্যবহার std::for_eachকরা এই সাধারণ দৃশ্যের জন্য ওভারকিল, তবে আপনি কেবল স্ক্রিনে প্রিন্টিংয়ের চেয়ে আরও কিছু করতে চাইলে এটি একটি খুব কার্যকর সমাধান: ব্যবহার করে std::for_eachআপনাকে ভেক্টর সামগ্রীগুলিতে কোনও (বুদ্ধিমান) অপারেশন করতে দেয়।

ওভারলোড ostream :: অপারেটর <<

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

template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
  if ( !v.empty() ) {
    out << '[';
    std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
    out << "\b\b]";
  }
  return out;
}

অন্য যে কোনও সমাধানের ব্যবহার সোজা হওয়া উচিত।

উপসংহার

এখানে উপস্থাপিত যে কোনও সমাধান কাজ করবে। এটি আপনার এবং কোডটির উপর নির্ভর করে যেটি "সেরা"। এর থেকে আরও বিশদযুক্ত যে কোনও বিষয় সম্ভবত অন্য কোনও প্রশ্নের জন্য সবচেয়ে ভাল বাকি আছে যেখানে উপকার / বিবেকের যথাযথ মূল্যায়ন করা যেতে পারে; তবে সর্বদা হিসাবে ব্যবহারকারীর পছন্দ সর্বদা একটি ভূমিকা পালন করবে: উপস্থাপিত সমাধানগুলির কোনওটিই ভুল নয়, তবে কিছু প্রতিটি স্বতন্ত্র কোডারের কাছে আরও ভাল লাগবে।

অভিযোজ্য বস্তু

এটি আমি পোস্ট করা আগেরটির একটি বর্ধিত সমাধান। যেহেতু সেই পোস্টটি মনোযোগ পাচ্ছে, তাই আমি এটিকে প্রসারিত করার এবং এখানে পোস্ট করা অন্যান্য দুর্দান্ত সমাধানগুলি উল্লেখ করার সিদ্ধান্ত নিয়েছি। আমার মূল পোস্ট মন্তব্য যে উল্লেখ করেন যে, যদি আপনি ছিল সেটা একটি ভিতরে আপনার ভেক্টর পরিবর্তন উপর ইচ্ছুক forলুপ তারপর দ্বারা উপলব্ধ দুটি পদ্ধতি আছে std::vector: এক্সেস উপাদান std::vector::operator[]যা সীমা চেক করে না, এবং std::vector::atসীমা চেক সঞ্চালন অবলম্বন দিতে হবে। অন্য কথায়, atযদি আপনি ভেক্টরের বাইরে কোনও উপাদান অ্যাক্সেস করার চেষ্টা করেন তবে নিক্ষেপ operator[]করবেন। আমি কেবল এই মন্তব্যটি যুক্ত করেছি, মূলত এমন কিছু উল্লেখ করার জন্য যা ইতিমধ্যে কেউ না জানলে এটি দরকারী হতে পারে। এবং আমি এখন কোন পার্থক্য দেখতে পাচ্ছি। অতএব এই সংযোজন।


যদি আপনি 0মধ্য থেকে লুপিং করেন vector::size()এবং ভেক্টরটি লুপের মধ্যে সংশোধন না করা হয় at()তবে অতিরিক্ত সীমানা পরীক্ষা করে ওভারহেড ব্যবহার করার প্রয়োজন নেই । এটি বলেছিল, আপনার পরামর্শ অনুসারে আমি একজন পুনরাবৃত্তিকারীর সাথে যাব।
এড এস

1
@Ed: হাঁ, সেখানে ব্যবহার করে কোন বিন্দু atযদি লুপ মডিফাই কিছুই ভেক্টর, কিন্তু আমার মনে হয়েছে আমি এটা উল্লেখ চাই ধরো যদি ভেক্টর হয় লুপ (যেমন যে হতে পারে unrecommended) পরিবর্তন এবং কারণ এটি একটি পায় না উল্লেখ করুন এবং এটি কমপক্ষে এটি জানার জন্য কার্যকর হতে পারে।
জোড়োয়ার

লুপের জন্য পরিসর-ভিত্তিক রেফারেন্সগুলি ব্যবহার করতে আবারও লেখা যেতে পারে, যা বৃহত্তর সাব-অবজেক্টগুলির ক্ষেত্রে গুরুত্বপূর্ণ হতে পারে, নিম্নরূপ:for (auto const &i: path) std::cout << i << ' ';
আন্ডারস্কোর_১১

@ আসরস্কোর_ডি: ধন্যবাদ আমি এই বিভাগটি পরিষ্কার করেছি এবং আমি আশা করি এটি এখন আরও সম্পূর্ণ এবং আরও কিছুটা পরিষ্কার হয়ে গেছে।
জোড়োয়ার

"ওভারলোড অপারেটর <<" ভাল সমাধান নয়; কমপক্ষে ওভারলোডেড অপারেটরের একটি অপারেন্ডটি আপনার প্রোগ্রাম দ্বারা সংজ্ঞায়িত একটি শ্রেণি হওয়া উচিত, কারণ তর্ক-নির্ভর নির্ভরতা
এমএম

218

এটি করার একটি আরও সহজ উপায় হ'ল স্ট্যান্ডার্ড কপি অ্যালগরিদম সহ :

#include <iostream>
#include <algorithm> // for copy
#include <iterator> // for ostream_iterator
#include <vector>

int main() {
    /* Set up vector to hold chars a-z */
    std::vector<char> path;
    for (int ch = 'a'; ch <= 'z'; ++ch)
        path.push_back(ch);

    /* Print path vector to console */
    std::copy(path.begin(), path.end(), std::ostream_iterator<char>(std::cout, " "));

    return 0;
}

Ostream_iterator বলা হয় যা একটি পুনরাবৃত্তি অ্যাডাপ্টার বলা হয় । প্রবাহে প্রিন্ট আউট করার জন্য এটি টাইপ করে টেম্প্লেটাইজড (এই ক্ষেত্রে, char)। cout(ওরফে কনসোল আউটপুট) হ'ল সেই প্রবাহ যা আমরা লিখতে চাই এবং স্পেস ক্যারেক্টার ( " ") যা আমরা ভেক্টরে সঞ্চিত প্রতিটি উপাদানগুলির মধ্যে মুদ্রণ করতে চাই।

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


3
আমার ভেক্টর টাইপ ছিল কি যদি vector<pair<int, struct node>>। এই ভেক্টরটি মুদ্রণের জন্য আমি কীভাবে উপরের পদ্ধতিটি ব্যবহার করব?
mtk

6
ডিলিমিটার স্ট্রিং প্রতিটি উপাদানের পরে লেখা হয় , এর মধ্যে নয়, শেষের পরেও। এটির জন্য বিশেষ ক্ষেত্রে মোকাবিলা করার প্রয়োজন হতে পারে যদি আপনি কেবল এটির মধ্যে বিভাজক হিসাবে চান।
কুইগি

2
@ এমটিকে আপনি operator<<আপনার নির্দিষ্ট জুটির জন্য কোনও ফাংশন ঘোষণা করতে পারেন <>।
জুতার ফাঁকা

অতিরিক্ত উত্তরোত্তর বিভাজক সম্পর্কে একটি উত্তর যুক্ত করে একই রকম দৃষ্টিভঙ্গি দেখানো হয়েছে তবে @ কুইগি: এর উপরের মন্তব্যটি নেওয়া হয়েছে।
dfri

@ ShoeLace- এর আর কোন উপায় নেই?
thegreatcoder

69

সি ++ 11 এ আপনি এখন লুপের জন্য একটি পরিসীমা-ভিত্তিক ব্যবহার করতে পারেন :

for (auto const& c : path)
    std::cout << c << ' ';

লুপের জন্য পরিসরের শরীরে যদি ভেক্টরের আকার পরিবর্তন না করা হয় তবে এটি দুর্দান্ত কাজ করে।
ব্রায়ান

8
@BrianP। হা. ধারকটির উপাদানগুলি মুদ্রণের ফলে ধারকটির পরিসর পরিবর্তন হয় না।
জুতো

এখানে পছন্দনীয় কি - গ উপাদান অনুলিপি এড়ানোর জন্য একটি মান অনুলিপি বা দৃ const় উল্লেখ হিসাবে?
ক্লিনফ্রেন্ড

@ Kleinfreund এটি ভেক্টরের সামগ্রীর উপর নির্ভর করে। উদাহরণস্বরূপ chars এর ভেক্টরের জন্য , সম্ভাবনাগুলি হ'ল ধ্রুবক রেফারেন্সের মধ্য দিয়ে যাওয়া আসলে মানের চেয়ে বেশি ব্যয়বহুল। তবে এখানে আমরা সুপার মাইক্রো অপ্টিমাইজেশনের কথা বলছি।
জুতো

43

আমি মনে করি এটি করার সর্বোত্তম উপায় হ'ল operator<<আপনার প্রোগ্রামটিতে এই ফাংশনটি যুক্ত করে কেবল ওভারলোড করা:

#include <vector>
using std::vector;
#include <iostream>
using std::ostream;

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "{";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "}";
    return out;
}

তারপরে আপনি যে <<কোনও সম্ভাব্য ভেক্টরটিতে অপারেটরটি ব্যবহার করতে পারেন , ধরে নিবেন এর উপাদানগুলিও ostream& operator<<সংজ্ঞায়িত হয়েছে:

vector<string>  s = {"first", "second", "third"};
vector<bool>    b = {true, false, true, false, false};
vector<int>     i = {1, 2, 3, 4};
cout << s << endl;
cout << b << endl;
cout << i << endl;

আউটপুট:

{first, second, third}
{1, 0, 1, 0, 0}
{1, 2, 3, 4}

3
V.size () - 1 এর ইনট হিসাবে সংরক্ষণ করা একটি নির্ভুলতার সম্ভাব্য ক্ষতি। আমি এটি কোনও স্বীকৃত পিয়ার পর্যালোচনা সম্পাদনা ( স্ট্যাকওভারফ্লো.com / revisions / 23397700/5 ) এ ঠিক করেছি, তবে এরপরে এটি যথাযথতার সম্ভাব্য ক্ষতি পুনরুদ্ধার করে আবার সম্পাদনা করা হয়েছিল। আমার ধারণা অনুশীলনে এটি খুব বেশি গুরুত্ব দেয় না কারণ ভেক্টররা সাধারণত এত বড় হয় না n't
জেডিম্যাটটিও

পরিবর্তনশীল হিসাবে এটিকে সংরক্ষণ না করে কোডের পঠনযোগ্যতা হ্রাস পায় যা আপনার সম্পাদনার একটি অংশ যার সাথে আমি দ্বিমত পোষণ করি না। আমি ধরণ পরিবর্তন করেছি lastকরতে size_t
ক্রিস রেডফোর্ড

size_t last = v.size() - 1;অপ্রয়োজনীয় দেখায়, আপনি লিঙ্কেরif (i) out << ", "; আগে শর্তটি ব্যবহার করতে পারেনout << v[i];
ভ্লাদিমির গামালিয়ান

3
এই অপারেটরটি ADL দ্বারা খুঁজে পাওয়া যায় নি, কারণ এটি এর কোনও যুক্তির নামস্থানে নেই। সুতরাং এটি অন্য কোনও নেমস্পেসের দ্বারা গোপন করা হবে operator<<উদাহরণ
এমএম

আপনি এই কাজ করতে যাচ্ছেন, কেন পরীক্ষা if (i != last) প্রতিটি সময় মধ্যে লুপ? পরিবর্তে, যদি ধারকটি খালি না থাকে তবে (ক) প্রথম উপাদানটি প্রেরণ করুন এবং তারপরে (খ) অবশিষ্ট উপাদানগুলি লুপ-প্রেরণ করুন , প্রথমে বিভাজকটি মুদ্রণ করুন (উপসর্গ হিসাবে)। কোনও অভ্যন্তরীণ লুপ পরীক্ষা (নিজে লুপের শর্ত বাদে) প্রয়োজন হয় না। শুধুমাত্র একটি আউট অফ লুপ পরীক্ষা প্রয়োজন।
WhozCraig

22

for_eachল্যাম্বডা এক্সপ্রেশন সম্পর্কে কীভাবে :

#include <vector>
#include <algorithm>
...
std::vector<char> vec;
...
std::for_each(
              vec.cbegin(),
              vec.cend(),
              [] (const char c) {std::cout << c << " ";} 
              );
...

অবশ্যই, এর জন্য একটি পরিসীমা-ভিত্তিক হ'ল এই কংক্রিটের কাজটির জন্য সর্বাধিক মার্জিত সমাধান, তবে এটি একটি আরও অনেক সম্ভাবনা দেয়।

ব্যাখ্যা

for_eachঅ্যালগরিদম একটি লাগে ইনপুট পরিসীমা এবং callable বস্তুর , পরিসর প্রতিটি উপাদান এই বস্তুর কলিং। একটি ইনপুট পরিসর দুটি পুনরুক্তি দ্বারা সংজ্ঞায়িত করা হয় । একজন callable বস্তুর একটি ফাংশন, ফাংশন একটি পয়েন্টার, একটি শ্রেণী যেটি overloads একটি অবজেক্ট হতে পারে () operatorবা এই ক্ষেত্রে হিসাবে, একটি ল্যামডা অভিব্যক্তি । এই অভিব্যক্তির জন্য প্যারামিটারটি ভেক্টর থেকে প্রাপ্ত উপাদানগুলির ধরণের সাথে মেলে।

এই বাস্তবায়নের সৌন্দর্য হ'ল ল্যাম্বদা এক্সপ্রেশন থেকে পাওয়ার পাওয়ার - আপনি কেবলমাত্র ভেক্টর প্রিন্টিংয়ের চেয়ে আরও অনেক কিছুতে এই পদ্ধতির ব্যবহার করতে পারেন।


10

কনসোলে কেবল ধারকটি অনুলিপি করুন।

std::vector<int> v{1,2,3,4};
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout, " " ));

আউটপুট করা উচিত:

1 2 3 4

8

সমস্যা সম্ভবত পূর্ববর্তী লুপ রয়েছে: (x = 17; isalpha(firstsquare); x++)। এই লুপটি মোটেও চলবে না (যদি firstsquareতা আলফা হয় না) বা চিরকাল চলবে (যদি এটি আলফা হয়)। কারণ বর্ধিত firstsquareহিসাবে পরিবর্তন হয় না x


7

সি ++ 11 এ লুপের জন্য একটি পরিসীমা-ভিত্তিক ভাল সমাধান হতে পারে:

vector<char> items = {'a','b','c'};
for (char n : items)
    cout << n << ' ';

আউটপুট:

a b c 

6

std::copyঅতিরিক্ত ট্রেলিং বিভাজক ব্যতীত তবে ব্যবহার করা হচ্ছে

একটি বিকল্প / পরিবর্তিত পদ্ধতির ব্যবহার std::copy(যেমনটি মূলত @ জোশুয়া ক্রাভিটিজ উত্তরে ব্যবহৃত হয়েছে ) তবে শেষ উপাদানটির পরে অতিরিক্ত ট্রেলিং বিভাজনকে অন্তর্ভুক্ত না করে:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template <typename T>
void print_contents(const std::vector<T>& v, const char * const separator = " ")
{
    if(!v.empty())
    {
        std::copy(v.begin(),
                  --v.end(),
                  std::ostream_iterator<T>(std::cout, separator));
        std::cout << v.back() << "\n";
    }
}

// example usage
int main() {
    std::vector<int> v{1, 2, 3, 4};
    print_contents(v);      // '1 2 3 4'
    print_contents(v, ":"); // '1:2:3:4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // '1'
    return 0;
}

একটি কাস্টম পিওডি টাইপের ধারকটিতে ব্যবহারের প্রয়োগ উদাহরণ:

// includes and 'print_contents(...)' as above ...

class Foo
{
    int i;
    friend std::ostream& operator<<(std::ostream& out, const Foo& obj);
public:
    Foo(const int i) : i(i) {}
};

std::ostream& operator<<(std::ostream& out, const Foo& obj)
{
    return out << "foo_" << obj.i; 
}

int main() {
    std::vector<Foo> v{1, 2, 3, 4};
    print_contents(v);      // 'foo_1 foo_2 foo_3 foo_4'
    print_contents(v, ":"); // 'foo_1:foo_2:foo_3:foo_4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // 'foo_1'
    return 0;
}

4

ওভারলোড অপারেটর <<:

template<typename OutStream, typename T>
OutStream& operator<< (OutStream& out, const vector<T>& v)
{
    for (auto const& tmp : v)
        out << tmp << " ";
    out << endl;
    return out;
}

ব্যবহার:

vector <int> test {1,2,3};
wcout << test; // or any output stream

3

আমি দুটি সমস্যা দেখতে পাচ্ছি। যেমন এখানে উল্লেখ করা হয়েছে for (x = 17; isalpha(firstsquare); x++)হয় হয় অসীম লুপ বা কখনই কার্যকর হয় না এবং if (entrance == 'S')প্রবেশের চরিত্রটি যদি 'এস' থেকে আলাদা হয় তবে পথ ভেক্টরের দিকে ধাক্কা দেওয়া কিছুই হয় না, খালি করে তোলে এবং এভাবে স্ক্রিনে কিছুই মুদ্রিত হয় না। আপনি পরে পরীক্ষা করতে path.empty()বা মুদ্রণের জন্য পরীক্ষা করতে পারেনpath.size()

যে কোনও উপায়ে, ভেক্টরের পরিবর্তে স্ট্রিং ব্যবহার করা ভাল না? আপনি অ্যারের মতো স্ট্রিংয়ের সামগ্রীগুলিও অ্যাক্সেস করতে পারেন, অক্ষরগুলি সন্ধান করতে পারেন, সাবস্ট্রিংগুলি এক্সট্রাক্ট করতে পারেন এবং স্ট্রিংটি সহজেই মুদ্রণ করতে পারেন (লুপ ছাড়াই)।

স্ট্রিং দিয়ে এগুলি করা কিছুটা কম বিভ্রান্তিকর উপায়ে লেখার উপায় এবং সমস্যাটি চিহ্নিত করা সহজ।


3

এই উত্তরটি জোড়োয়ারের উত্তরের ভিত্তিতে তৈরি, তবে আমি সেখানে কোনও মন্তব্য করতে পারিনি।

আপনি পরিবর্তে সিবেগিন এবং ক্যান্ড ব্যবহার করে অটো (সি ++ 11) / টাইপডেফ সংস্করণ কনস্ট করতে পারেন

for (auto i = path.cbegin(); i != path.cend(); ++i)
    std::cout << *i << ' ';

1

সি ++ 11`` এ ``

for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';

for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';

এই উত্তরটি ইতিমধ্যে বিদ্যমান উত্তরের তুলনায় কোনও অতিরিক্ত তথ্য দেয় না।
ইয়াসাস

0
#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector <pair<string,int> > v;
    int n;
    cin>>n;
int i;
    for( i=0;i<n;i++)
    {
        int  end;
        string str;
        cin>>str;
        cin>>end;
        v.push_back(make_pair(str,end));
    }



for (int j=0;j<n;j++)
{
    cout<<v[j].first<< " "<<v[j].second<<endl;
}``
}

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



0

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

template <typename T>
inline constexpr bool is_string_type_v = std::is_convertible_v<const T&, std::string_view>;

template<class T>
struct range_out {
  range_out(T& range) : r_(range) {
  }
  T& r_;
  static_assert(!::is_string_type_v<T>, "strings and string-like types should use operator << directly");
};

template <typename T>
std::ostream& operator<< (std::ostream& out, range_out<T>& range) {
  constexpr bool is_string_like = is_string_type_v<T::value_type>;
  constexpr std::string_view sep{ is_string_like ? "', '" : ", " };

  if (!range.r_.empty()) {
    out << (is_string_like ? "['" : "[");
    out << *range.r_.begin();
    for (auto it = range.r_.begin() + 1; it != range.r_.end(); ++it) {
      out << sep << *it;
    }
    out << (is_string_like ? "']" : "]");
  }
  else {
    out << "[]";
  }

  return out;
}

এখন এটি যে কোনও ব্যাপ্তিতে ব্যবহার করা মোটামুটি সহজ:

std::cout << range_out{ my_vector };

স্ট্রিং-এর মতো চেক উন্নতির জন্য ঘর ছেড়ে দেয়। আমিও আছে static_assertএড়াতে আমার দ্রবণে চেক std::basic_string<>, কিন্তু আমি এটা এখানে সরলতা জন্য বাকি।


-1

আপনি নিজের ফাংশন লিখতে পারেন:

void printVec(vector<char> vec){
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i] << " ";
    }
    cout << endl;
}

-1

যে লুপগুলি ছাড়াই ওয়ান-লাইনার চায় তাদের জন্য:

আমি বিশ্বাস করতে পারি না যে এই বিষয়ে নুনের কিছু নেই, তবে সম্ভবত এটি আরও সি-মত পদ্ধতির কারণে। যাইহোক, লুপ ছাড়াই এটি করা সম্পূর্ণ নিরাপদ, ওয়ান-লাইনারে, অনুমান করে যে এটি std::vector<char>নাল-সমাপ্ত:

std::vector<char> test { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };
std::cout << test.data() << std::endl;

তবে ostream@ জোরাওয়ারের পরামর্শ অনুসারে আমি এটি অপারেটরে মুড়ে রাখব, কেবল নিরাপদ থাকার জন্য:

template <typename T>std::ostream& operator<< (std::ostream& out, std::vector<T>& v)
{
    v.push_back('\0'); // safety-check!
    out << v.data();
    return out;
}

std::cout << test << std::endl; // will print 'Hello, world!'

printfপরিবর্তে ব্যবহার করে আমরা অনুরূপ আচরণ অর্জন করতে পারি :

fprintf(stdout, "%s\n", &test[0]); // will also print 'Hello, world!'

বিঃদ্রঃ:

ওভারলোডেড ostreamঅপারেটরটিকে ভেক্টরটিকে নন-কনস্ট্যান্ট হিসাবে গ্রহণ করতে হবে। এটি প্রোগ্রামটিকে নিরাপত্তাহীন করতে পারে বা অপব্যবহারযোগ্য কোডটি প্রবর্তন করতে পারে। এছাড়াও, যেহেতু নাল-চরিত্র সংযুক্ত করা হয়, তাই এর পুনঃনির্ধারণ std::vectorঘটতে পারে। সুতরাং পুনরাবৃত্তকারীগুলির সাথে লুপগুলি ব্যবহার করা সম্ভবত দ্রুততর হবে।


1
1. এর fprintf(stdout, "%s\n", &test[0]);থেকে আলাদা নয় std::cout << test.data(), উভয়ের জন্য নাল-টার্মিনেটেড ভেক্টর প্রয়োজন। ২. "তবে আমি এটি ostream অপারেটর" এ আবদ্ধ করব << যে অপারেটরটি ডান অপারেন্ডকে পরিবর্তন করে তোলে এটি একটি খুব খারাপ ধারণা।
হলিব্ল্যাকগেট

আমি কোডটিতে fprintf(stdout, "%s\n", &test[0]);দীর্ঘ সময় ব্যবহার করেছি এটি কখনও আমাকে কোনও সমস্যা না দিয়ে। মজাদার! এবং আমি সম্মত হই যে ostreamঅপারেটরে ভেক্টরটি সংশোধন করা এতটা সুন্দর নয় তবে আমি নিজে লুপিং এবং পুনরুক্তি ব্যবহারকারী উভয়কেই অপছন্দ করি । কোনওভাবেই আমি সাধারণ ক্রিয়াকলাপের মতো মনে করি যেন একটি std::vector<char>স্ট্যান্ডার্ড লাইব্রেরি প্রিন্ট করা উচিত এই বিষয়গুলি দূরে আড়াল করা উচিত। তবে সি ++ ক্রমাগত বিকাশ করছে, এটি শীঘ্রই আসতে পারে come
イ き ん
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.