判断是否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 于厦门