简体   繁体   English

如何遍历一组C ++

[英]how to iterate through a set of sets C++

Pretty new to C++, only at it a week or so, I want to iterate through a set of nested sets and write each element in the inner set to a line in a file. 对于C ++来说,这是一个相当新的知识,仅在一周左右的时间内,我想遍历一组嵌套集并将内部集中的每个元素写入文件中的一行。 Each inner set has 3 elements and I want all three elements on the same line. 每个内部集合都有3个元素,我希望所有3个元素都在同一行上。 I have a set up as follows: 我的设置如下:

   // Define "bigSet" and initiate as empty set "Triplets"
   typedef set < set<string> > bigSet;
   bigSet Triplets;

I tried something of this sort to go through it but it gives me an error... 我尝试过这种方法,但是却给我一个错误...

    // Iterate through and print output
    set <string>::iterator it;
    for(it = Triplets.begin(); it != Triplets.end(); it++){
        cout << *it << endl;
    }

Any help is greatly appreciated guys thank you! 任何帮助都非常感谢你们,谢谢!

Triplets is not a set<string> ; 三元set<string>不是set<string> it is a set<set<string>> ; 这是一个set<set<string>> ; each item in Triplets is itself a set , than can contain several strings. Triplets中的每个项目本身都是一个set ,可以包含多个字符串。

The iterator must match the type of the container; 迭代器必须匹配容器的类型。 with two levels of nested containers, you should iterate twice: 如果有两个嵌套容器级别,则应迭代两次:

set<set<string>>::iterator it;
set<string>::iterator it2;
for(it = Triplets.begin(); it != Triplets.end(); it++) {
    for (it2 = it->begin(); it2 != it->end(); ++it2) {
        cout << *it2 << endl;
    }
}

I would do it this way: 我会这样:

 // Iterate through and print output
    set < set <string> >::iterator it_ex; // iterator for the "outer" structure
    set <string>::iterator it_in; // iterator for the "inner" structure

    for(it_ex = Triplets.begin(); it_ex != Triplets.end(); it_ex++)
    {
        for(it_in = it_ex->begin(); it_in != it_ex->end(); it_in++)   
            cout << *it_in << ", ";
        cout << endl;
    }

Triplets is type set < set<string> > and therefore requires an iterator of type set < set<string> >::iterator or bigSet::iterator . Tripletsset < set<string> >类型的,因此需要set < set<string> >::iteratorbigSet::iterator It isn't type set <string> . 它不是类型set <string> You could also use const_iterator . 您也可以使用const_iterator

Note that iterating Triplets gives you an iterator to another set, and not a string. 请注意,迭代Triplets使您可以迭代到另一个集合,而不是字符串。

Also consider 还考虑

for (const auto& i : Triplets)
{
    for (const auto& j : i)
    {
        cout << j << endl;
    }
}

You have an error because Triplets.begin() is not of type set<string>::iterator , it's set<set<string>>::iterator . 您有一个错误,因为Triplets.begin()的类型不是set<string>::iterator ,而是set<set<string>>::iterator

What you need to do is have two loops: one for iterating over the outer set and one for the inner. 您需要做的是有两个循环:一个循环迭代外部集合,一个循环内部。

set<set<string>>::iterator it;
for(it = Triplets.begin(); it != Triplets.end(); ++it)
{
    set<string>::iterator it2;
    for(it2 = it->begin(); it2 != it->end(); ++it2)
    {
        cout << *it2;
    }

    cout << endl;
}

If you use increment/decrement operators ( ++ / -- ) on iterators, it might be better to use the prefix versions ( ++it ) instead of the suffix ones ( it++ ). 如果在迭代器上使用增量/减量运算符( ++ / -- ),则最好使用前缀版本( ++it )而不是后缀版本( it++ )。 This is because the suffix ones create a copy of the iterator before it is incremented (and that copy is then returned) but in cases like this, you have no need for it. 这是因为后缀在递增之前创建了迭代器的副本(然后返回该副本),但是在这种情况下,则不需要它。

Moreover, if you're using C++11, you can use the range-based for loops and auto keyword, which simplify things a lot: 此外,如果您使用的是C ++ 11,则可以使用基于范围的for循环和auto关键字,这可以简化很多事情:

for(const auto &innerSet : Triplets)
{
    for(const auto &innerSetElement : innerSet)
    {
        cout << innerSetElement;
    }

    cout << endl;
}

First: if they're triplets, are you sure that std::set is the type you want for the inner values. 首先:如果它们是三胞胎,则确定std::set是您想要的内部值的类型。 Perhaps a class would be more appropriate, in which case, you define an operator<< for the `class, and your simple loop works perfectly. 也许一个class会更合适,在这种情况下,您可以为`类定义一个operator<< ,并且您的简单循环可以完美地工作。 Something like: 就像是:

class Triplet
{
    std::string x;
    std::string y;
    std::string z;
public:
    //  Constructors to enforce that none of the entries are identical...
    //  Accessors, etc.
    friend std::ostream& operator<<( std::ostream& dest, Triplet )
    {
        dest << x << ", " << y << ", " << z;
        return dest;
    }
};

And then to output: 然后输出:

for ( Triplet const& elem : Triplets ) {
    std::cout << elem << std::endl;
}

Otherwise: you need to define the format you want for the output. 否则:您需要定义所需的输出格式。 In particular, you'll probably want a separator between the strings in the line, for example. 特别是,例如,您可能需要在行中的字符串之间使用分隔符。 Which means you probably cannot use a range based for , at least not for the inner loop. 这意味着你可能无法使用基于范围for ,至少不会内环。 You would need something like: 您将需要以下内容:

for ( std::set<std::string> const& triplet : Triplets ) {
    for ( auto it = triplet.cbegin(); it != triplet.cend(); ++it ) {
        if ( it != triplet.cebegin() ) {
            std::cout << ", ";
        }
        std::cout << *it;
    }
    std::cout << std::endl;
}

(If the set of triplets is large, you'll definitely want to consider replacing std::endl with '\\n' . But of course, if it is really large, you probably won't be outputting to std::cout .) (如果三元组的集合很大,您肯定会考虑用'\\n'代替std::endl 。但是,当然,如果它真的很大,则可能不会输出到std::cout 。 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM