简体   繁体   中英

cin is not taking in the last input in a while loop

In the following code segment, the cin inside the while loop, which is nested inside the while loop in the main function, is somehow not working during the last input (ie, when h == n-1 ) and reporting a segmentation fault instead.

I figured this out by using the print statements (which are commented in the code below), one at the start of the inner while loop, one after the cin statement (to find the read values of v and x decremented by 1) and one outside the while loop. The third cout statement doesn't execute, from which I concluded that the segmentation fault is inside the while loop.

Moreover, in the last iteration of the inner while loop, the cout statement after the cin statement (to print the values of v and x ) also didn't execute. And so, I think that the cin inside the inner while loop isn't working in the last iteration.

I tried searching a lot and put in the cin.clear() and cin.ignore(numeric_limits<streamsize>::max(), '\n'); statements but still no use!

Why is there such an issue?

#include <bits/stdc++.h>

using namespace std;
vector <vector<int>> adj;
vector<unordered_set <int>> leaf;

int process(int node, int *pans, int k){
    *pans = *pans + (leaf[node].size() / k) * k;
    int temp = (leaf[node].size() / k) * k;
    if(temp == 0) return 0;
    for(auto it : leaf[node]){
        if(temp == 0) break;
        leaf[node].erase(it);
        auto j = find(adj[node].begin(), adj[node].end(), it);
        adj[node].erase(j);
        temp --;
    }
    if(adj[node].size() == 1){
        leaf[adj[node][0]].insert(node);
        process(adj[node][0], pans, k);
    }
    return 0;
}

int main(){
    int t, v, x, n, k;
    cin>>t;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    while(t--){
        int ans = 0;
        cin>>n>>k;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        adj.resize(n);
        int h = 1;
        while(h < n){
            // cout<<"r";
            cin>>v>>x;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            v --; x --;
            cout<<v<<" "<<x<<"\n";
            adj[v].push_back(x);
            adj[x].push_back(v);
            h++;
        }
        // cout<<"out";
        leaf.resize(n);
        for(int i = 0; i < n; i ++){
            if(adj[i].size() == 1) leaf[adj[i][0]].insert(i);
        }
        for(int i = 0; i < n; i ++){
            if(leaf[i].size() >= k) process(i, &ans, k);
        }
        cout<<ans<<"\n";
        adj.clear();
        leaf.clear();
    }
}

Following is an example of the input:

1
8 3
1 2
1 5
7 6
6 8
3 1
6 4
6 1

The error is here

for(auto it : leaf[node]){
    if(temp == 0) break;
    leaf[node].erase(it);
    auto j = find(adj[node].begin(), adj[node].end(), it);
    adj[node].erase(j);
    temp --;
}

By modifying the unordered_set leaf[node].erase(it); you are invalidating the implicit iterator used by the range based for loop. Rewrite your loop with an explciit iterator so you can account for the iterator invalidation. Like this

for (auto i = leaf[node].begin(); i != leaf[node].end(); ) {
    if(temp == 0) break;
    auto it = *i;
    i = leaf[node].erase(i);
    auto j = find(adj[node].begin(), adj[node].end(), it);
    adj[node].erase(j);
    temp --;
}

With this loop your code runs to completion (at least for me). I've no idea if the output is correct or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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