为何__builtin_ctz及STL方法在CodeChef MAX2题中失效?
CodeChef MAX2题目:两种解法失效原因排查
CodeChef的MAX2题目要求统计二进制字符串从末尾开始到第一个'1'为止的0的数量。以下三种解法中,循环统计能得到正确答案,但使用__builtin_ctz和find_last_of的方法在OJ上返回错误,本地测试用例结果一致,现分析错误原因:
正确的循环代码
#include <iostream> using namespace std; int main() { long int N; cin >> N; string s; cin >> s; int count = 0; for (long int i = s.size()-1; i>=0; i--) { if (s[i] =='0') count++; if (s[i] == '1') break; } cout << count<<endl; return 0; }
使用__builtin_ctz的错误代码
#include <iostream> #include<math.h> using namespace std; #include<bits/stdc++.h> int main() { long int N; cin >> N; char s[N+1]; cin >> s; string p =s; long int num = strtol(s,NULL,2); cout<<__builtin_ctz(num)<<endl; return 0; }
使用find_last_of的错误代码
#include <iostream> #include<math.h> using namespace std; #include<bits/stdc++.h> int main() { long int N; cin >> N; char s[N+1]; cin >> s; string p =s; long int num = strtol(s,NULL,2); if (num%2 == 1) { cout<<"0\n"; } else { cout<<p.size()-p.find_last_of('1')-1<<endl; } return 0; }
错误原因分析
1. __builtin_ctz解法的问题
- 数值溢出:题目中二进制字符串的长度N可能远超过
long int的位数(如32位或64位),strtol无法将超长二进制字符串正确转换为long int,会导致溢出得到错误数值,__builtin_ctz基于错误数值计算,结果自然不正确。 - 未定义行为:当输入字符串全为'0'时,
num的值为0,而__builtin_ctz(0)的行为是未定义的,不同编译器会返回不可预料的结果,OJ测试用例包含这类情况时会出错。
2. find_last_of解法的问题
- 全0字符串处理错误:当输入字符串全为'0'时,
p.find_last_of('1')返回string::npos(无符号整数最大值),此时计算p.size() - string::npos -1会因无符号整数溢出得到极大错误值,而非正确结果。 - 溢出导致判断错误:同样存在
strtol转换超长字符串溢出的问题,num的值错误,导致num%2 ==1的判断逻辑失效,进而影响后续计算。
内容的提问来源于stack exchange,提问作者Naman Gupta
相关产品推荐
相关产品推荐

