对自定义2D vector排序触发运行时错误,该如何修复?
问题复现
我尝试基于特定字符的计数与其余字符计数的差值对2D vector进行排序,大部分测试用例运行正常,但如下测试用例执行异常。经调试发现,当ch='d'和ch='e'时会抛出运行时错误,暂未定位到具体问题原因。
实现逻辑
遍历a~e共5个字符作为目标字符ch,目标是删除部分字符串后让ch的出现次数最多,每次优先删除「ch出现次数减去其余字符出现总次数」差值最大的字符串。
问题代码
typedef long long int ll; void solve() { ll n; string s; cin>>n; vector<vector<ll>>v(n,vector<ll>(5,0)); unordered_map<char, ll>m; vector<string>str; unordered_map<char, ll>old; for(ll i=0;i<n;i++) { cin>>s; str.push_back(s); } for(ll i=0;i<n;i++) { for(ll j=0;j<str[i].length();j++) { v[i][str[i][j]-97]++; m[str[i][j]]++; } } old=m; ll ans=0; for(char ch='a';ch<='e';ch++) { m=old; ll sum=m['a']+m['b']+m['c']+m['d']+m['e']; if(sum-m[ch]<m[ch]) { ans=max(ans,n); } sort(v.begin(),v.end(),[ch](const vector<ll>&a,const vector<ll>&b) { return (a[ch-97]-(a[0]+a[1]+a[2]+a[3]+a[4]))<=(b[ch-97]-(b[0]+b[1]+b[2]+b[3]+b[4])); }); for(ll i=0;i<n;i++) { for(ll j=0;j<5;j++) { m[j+97]=m[j+97]-v[i][j]; } ll sumrest=m['a']+m['b']+m['c']+m['d']+m['e']; if(m[ch]>sumrest-m[ch]) { ans=max(ans,n-i-1); } } } cout<<ans<<"\n"; }
触发错误的测试用例
1 43 a d bbc a dda c e bb cbd c dc e caab d c e e bd d a a b a c d c d ba e c ecdb bdbd d e cb ac ccd cb cda da bb d c
问题原因与修复方案
- 第一个错误:
std::sort要求比较函数满足严格弱序规则,不能使用<=作为判断条件,必须改为<,否则会触发未定义行为,极端情况直接出现段错误,这就是ch为d、e时运行报错的直接原因。 - 第二个错误:代码没有对原始统计得到的
v数组做备份,第一次遍历ch='a'排序后v的顺序被永久修改,后续ch='b'到ch='e'的排序逻辑全部基于已经打乱的v数组,结果完全错误。
修正后代码
typedef long long int ll; void solve() { ll n; string s; cin>>n; vector<vector<ll>> original_v(n,vector<ll>(5,0)); // 备份原始统计结果 unordered_map<char, ll>m; vector<string>str; unordered_map<char, ll>old; for(ll i=0;i<n;i++) { cin>>s; str.push_back(s); } for(ll i=0;i<n;i++) { for(ll j=0;j<str[i].length();j++) { original_v[i][str[i][j]-97]++; m[str[i][j]]++; } } old=m; ll ans=0; for(char ch='a';ch<='e';ch++) { m=old; ll sum=m['a']+m['b']+m['c']+m['d']+m['e']; if(sum-m[ch]<m[ch]) { ans=max(ans,n); } auto v = original_v; // 每次循环都用原始数组拷贝,避免排序修改原始数据 sort(v.begin(),v.end(),[ch](const vector<ll>&a,const vector<ll>&b) { // 把<=改成<,满足严格弱序要求 return (a[ch-97]-(a[0]+a[1]+a[2]+a[3]+a[4])) < (b[ch-97]-(b[0]+b[1]+b[2]+b[3]+b[4])); }); for(ll i=0;i<n;i++) { for(ll j=0;j<5;j++) { m[j+97]=m[j+97]-v[i][j]; } ll sumrest=m['a']+m['b']+m['c']+m['d']+m['e']; if(m[ch]>sumrest-m[ch]) { ans=max(ans,n-i-1); } } } cout<<ans<<"\n"; }
内容的提问来源于stack exchange,提问作者MercuryVapor
相关产品推荐
相关产品推荐

