Я пытаюсь проверить, являются ли заданные отношения транзитивными, и если нет, добавить новые пары отношений, чтобы сделать их транзитивными. Пример исходных данных:

aa ab ad be

Функция должна быть такой: aa ab ad be ae, потому что для того, чтобы быть переходным, если ab и bc существуют, то ac тоже должен существовать. Но при любой попытке я получаю ошибку сегментации.

Я новичок в программировании на C++ и пытаюсь узнать об итераторах. Вот моя функция:

vector isTransitive(vector relations){
    bool flag;
    for(auto it=relations.begin();it != relations.end(); ++it){ 
        for(auto it2=relations.begin();it2 != relations.end(); ++it2){
            if((*it)[1] == (*it2)[0] && (*it)[0] != (*it)[1] && (*it2)[0]!=(*it2)[1]){ //if there exists ab and bc
                string newRelation;  //if there is a (a,b) (b,c) holds (a,c)
                newRelation.push_back((*it)[0]);
                newRelation.push_back((*it2)[1]);
                flag=false;
                for(auto it3=relations.begin();it3 != relations.end(); ++it3){
                    if(*it3==newRelation){
                        flag=true;
                        it3=relations.end(); //break the loop
                        it2=relations.end(); //break the loop
                    }
                }
                if(flag==false){
                    relations.push_back(newRelation);
                }
            }
        }
    }
    return relations;
}

if(*it3==newRelation) когда это утверждение true, я получаю ошибку segfault.

Ответы (1)

Цикл for эквивалентен циклу while (из cppreference):

{

    init_statement
    while ( condition ) {

        statement
        iteration_expression ;

    } 

} 

Вот две строчки:

it3=relations.end(); //break the loop
it2=relations.end(); //break the loop

Вы не нарушаете цикл, но вызываете неопределенное поведение. Сначала оба итератора будут увеличены, затем будет проверено условие цикла. В этот момент it3 уже не является relations.end(). Это выглядит примерно так:

{
    auto it = relations.begin();
    while (it != relations.end()) {
        it = relations.end();
        ++it;
    }
}

Условие никогда не будет true, и вы выйдете за пределы relations.

Для выхода из циклов используйте break. Чтобы выйти из вложенных циклов, можно поместить их в функцию и использовать return.

2022 WebDevInsider