判断是否3的幂 解决方法

可西哥 2007-02-10 03:52:56
在CSDN上看到一个关于判断一个数是否3的幂的问题,要求是使用简洁的算法,

于是结合被3整除的数的特点,以及大数的运算,得到了以下的程序,思路比较简单

主要解决以下几个问题:

一是判断一个字串是否有效的数字,这个比较简单就不细说了;

二是判断一个数是否能被3整除;这个只要将各位数上的数相加,得到各位数之和,

再判断各位数之和是否3的倍数;一个10万位的数,各位数之和也不过90万,使用一个

unsigned int足够了;

三是如何将一个大数除以3;直接将每一位除3,再考虑上一位的余数即可;

以下是C++源程序:



// Judge3.cpp : Defines the entry point for the console application.
/*
判断一个数是否3的幂,考虑大数的情况
算法要求简洁

思路:
将大数表示成数组,进行判断
*/

#include "stdafx.h"
#include "stdio.h"

/*
函数 判断一个字串是否数字,并返回位数
*/
bool isnumeric(char* big, unsigned int *intLen)
{
unsigned int i = 0; //临时变量
unsigned int intPos=0; //某一位的值

*intLen = 0;
for (i=0;big[i]!=0;i++,(*intLen)++)
{
intPos = (int)big[i]-'0';
if (intPos<0||intPos>9)
{
return 0;
}
}
return 1;
}

/*
函数 判断一个大数是否能被3整除
使用各位相加的方法进行判断
同时过滤比3小的数
*/
bool CanDiv3(char* big)
{
unsigned int i = 0; //临时变量
unsigned int intLen=0; //位数
unsigned int intPos=0; //某一位的值
unsigned int intSum = 0; //各位和

//计算位数
//intLen=sizeof(big);
//计算各位和
for (i=0;big[i]!=0;i++,intLen++)
{
intPos = (int)big[i]-'0';
intSum +=intPos;
}
//过滤比3小的数
if (intLen<=1 && intSum <3)
{
return 0;
}

if (intSum % 3==0)
{
return 1;
}
else
{
return 0;
}
}


/*
函数 大数除3
函数返回是否处理成功;
如果不能被3整除,不做处理

*/
bool Div3(char* big)
{
unsigned int i = 0; //临时变量,正在处理左第几位
unsigned int intLen=0; //结果的位数
unsigned int intPos=0; //某一位的值
unsigned int intDiv=0; //除3后的结果
unsigned int intMod = 0; //余数
bool blnCan = false; //是否能被3整除

blnCan = CanDiv3(big);
if (!blnCan)
{
return 0;
}

for (i=0;big[i]!=0;i++)
{
intPos = (int)big[i]-'0';
intDiv = (intMod*10+intPos)/3;
intMod = (intMod*10+intPos) % 3;
if (!(intLen==0&&intDiv==0))
{
big[intLen]=intDiv+'0';
//big[i]=intDiv+'0';
intLen++;
}
}
big[intLen]=0;
return 1;
}

/*
函数 判断是否3的幂
函数返回3的几次幂
如果不是3的幂,则返回0
*/

int Power3(char* big)
{
unsigned int intRet=0; //返回值
unsigned int intLen=0; //长度
unsigned intP=0; //幂
bool blnL = false; //判断返回值

blnL = isnumeric(big,&intLen);
if (!blnL){return -1;}
while (Div3(big))
{
intRet++;
//判断
blnL=isnumeric(big,&intLen);
if (intLen==1&&big[0]=='1')
{
return intRet;
break;
}
}
return 0;
}

//主程序
int main(int argc, char* argv[])
{
char strInput[1024];

char* chrTest="3243243231";
bool tt=false;
unsigned int intLen=0;
int intP=0;
bool lo=true;

while (lo)
{
printf("\n请输入整数(0退出):\n");
scanf("%s",&strInput);

chrTest = strInput;
tt=isnumeric(chrTest,&intLen);
if (intLen==1&&chrTest[0]=='0')
{
break;
}

//printf("\n您输入的是 %s\n",strInput);
if (tt)
{
printf("它共有%d位\n",intLen);
tt=CanDiv3(chrTest);
if (tt)
{
printf("它能被3整除\n");
/*
tt=Div3(chrTest);
if (tt)
{
printf("除3结果为%s\n\n",chrTest);
}
*/
intP = Power3(chrTest);
if (intP>0)
{
printf("它是3的%d次幂\n",intP);
}
else
{
printf("它不是3的幂\n");
}

}
else
printf("它不能被3整除\n");
}
else
{
printf("您输入的不是有效的数字!\n");
}
}

return 0;
}

运行结果如下:



请输入整数(0退出):
adf1130
您输入的不是有效的数字!

请输入整数(0退出):
123.21
您输入的不是有效的数字!

请输入整数(0退出):
1
它共有1位
它不能被3整除

请输入整数(0退出):
81
它共有2位
它能被3整除
它是3的4次幂

请输入整数(0退出):
84
它共有2位
它能被3整除
它不是3的幂

请输入整数(0退出):
3433683820292512484657849089281
它共有31位
它能被3整除
它是3的64次幂

请输入整数(0退出):
5164687961316549165468645642
它共有28位
它能被3整除
它不是3的幂

请输入整数(0退出):
0
Press any key to continue

以上结果在Visual C++ 6下运行通过

稍加修改也可以判断其它数的幂,但只限于一位数,如果是二位数,在除法上需要加以改进。

2007年2月10日 xmxoxo 于厦门
...全文
314 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
johnhanscn 2007-02-13
  • 打赏
  • 举报
回复
做数值分析计算,还得数学好的人,呵呵
bleakxandu 2007-02-11
  • 打赏
  • 举报
回复
x = 3^n;
lgx = n*lg3
只要判断 lgx/lg3是否整除即可.

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧