从 C++ 中的集合中删除最后一个元素
Erasing last element from a set in C++
#include <bits/stdc++.h>
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define SZ(s) int(s.size())
using namespace std;
typedef long long ll;
int main()
{
FIN;
set<ll>s;
ll N, M;
cin >> N >> M;
ll x;
for(ll i = 0; i < N+M; i++)
{
cin >> x;
if(x==-1)
{
auto x = *s.rbegin();
cout<<x<<'\n';
//-------------------------------------------------------------------------------------------------
s.erase( --s.end() ); // --s.end() when replaced with s.rbegin(), gives an error
//------------------------------------------------------------------------------------------------
}
else
{
s.insert( x );
}
}
}
在水平线之间的代码中,我试图从集合中删除最后一个元素。
当我写 s.erase( s.rbegin( ) ) 而不是 s.erase( --s.end( ) ) ,它给了我一个编译错误说:
**error: no matching function for call to ‘std::set<long long int>::erase(std::set<long long int>::reverse_iterator)’
20 | s.erase( s.rbegin() );**
不是 s.rbegin() 和 --s.end() 指向同一个元素?
std::set::rbegin returns a reverse_iterator,技术上指向同一件事,但集合没有接收 reverse_iterator 作为参数的擦除方法。
reverse_iterator
的实现方式与 iterator
不同。 iterator
的逻辑地址和物理地址相同,但 reverse_iterator
的逻辑地址和物理地址不同。例如:s.end()
和 s.rbegin()
具有相同的物理地址但是 *s.end()
会给你一个错误但是 *s.rbegin()
会给你容器的最后一个值 s
.
下面的代码会让事情变得清晰:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> S{ 1, 2, 3 };
set<int>::iterator itr = S.find(2);
cout << *itr << endl;
set<int>::reverse_iterator r_itr(itr);
cout << *r_itr << endl;
cout << itr._Ptr << ' ' << r_itr.base()._Ptr << endl;
//S.erase(r_itr); // ERROR!
S.erase(r_itr.base());
for (int e : S)
cout << e << ' ';
}
在我的机器上,它产生了以下输出:
2
1
00F85DA8 00F85DA8
1 3
#include <bits/stdc++.h>
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define SZ(s) int(s.size())
using namespace std;
typedef long long ll;
int main()
{
FIN;
set<ll>s;
ll N, M;
cin >> N >> M;
ll x;
for(ll i = 0; i < N+M; i++)
{
cin >> x;
if(x==-1)
{
auto x = *s.rbegin();
cout<<x<<'\n';
//-------------------------------------------------------------------------------------------------
s.erase( --s.end() ); // --s.end() when replaced with s.rbegin(), gives an error
//------------------------------------------------------------------------------------------------
}
else
{
s.insert( x );
}
}
}
在水平线之间的代码中,我试图从集合中删除最后一个元素。
当我写 s.erase( s.rbegin( ) ) 而不是 s.erase( --s.end( ) ) ,它给了我一个编译错误说:
**error: no matching function for call to ‘std::set<long long int>::erase(std::set<long long int>::reverse_iterator)’
20 | s.erase( s.rbegin() );**
不是 s.rbegin() 和 --s.end() 指向同一个元素?
std::set::rbegin returns a reverse_iterator,技术上指向同一件事,但集合没有接收 reverse_iterator 作为参数的擦除方法。
reverse_iterator
的实现方式与 iterator
不同。 iterator
的逻辑地址和物理地址相同,但 reverse_iterator
的逻辑地址和物理地址不同。例如:s.end()
和 s.rbegin()
具有相同的物理地址但是 *s.end()
会给你一个错误但是 *s.rbegin()
会给你容器的最后一个值 s
.
下面的代码会让事情变得清晰:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> S{ 1, 2, 3 };
set<int>::iterator itr = S.find(2);
cout << *itr << endl;
set<int>::reverse_iterator r_itr(itr);
cout << *r_itr << endl;
cout << itr._Ptr << ' ' << r_itr.base()._Ptr << endl;
//S.erase(r_itr); // ERROR!
S.erase(r_itr.base());
for (int e : S)
cout << e << ' ';
}
在我的机器上,它产生了以下输出:
2 1 00F85DA8 00F85DA8 1 3