1, 对任意输入的正整数N,编写程序求N!的尾部连续0的个数,并指出计算复杂度。如:18!=6402373705728000,尾部连续0的个数是3。(不用考虑数值超出计算机整数界限的问题)
private static String multipy(String num1, String num2)
int len1 = num1.length();
int len2 = num2.length();
for (i = len1 -1; i >=0; --i)
n1 = num1.charAt(i) - '0';
StringBuilder tmpSB = new StringBuilder(sum);
for (j = i; j < len1 -1; ++j)
result = add(result,tmpSB.toString());
for (i = len2 -1; i >=0; --i)
n2 = num2.charAt(i) - '0';
StringBuilder tmpSB = new StringBuilder(sum);
for (j = i; j < len2 -1; ++j)
result = add(result,tmpSB.toString());
private static String add(String num1, String num2)
int len1 = num1.length();
int len2 = num2.length();
StringBuilder sb = new StringBuilder();
for (i = len1 - 1,j = len2 - 1 ; i >= 0 && j >= 0; --i,--j)
n1 = num1.charAt(i) - '0';
n2 = num2.charAt(j) - '0';
n1 = num1.charAt(i) - '0';
n2 = num2.charAt(j) - '0';
private static String factorial(int n)
for (int i = n; i >= 2; --i)
result = multipy(result,String.valueOf(i));
private static int countNFactZeroes(int n)
String result = factorial(n);//N!
System.out.println(result);
for (int i = result.length()-1; i >= 0; --i)
if (result.charAt(i) == '0')
public static void main(String[] args) throws Exception
System.out.println(countNFactZeroes(18));
解法2:连续K个0,则说明是10^K的倍数,即(2×5)^ K= 2^K× 5^K;待求的数为N*(N-1)(N-2)………1,由于每两个数至少可以分解出1个2,2肯定比5多,因此K的个数取决于上式的分解因子中有几个5的问题;能拆解出5的只可能是5的倍数,而能拆解出多少个5则看这个数是5的几次方的倍数了。时间复杂度是O(nlogn)
private static int countNFactZeroes2(int n)
for(i = 5; i <= n; i += 5) // 循环次数为n/5
for(j = i; j%5 == 0; j /= 5) // 此处的最大循环次数为 LOG5(N)
解法3:N不变,pow5以5的幂递增,此算法的思想是求出N以内所有被5整除的数的个数,所有被25整除的个数(在5的基础上多出了一个5因子),所有被125整除的个数(在25的基础上多出了一个5因子)。。。
private static int countNFactZeroes3(int n)
for(pow5 = 5; pow5 <= n; pow5 *= 5) // 此处的循环次数为LOG5(N)
设最大数为N, 设5^(n+1) > N >= 5^n
[N/5] + [N/(5^2)] + [N/(5^3)] + ... + [N/(5^n)] 即为连续0的个数
上述式子的项数为log5(N),即为循环的次数,故复杂度为log5(N)
[N/5] + [N/(5^2)] + [N/(5^3)] + ... + [N/(5^n)]
=[N/5] + [[N/5]/5] + [ [[N/5]/5]/5] + ... + [。。。]
=A1+ [A1/5] + [A2/5] + ... + [An-1/5]
即上述各项构成等比数列,An=An-1/5,等比为1/5
即对A1反复除5,只要其大于0,即相加,便得到以下算法
private static int countNFactZeroes4(int n)
等比数列的项数为log5(N),即为循环的次数,故复杂度为log5(N)
2,题目: 请编写一个 C 函数,该函数将给定的一个字符串转换成整数
/************************************************************************/
/* Author: phinecos Date:2009-05-27 */
/************************************************************************/
int StringToInt(const char* str)
assert(strlen(str) != 0);
if ((*(p+1) == 'x') || (*(p+1) == 'X'))
if (*p >='0' && *p <= '9')
result = result*radix + *p - '0';
int tmp = toupper(*p);//大写化
result = result*radix + tmp -'A'+10;
result = result*radix + *p - '0';
cout << StringToInt("-355643") << endl;
cout << StringToInt("-0x200") << endl;
cout << StringToInt("-0123") << endl;
cout << StringToInt("-0x7FFFFFFF") << endl;
3,已知两个字符数组,char a[m],b[n],m>n>1000,写程序将a中存在,但b中不存在的元素放入字符数组c中,并说明算法的时间复杂度
/************************************************************************/
/* Author: phinecos Date:2009-05-27 */
/************************************************************************/
bool isExist[256] = {false};//256个字符是否存在的标志
char* merge(char a[], int n, char b[],int m)
if (isExist[b[i]] == true)
for (i = 0; i < 256; ++i)
char a[] = {'a','c','4','s','v','y','Y','C','E'};
char b[] = {'c','y',',','u','r'};
int n = sizeof(a) / sizeof(char);
int m = sizeof(b) / sizeof(char);
char *c = merge(a,n,b,m);
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2009/05/27/1490921.html 转载请自行联系原作者