How to generate a list from a list vector by concatenating subsequences of positives and negatives

0

Implement a function void sign_join(vector< list<int> > &VL,list<int> &L) that, given a vector of lists VL generate a L list where they are First concatenated all the first non-negative subsequence of VL [0], VL [1] , ... After the negatives. Then again the non-negatives. So continuing until all the VLs are finished

Examples: VL: [[1,2, -1, -2,3,4, -3, -4], [5,6, -5, -6,7,8, -7, -8], [- 9 , -10]],

= > L: [1,2,5,6, -1, -2, -5, -6, -9, -10,3,4,7,8, -3, -4, -7, -8],

The code I have is the following:

int sign(int &x){
    if(x>=0){
        return 1;
    }else{
        return 0;
    }
}

bool vectorempty(vector<list<int>> &VL) {
    for(int i=0; i<VL.size(); i++) {
        if(!VL[i].empty()) {
            return false;
        }
    }
    return true;
}

int main(int argc, char *argv[]) {

    vector<list<int>> vl = {{1,2,-3}, {3,4,-5,-1}, {5,6,-8}};
    list<int> l;

    int s = 1;
    int i=0;
    while(vectorempty(vl)==false){
        auto it = vl[i].begin();
        while(it != vl[i].end() && sign(*it)==s) {
            l.push_back(*it);
            it=vl[i].erase(it);
        }
        if(i == (vl.size()-1)) {
            i=0;
            s=-s;
        }else{
            ++i;
        }
    }

    for(int &x:l) cout<<x<<" ";

    return 0;
}

But it remains in an infinite loop and I do not know how to solve it.

    
asked by facundo rotger 10.09.2018 в 17:09
source

1 answer

1

Without debugging I can not see where the program stays in an infinite loop (by the way, have you tried to debug?).

I still think that you complicate your life unnecessarily and reinvent the wheel: There is already a function to determine if a number is negative, it belongs to the header <cmath> and it's the function std::signbit .

Proposal.

Create a separate function (to follow the principle of sole responsibility ) to make the operation, my advice is that it is not a destructive operation (that does not alter the original data).

The algorithm to follow, in pseudocode, would be:

  • Access a list.
  • Extract numbers while the numbers are of the appropriate sign (and numbers remain).
  • Follow the previous step to the end or until you find an inappropriate sign number.
  • Go to the next list, repeat until all the lists are empty.
  • In code it could look like this:

    using ilist = std::list<int>;
    using vlist = std::vector<ilist>;
    
    ilist procesa(const vlist &vl)
    {
        auto negativo = false;
        auto temp = vl;
        auto datos = [](const vlist &vl)
        {
            for (const auto &l : vl)
                if (l.size())
                    return true;
            return false;
        };
        ilist resultado{};
    
        while (cuenta(temp))
        {
            for (auto &lista : temp)
    //                ~~~~~~ <--- Accede a la lista
            {
                for (auto v = lista.begin(), e = lista.end();
                    (v != e) && (std::signbit(*v) == negativo);)
    //              ~~^~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
    //                 \--- Mientras queden números     /
    //                                                 /
    // Mientras los números sean del signo adecuado --/
                {
                    resultado.push_back(*v);
                    v = lista.erase(v);
    //              ~~~~~~~~~~~~~~~~~~~~~~~~ <--- Extrae números
                }
            }
            negativo = !negativo;
        }
    
        return resultado;
    }
    
        
    answered by 10.09.2018 в 19:11