cin 没有接受 while 循环中的最后一个输入
cin is not taking in the last input in a while loop
在下面的代码段中,while
循环中的 cin
嵌套在 main
函数的 while
循环中,但不知何故无法正常工作在最后一次输入期间(即 h == n-1
时)并改为报告分段错误。
我通过使用 print
语句(在下面的代码中注释)解决了这个问题,一个在内部 while
循环的开始,一个在 cin
之后语句(查找 v
和 x
的读取值减 1)和一个在 while
循环之外的语句。第三个 cout
语句没有执行,由此我得出结论,分段错误在 while
循环内。
此外,在内部 while
循环的最后一次迭代中, cin
语句之后的 cout
语句(打印 v
和 x
) 也没有执行。因此,我认为内部 while
循环中的 cin
在上一次迭代中不起作用。
我尝试了很多搜索并输入了 cin.clear()
和 cin.ignore(numeric_limits<streamsize>::max(), '\n');
语句,但仍然没有用!
为什么会出现这样的问题?
#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();
}
}
以下是输入示例:
1
8 3
1 2
1 5
7 6
6 8
3 1
6 4
6 1
错误在这里
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 --;
}
通过修改 unordered_set leaf[node].erase(it);
您将使基于范围的 for 循环使用的隐式迭代器无效。用一个 explciit 迭代器重写你的循环,这样你就可以解决迭代器失效的问题。像这样
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 --;
}
通过这个循环,您的代码运行完成(至少对我而言)。我不知道输出是否正确。
在下面的代码段中,while
循环中的 cin
嵌套在 main
函数的 while
循环中,但不知何故无法正常工作在最后一次输入期间(即 h == n-1
时)并改为报告分段错误。
我通过使用 print
语句(在下面的代码中注释)解决了这个问题,一个在内部 while
循环的开始,一个在 cin
之后语句(查找 v
和 x
的读取值减 1)和一个在 while
循环之外的语句。第三个 cout
语句没有执行,由此我得出结论,分段错误在 while
循环内。
此外,在内部 while
循环的最后一次迭代中, cin
语句之后的 cout
语句(打印 v
和 x
) 也没有执行。因此,我认为内部 while
循环中的 cin
在上一次迭代中不起作用。
我尝试了很多搜索并输入了 cin.clear()
和 cin.ignore(numeric_limits<streamsize>::max(), '\n');
语句,但仍然没有用!
为什么会出现这样的问题?
#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();
}
}
以下是输入示例:
1
8 3
1 2
1 5
7 6
6 8
3 1
6 4
6 1
错误在这里
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 --;
}
通过修改 unordered_set leaf[node].erase(it);
您将使基于范围的 for 循环使用的隐式迭代器无效。用一个 explciit 迭代器重写你的循环,这样你就可以解决迭代器失效的问题。像这样
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 --;
}
通过这个循环,您的代码运行完成(至少对我而言)。我不知道输出是否正确。