某个数字出现的次数
来源:互联网 发布:东方中原电子白板软件 编辑:程序博客网 时间:2024/05/16 14:44
在
http://bbs.chinaunix.net/thread-1191740-1-2.html
有个网友提问。
本人写了个程序,基本可以解决这个问题。
题目:
写一个函数f(n),能得到0到1234567890之间的任意一个数中出现1的次数
例如f(0)=0,f(1)=1,f(12)=5
本人把她扩展了一下,她可以查到任意10个数字出现的次数。她可以自定义开始和结束点,
_findOneOf0_9NumberAppearsTimes_method_2()只要在封装一次其实也是可以使用开始和结束点的,这里本人就不给出了。其实还可以在扩展成对于任意进制适用的,不只适用于10进制,这个我也不给出了。
不过_findOneOf0_9NumberAppearsTimes_method_2()对于“边界值”的计算可能出现出现问题,如果出现问题,请给本人留言或写信(cpdoor@163.com )指出。
这里本人提供了两个函数
findOneOf0_9NumberAppearsTimes_method_1()和_findOneOf0_9NumberAppearsTimes_method_2()
都可以得出结果。不过显然前者和后者的执行时间差很多!就像提问的那样,在计算
1234567890
时,这个优势就显示出来了。其实
_findOneOf0_9NumberAppearsTimes_method_2()
还是不是最快的!我能想到最快的方法是利用查表的方法,就是事先把结果存在一个表中,这应该是最快的,不过前期要准备一下!呵呵!
findOneOf0_9NumberAppearsTimes_method_1()
的基本原理就是正常的穷举遍历,可以很正确,但是一定是最慢的。
_findOneOf0_9NumberAppearsTimes_method_2()
的基本原理就是KEY按照个位,十位,百位...出现的次数和就是KEY出现的次数了。
PS:
任何关于更快的修改意见和扩展性(扩展到不同制式,比如16进制)的建议留言都是欢迎的。
//=============================================================================
// 10^n, value of 10's power N
int _10_power_N( const int iN )
{
int iTemp = 1;
for( int i = iN; i > 0; --i )
{
iTemp *= 10;
}
return iTemp;
}
// compute number digit
int digitIs( int iN )
{
int iDigit = 0;
do
{
++iDigit;
iN /= 10;
}while( iN > 0 );
return iDigit;
}
// Find one of the [0-9] number appears times, whose zone is from iBegin to iEnd
// The Basic method for this question, which called method_1
int findOneOf0_9NumberAppearsTimes_method_1( const int iKey ,const int iBegin, const int iEnd )
{
int iTimes = 0;
int iTemp = 0;
int iTempI = 0;
#ifdef _DEBUG
int iTempEnd = iEnd;
int iLongest = digitIs( iTempEnd );
int iLowestDigit = 0;
int iMiddleDigit = 0;
int iHighestDigit = 0;
#endif // _DEBUG
for( int i = iBegin; i <= iEnd; ++i )
{
iTempI = i;
do{
iTemp = iTempI % 10;
if( iTemp == iKey )
{
++iTimes;
#ifdef _DEBUG
int iDigit_iTempI = digitIs( iTempI );
int iDigit_i = digitIs( i );
if( iDigit_iTempI == iDigit_i )
{
++iLowestDigit;
}
else if( ( iDigit_i == iLongest ) && ( iDigit_iTempI == 1 ) )
{
++iHighestDigit;
}
else
{
++iMiddleDigit;
}
#endif // _DEBUG
}
iTempI /=10;
}while( iTempI != 0 );
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
int _findOneOf0_9NumberAppearsTimes_method_2( const int iKey ,const int iEnd )
{
int iTimes = 0;
int iDigit = 0;
int iTempEnd = iEnd;
int iLastTempEnd = iEnd;
int iTemp = 0;
#ifdef _DEBUG
int iLowestDigit = 0;
int iMiddleDigit = 0;
int iHighestDigit = 0;
#endif // _DEBUG
iDigit = digitIs( iTempEnd );
if( iKey == 0 )
{
for( int i = 0; i < ( iDigit -1 ); ++i )
{
if( i == 0 )
{
// lowest digit
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
else
{
// other middle digits
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( ( iTemp - 1 ) * _10_power_N( i - 0 ) );
#ifdef _DEBUG
iMiddleDigit += ( ( iTemp - 1 ) * _10_power_N( i - 0
) );
#endif // _DEBUG
iTimes += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#ifdef _DEBUG
iMiddleDigit += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
iLastTempEnd = iTempEnd;
iTempEnd /= 10;
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
for( int i = 0; i < ( iDigit -1 ); ++i )
{
if( i == 0 )
{
// lowest digit
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
else
{
// other middle digits
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
iTimes += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#ifdef _DEBUG
iMiddleDigit += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
iLastTempEnd = iTempEnd;
iTempEnd /= 10;
}
// highest digit
iTemp = iEnd / _10_power_N( iDigit -1 );
if( iTemp > iKey )
{
iTimes += _10_power_N( iDigit - 1 );
#ifdef _DEBUG
iHighestDigit += _10_power_N( iDigit - 1 );
#endif // _DEBUG
}
else if( iTemp == iKey )
{
iTimes += ( iEnd - iTemp * _10_power_N( iDigit -1 ) + 1 );
#ifdef _DEBUG
iHighestDigit += ( iEnd - iTemp * _10_power_N( iDigit -1 ) + 1 );
#endif // _DEBUG
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
int main(int argc, _TCHAR* argv[])
{
int iN;
int iBegin = 0;
int iEnd = 1004 ;
printf(" %d - %d\n", iBegin, iEnd );
for( int i = 0; i < 10; ++i )
{
printf( "==============================================================\n" );
#ifdef _DEBUG
iN = findOneOf0_9NumberAppearsTimes_method_1( i, iBegin, iEnd );
printf( "-> %d %d\n", i, iN );
#endif // _DEBUG
iN = _findOneOf0_9NumberAppearsTimes_method_2( i, iEnd );
printf( "#-> %d %d\n", i, iN );
}
getchar();
return 0;
}
http://bbs.chinaunix.net/thread-1191740-1-2.html
有个网友提问。
本人写了个程序,基本可以解决这个问题。
题目:
写一个函数f(n),能得到0到1234567890之间的任意一个数中出现1的次数
例如f(0)=0,f(1)=1,f(12)=5
本人把她扩展了一下,她可以查到任意10个数字出现的次数。她可以自定义开始和结束点,
_findOneOf0_9NumberAppearsTimes_method_2()只要在封装一次其实也是可以使用开始和结束点的,这里本人就不给出了。其实还可以在扩展成对于任意进制适用的,不只适用于10进制,这个我也不给出了。
不过_findOneOf0_9NumberAppearsTimes_method_2()对于“边界值”的计算可能出现出现问题,如果出现问题,请给本人留言或写信(cpdoor@163.com )指出。
这里本人提供了两个函数
findOneOf0_9NumberAppearsTimes_method_1()和_findOneOf0_9NumberAppearsTimes_method_2()
都可以得出结果。不过显然前者和后者的执行时间差很多!就像提问的那样,在计算
1234567890
时,这个优势就显示出来了。其实
_findOneOf0_9NumberAppearsTimes_method_2()
还是不是最快的!我能想到最快的方法是利用查表的方法,就是事先把结果存在一个表中,这应该是最快的,不过前期要准备一下!呵呵!
findOneOf0_9NumberAppearsTimes_method_1()
的基本原理就是正常的穷举遍历,可以很正确,但是一定是最慢的。
_findOneOf0_9NumberAppearsTimes_method_2()
的基本原理就是KEY按照个位,十位,百位...出现的次数和就是KEY出现的次数了。
PS:
任何关于更快的修改意见和扩展性(扩展到不同制式,比如16进制)的建议留言都是欢迎的。
//=============================================================================
// 10^n, value of 10's power N
int _10_power_N( const int iN )
{
int iTemp = 1;
for( int i = iN; i > 0; --i )
{
iTemp *= 10;
}
return iTemp;
}
// compute number digit
int digitIs( int iN )
{
int iDigit = 0;
do
{
++iDigit;
iN /= 10;
}while( iN > 0 );
return iDigit;
}
// Find one of the [0-9] number appears times, whose zone is from iBegin to iEnd
// The Basic method for this question, which called method_1
int findOneOf0_9NumberAppearsTimes_method_1( const int iKey ,const int iBegin, const int iEnd )
{
int iTimes = 0;
int iTemp = 0;
int iTempI = 0;
#ifdef _DEBUG
int iTempEnd = iEnd;
int iLongest = digitIs( iTempEnd );
int iLowestDigit = 0;
int iMiddleDigit = 0;
int iHighestDigit = 0;
#endif // _DEBUG
for( int i = iBegin; i <= iEnd; ++i )
{
iTempI = i;
do{
iTemp = iTempI % 10;
if( iTemp == iKey )
{
++iTimes;
#ifdef _DEBUG
int iDigit_iTempI = digitIs( iTempI );
int iDigit_i = digitIs( i );
if( iDigit_iTempI == iDigit_i )
{
++iLowestDigit;
}
else if( ( iDigit_i == iLongest ) && ( iDigit_iTempI == 1 ) )
{
++iHighestDigit;
}
else
{
++iMiddleDigit;
}
#endif // _DEBUG
}
iTempI /=10;
}while( iTempI != 0 );
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
int _findOneOf0_9NumberAppearsTimes_method_2( const int iKey ,const int iEnd )
{
int iTimes = 0;
int iDigit = 0;
int iTempEnd = iEnd;
int iLastTempEnd = iEnd;
int iTemp = 0;
#ifdef _DEBUG
int iLowestDigit = 0;
int iMiddleDigit = 0;
int iHighestDigit = 0;
#endif // _DEBUG
iDigit = digitIs( iTempEnd );
if( iKey == 0 )
{
for( int i = 0; i < ( iDigit -1 ); ++i )
{
if( i == 0 )
{
// lowest digit
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
else
{
// other middle digits
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( ( iTemp - 1 ) * _10_power_N( i - 0 ) );
#ifdef _DEBUG
iMiddleDigit += ( ( iTemp - 1 ) * _10_power_N( i - 0
) );
#endif // _DEBUG
iTimes += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#ifdef _DEBUG
iMiddleDigit += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
iLastTempEnd = iTempEnd;
iTempEnd /= 10;
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
for( int i = 0; i < ( iDigit -1 ); ++i )
{
if( i == 0 )
{
// lowest digit
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iLowestDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
else
{
// other middle digits
if( ( iTempEnd % 10 ) > iKey )
{
iTemp = iTempEnd / 10 + 1;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
else if( ( iTempEnd % 10 ) == iKey )
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
iTimes += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#ifdef _DEBUG
iMiddleDigit += ( iEnd - iTempEnd * _10_power_N( i - 0 ) + 1 );
#endif // _DEBUG
}
else
{
iTemp = iTempEnd / 10;
iTimes += ( iTemp * _10_power_N( i ) );
#ifdef _DEBUG
iMiddleDigit += ( iTemp * _10_power_N( i ) );
#endif // _DEBUG
}
}
iLastTempEnd = iTempEnd;
iTempEnd /= 10;
}
// highest digit
iTemp = iEnd / _10_power_N( iDigit -1 );
if( iTemp > iKey )
{
iTimes += _10_power_N( iDigit - 1 );
#ifdef _DEBUG
iHighestDigit += _10_power_N( iDigit - 1 );
#endif // _DEBUG
}
else if( iTemp == iKey )
{
iTimes += ( iEnd - iTemp * _10_power_N( iDigit -1 ) + 1 );
#ifdef _DEBUG
iHighestDigit += ( iEnd - iTemp * _10_power_N( iDigit -1 ) + 1 );
#endif // _DEBUG
}
#ifdef _DEBUG
printf( "Lowest:%d, Middle:%d, Highest:%d\t", iLowestDigit, iMiddleDigit, iHighestDigit );
#endif // _DEBUG
return iTimes;
}
int main(int argc, _TCHAR* argv[])
{
int iN;
int iBegin = 0;
int iEnd = 1004 ;
printf(" %d - %d\n", iBegin, iEnd );
for( int i = 0; i < 10; ++i )
{
printf( "==============================================================\n" );
#ifdef _DEBUG
iN = findOneOf0_9NumberAppearsTimes_method_1( i, iBegin, iEnd );
printf( "-> %d %d\n", i, iN );
#endif // _DEBUG
iN = _findOneOf0_9NumberAppearsTimes_method_2( i, iEnd );
printf( "#-> %d %d\n", i, iN );
}
getchar();
return 0;
}
- 某个数字出现的次数
- 记录某个数字出现的次数
- 计算数值区间内某个数字出现的次数
- 反转字符串、整形数组某个数字出现的次数、排序
- 查找数组中某个出现次数超过数组长度一半的数字
- 计算数字出现的次数
- vi统计某个匹配出现的次数
- Linux 统计某个字符串出现的次数
- Linux 统计某个字符串出现的次数
- Linux 统计某个字符串出现的次数
- 统计某个单词出现的次数
- Linux 统计某个字符串出现的次数
- 统计某个字符串出现的次数
- 统计字符出现的次数和数字出现的次数
- 返回某个字符串中某个字符串中出现的次数
- 随机生成 50 个数字(整数),每个数字的范围是[10, 50],统计每个数字出现的次数以及 出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来,如果某个数 字出现次数为 0,则不要打印
- 统计一定范围内的数字出现次数
- 出现次数超过一半的数字
- PC Windows 测时间消耗的程序
- 设计模式php实例:观察者模式
- ‘单引号’的有趣用法
- Android学习笔记(五)常用控件上
- 高效程序猿之(二)VS2010优秀插件
- 某个数字出现的次数
- 自己动手学TCP/IP--TCP连接三次握手
- 博弈题集
- Android学习笔记(五)常用控件中
- TICK 与 CLOCK CYCLE 的区别
- 一路走来
- Argus (P2051)
- 连字符,double pound
- Android学习笔记(五)常用控件下