项目场景:
最近在刷算法笔记的进制转换,想把常用的功能封装为函数,方便成为一个模板,供后续使用。但是封装为模板之后,就遇到了很多问题,表面看起来结果是对的,但是提交之后却是各种报错。故在此记录一下,防止以后踩坑!
1、把10进制数y转化为Q进制数z,想把z直接变成int型输出,而不是逐位输出 :这样的结果虽然看起来都是对的,但是无法通过测试。具体原因不明,但是有一个比较合理的理由(若Q为16,那怎么可以把A,B,C这类特殊标记转化为10,11等数字输出呢,所以这样肯定不合理)
2、转化为逐个输出后,依旧无法通过 : 查找了比较久的原因。因为codeup上不能查看报错原因。幸好牛客网上有同类型题目,在那个编辑器上可以更好调试和看到自己代码出错情况。
根据报错信息提示:
运行超时,因为自己本地测试2 0 0 这组数据,确实只输出了一个结果

原来是时间限制是1~2秒,而我单个测试就是10s以上。看来是代码长度和函数之间调用关系导致超时。
原始代码
#include<cstdio>
#include<math.h>
#include<string.h>
// 把转化为的进制(非10进制)逐个输出
void displayOneToOne (int a[], int n) {
// 参数: a(数组) 、 n(数组长度)
// 次函数最多到16进制的输出,因为超过16进制的并不常见
for(int i=n-1;i>=0;i--){
if(a[i]>9) {
switch(a[i]) {
case 10:
printf("A");
break;
case 11:
printf("B");
break;
case 12:
printf("C");
break;
case 13:
printf("D");
break;
case 14:
printf("E");
break;
case 15:
printf("F");
break;
default:
printf("该进制超过16进制,无法输出!");
}
} else {
printf("%d",a[i]);
}
}
printf("\n");
}
// 把int型数组反序变成int型
int changeToint(int a[], int n){
// 参数: a(数组) 、 n(数组长度)
int ans =0;
for(int i = n-1;i>=0;i--){
ans +=a[i]*pow(10,i);
}
return ans;
}
// 把P进制的x转化为十进制的y
int changeToOct(int x, int P){
// 参数:x(待转换数) 、 P(进制)
int y = 0;
int product = 1;
while(x !=0){
y = y + (x%10)*product;
x = x/10;
product = product*P;
}
return y; // 返回的十进制数y
}
//把十进制的y转化为Q进制的z
int changeToQ(long long y, int Q) {
// 参数: y(待转换数) 、 Q(进制)
int z[40], num=0 , n;
do
{
z[num++] = y%Q ;
y = y/Q;
}while(y!=0);
// 最后处理的结果就是z[]这个数组,但是由于在c/c++中无法把数组返回,
// 故把数组化为一串数字,返回为int型,自己区分清楚
// n = changeToint(z,num); // 目前不适用该函数,使用另一种展示函数
// 为什么不能转化为int型返回,因为进制里面除了10进制是int,其他都不是
// 比如16进制,还有A,B,C等大写字母,所以不能变成int,应该从z数组逐个输出
displayOneToOne(z,num);
return 0; // 返回0,表示转换成功,若不是,则返回n
}
int main() {
int m,A,B;
long long temp;
while(1) {
scanf("%d",&m);
if(m == 0) break;
scanf("%d %d",&A,&B);
temp = A+B;
int ans = changeToQ(temp,m);
}
return 0;
}
修改后的代码
把不用的代码直接删去,把函数转化为内部代码
#include<cstdio>
#include<math.h>
#include<string.h>
int main() {
int m;
int z[40],i;
long long temp,A,B;
while(1) {
scanf("%d",&m);
if(m == 0) break;
scanf("%lld %lld",&A,&B);
temp = A+B;
int num =0;
do
{
z[num++] = temp%m;
temp = temp/m;
}while(temp!=0);
for(i = num-1;i>=0;i--){
printf("%d",z[i]);
}
printf("\n");
}
return 0;
}
但是依旧无法通过牛客的测试,却通过了codeup的测试。在一位牛客下的读者提醒下,应该是牛客和其他OJ判断结束的条件不同,这里就不加while循环,也不去判断m是否为0结束,就通过了。
解决方案:
方法:看清题目要求,再适中取舍一个方法,此时显然直接拆分函数比较合适:
经过多次测试,牛客网可使用以下代码测试通过
#include<cstdio>
#include<math.h>
#include<string.h>
// 把转化为的进制(非10进制)逐个输出
void displayOneToOne (int a[], int n) {
// 参数: a(数组) 、 n(数组长度)
// 次函数最多到16进制的输出,因为超过16进制的并不常见
for(int i=n-1;i>=0;i--){
if(a[i]>9) {
switch(a[i]) {
case 10:
printf("A");
break;
case 11:
printf("B");
break;
case 12:
printf("C");
break;
case 13:
printf("D");
break;
case 14:
printf("E");
break;
case 15:
printf("F");
break;
default:
printf("该进制超过16进制,无法输出!");
}
} else {
printf("%d",a[i]);
}
}
printf("\n");
}
// 把int型数组反序变成int型
int changeToint(int a[], int n){
// 参数: a(数组) 、 n(数组长度)
int ans =0;
for(int i = n-1;i>=0;i--){
ans +=a[i]*pow(10,i);
}
return ans;
}
// 把P进制的x转化为十进制的y
int changeToOct(int x, int P){
// 参数:x(待转换数) 、 P(进制)
int y = 0;
int product = 1;
while(x !=0){
y = y + (x%10)*product;
x = x/10;
product = product*P;
}
return y; // 返回的十进制数y
}
//把十进制的y转化为Q进制的z
int changeToQ(long long y, int Q) {
// 参数: y(待转换数) 、 Q(进制)
int z[40], num=0 , n;
do
{
z[num++] = y%Q ;
y = y/Q;
}while(y!=0);
// 最后处理的结果就是z[]这个数组,但是由于在c/c++中无法把数组返回,
// 故把数组化为一串数字,返回为int型,自己区分清楚
// n = changeToint(z,num); // 目前不适用该函数,使用另一种展示函数
// 为什么不能转化为int型返回,因为进制里面除了10进制是int,其他都不是
// 比如16进制,还有A,B,C等大写字母,所以不能变成int,应该从z数组逐个输出
displayOneToOne(z,num);
return 0; // 返回0,表示转换成功,若不是,则返回n
}
int main() {
int m,A,B;
long long temp;
scanf("%d",&m);
scanf("%d %d",&A,&B);
temp = A+B;
int ans = changeToQ(temp,m);
return 0;
}
总结:代码结果一样,可以参考别人写的代码,多测几遍,寻找不同之处,实在不行可以试试多个平台试试,最终一定能找到解决办法!
博主在学习算法过程中遇到进制转换函数封装的问题,导致代码在不同在线评测平台上表现不一致。主要问题包括:尝试将进制转换结果直接转为整型输出失败,以及因时间限制导致的运行超时。通过调试和优化,博主发现应按题目要求调整代码,并理解不同平台的结束条件。最终,通过删除无效代码、简化函数调用和注意平台差异,实现了代码的正确运行。

774

被折叠的 条评论
为什么被折叠?



