1 丑数,阿格里数
阿格里数,即丑数(Ugly Number)、逊数(Humble Number)。
一般而言:把只包含质因子2,3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但7、14不是,因为它们包含质因子7。 习惯上我们把1当做是第一个丑数。
拓展一下:对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S。这个正整数集合包括,p1、p1*p2、p1*p1、p1*p2*p3...(还有其它)。该集合被称为S集合的“丑数集合”。
计算结果:
2 源程序,文本格式
using System;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
public static partial class Number_Sequence
{
private static int UglyNumber_MaxDivide(int a, int b)
{
while (a % b == 0)
{
a = a / b;
}
return a;
}
public static int IsUglyNumber_Original(int no)
{
no = UglyNumber_MaxDivide(no, 2);
no = UglyNumber_MaxDivide(no, 3);
no = UglyNumber_MaxDivide(no, 5);
return (no == 1) ? 1 : 0;
}
public static int Ugly_Number(int index)
{
int i = 1;
int count = 1;
while (index > count)
{
i++;
if (IsUglyNumber_Original(i) == 1)
{
count++;
}
}
return i;
}
public static int Ugly_Number_Second(int n)
{
int[] ugly = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no = Math.Min(next_multiple_of_2, Math.Min(next_multiple_of_3, next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
return next_ugly_no;
}
public static int Ugly_Number_Third(int n)
{
SortedSet<int> t = new SortedSet<int>();
t.Add(1);
int i = 1;
while (i < n && t.Count > 0)
{
int temp = t.Min;
t.Remove(temp);
t.Add(temp * 2);
t.Add(temp * 3);
t.Add(temp * 5);
i++;
}
return t.Min;
}
private static int Ugly_Number_UpperBound(int[] array, int left, int right, int element)
{
while (left < right)
{
int middle = left + (right - left) / 2;
if (array[middle] > element)
{
right = middle;
}
else
{
left = middle + 1;
}
}
return left;
}
public static int Ugly_Number_Fourth(int n)
{
int[] pow = new int[40];
for (int i = 0; i < 40; ++i)
{
pow[i] = 1;
}
for (int i = 1; i <= 30; ++i)
{
pow[i] = pow[i - 1] * 2;
}
int left = 1;
int right = 2147483647;
int ans = -1;
while (left <= right)
{
int mid = left + ((right - left) / 2);
int cnt = 0;
for (long i = 1; i <= mid; i *= 5)
{
for (long j = 1; j * i <= mid; j *= 3)
{
cnt += Ugly_Number_UpperBound(pow, 0, 31, (int)(mid / (i * j)));
}
}
if (cnt < n)
{
left = mid + 1;
}
else
{
right = mid - 1;
ans = mid;
}
}
return ans;
}
}
}
————————————————————
POWER BY TRUFFER.CN
3 代码格式
using System;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
public static partial class Number_Sequence
{
private static int UglyNumber_MaxDivide(int a, int b)
{
while (a % b == 0)
{
a = a / b;
}
return a;
}
public static int IsUglyNumber_Original(int no)
{
no = UglyNumber_MaxDivide(no, 2);
no = UglyNumber_MaxDivide(no, 3);
no = UglyNumber_MaxDivide(no, 5);
return (no == 1) ? 1 : 0;
}
public static int Ugly_Number(int index)
{
int i = 1;
int count = 1;
while (index > count)
{
i++;
if (IsUglyNumber_Original(i) == 1)
{
count++;
}
}
return i;
}
public static int Ugly_Number_Second(int n)
{
int[] ugly = new int[n];
int i2 = 0, i3 = 0, i5 = 0;
int next_multiple_of_2 = 2;
int next_multiple_of_3 = 3;
int next_multiple_of_5 = 5;
int next_ugly_no = 1;
ugly[0] = 1;
for (int i = 1; i < n; i++)
{
next_ugly_no = Math.Min(next_multiple_of_2, Math.Min(next_multiple_of_3, next_multiple_of_5));
ugly[i] = next_ugly_no;
if (next_ugly_no == next_multiple_of_2)
{
i2 = i2 + 1;
next_multiple_of_2 = ugly[i2] * 2;
}
if (next_ugly_no == next_multiple_of_3)
{
i3 = i3 + 1;
next_multiple_of_3 = ugly[i3] * 3;
}
if (next_ugly_no == next_multiple_of_5)
{
i5 = i5 + 1;
next_multiple_of_5 = ugly[i5] * 5;
}
}
return next_ugly_no;
}
public static int Ugly_Number_Third(int n)
{
SortedSet<int> t = new SortedSet<int>();
t.Add(1);
int i = 1;
while (i < n && t.Count > 0)
{
int temp = t.Min;
t.Remove(temp);
t.Add(temp * 2);
t.Add(temp * 3);
t.Add(temp * 5);
i++;
}
return t.Min;
}
private static int Ugly_Number_UpperBound(int[] array, int left, int right, int element)
{
while (left < right)
{
int middle = left + (right - left) / 2;
if (array[middle] > element)
{
right = middle;
}
else
{
left = middle + 1;
}
}
return left;
}
public static int Ugly_Number_Fourth(int n)
{
int[] pow = new int[40];
for (int i = 0; i < 40; ++i)
{
pow[i] = 1;
}
for (int i = 1; i <= 30; ++i)
{
pow[i] = pow[i - 1] * 2;
}
int left = 1;
int right = 2147483647;
int ans = -1;
while (left <= right)
{
int mid = left + ((right - left) / 2);
int cnt = 0;
for (long i = 1; i <= mid; i *= 5)
{
for (long j = 1; j * i <= mid; j *= 3)
{
cnt += Ugly_Number_UpperBound(pow, 0, 31, (int)(mid / (i * j)));
}
}
if (cnt < n)
{
left = mid + 1;
}
else
{
right = mid - 1;
ans = mid;
}
}
return ans;
}
}
}