Algorithm 按递增顺序打印表格2^i*5^j的编号

Algorithm 按递增顺序打印表格2^i*5^j的编号,algorithm,smooth-numbers,Algorithm,Smooth Numbers,如何按递增顺序打印表格2^i*5^j的编号 For eg: 1, 2, 4, 5, 8, 10, 16, 20 我们有两个循环,一个是递增的i,第二个是递增的j从零开始,对吗?(问题标题中的乘法符号令人困惑) 你可以做一些非常简单的事情: 在数组中添加所有项 对数组进行排序 或者你需要一个有更多数学分析的解决方案 编辑:利用与问题的相似性提供更智能的解决方案 如果我们把无限多个2^i和5^j想象成两个独立的流/列表,那么这个问题看起来与众所周知的问题非常相似 因此,解决方案步骤如下: 从每个

如何按递增顺序打印表格
2^i*5^j
的编号

For eg:
1, 2, 4, 5, 8, 10, 16, 20

我们有两个循环,一个是递增的
i
,第二个是递增的
j
从零开始,对吗?(问题标题中的乘法符号令人困惑)

你可以做一些非常简单的事情:

  • 在数组中添加所有项
  • 对数组进行排序
  • 或者你需要一个有更多数学分析的解决方案

    编辑:利用与问题的相似性提供更智能的解决方案

    如果我们把无限多个
    2^i
    5^j
    想象成两个独立的流/列表,那么这个问题看起来与众所周知的问题非常相似

    因此,解决方案步骤如下:

    • 从每个流(2个和5个)中获取两个数字1
    • 比较
    • 返回最小值
    • 从先前返回的最小值的流中获取下一个数字
    就这样!;)


    PS:合并排序的复杂性总是
    O(n*log(n))

    这实际上是一个非常有趣的问题,特别是如果您不希望这是n^2或nlog复杂性

    我要做的是:

    • 定义包含2个值(i和j)和公式结果的数据结构
    • 定义包含此数据结构的集合(例如std::vector)
    • 使用值(0,0)初始化集合(本例中的结果为1)
    • 现在在循环中执行以下操作:
      • 查看集合,并以值最小的实例为例
      • 将其从集合中删除
      • 把这个打印出来
      • 基于刚刚处理的实例创建2个新实例
        • 首先是增量i
        • 在第二个实例中,增量j
      • 将这两个实例添加到集合中(如果它们还不在集合中)
    • 循环直到你受够为止
    通过选择正确的数据结构和集合,可以轻松调整性能。 例如,在C++中,可以使用一个STD::MAP,其中密钥是公式的结果,值是对(I,J)。获取最小值就是获取映射(*map.begin())中的第一个实例

    我很快编写了以下应用程序来说明它(它可以工作,但不包含进一步的注释,对不起):

    #包括
    #包括
    #包括
    typedef__int64整数;
    typedef std::pair MyPair;
    typedef std::map MyMap;
    整数结果(常量MyPair和MyPair)
    {
    返回功率((双)2,(双)我的对。第一个)*功率((双)5,(双)我的对。第二个);
    }
    int main()
    {
    我的地图;
    mypairfirstvalue(0,0);
    myMap[结果(firstValue)]=firstValue;
    while(true)
    {
    auto it=myMap.begin();
    如果(it->first<0)中断;//溢出
    MyPair MyPair=it->second;
    首先,这个问题很模糊

    尽管如此,我还是要根据您的模糊等式和模式作为您的预期结果进行一次尝试。因此,我不确定以下内容是否适用于您正在尝试的操作,但它可能会让您对java集合有一些了解

    import java.util.List;
    import java.util.ArrayList;
    import java.util.SortedSet;
    import java.util.TreeSet;
    
    
    public class IncreasingNumbers {
    
        private static List<Integer> findIncreasingNumbers(int maxIteration) {
            SortedSet<Integer> numbers = new TreeSet<Integer>();
            SortedSet<Integer> numbers2 = new TreeSet<Integer>();
    
            for (int i=0;i < maxIteration;i++) {
                int n1 = (int)Math.pow(2, i);
                numbers.add(n1);
    
                for (int j=0;j < maxIteration;j++) {
                    int n2 = (int)Math.pow(5, i);
                    numbers.add(n2);
    
                    for (Integer n: numbers) {
                        int n3 = n*n1;
                        numbers2.add(n3);
                    }
                }
            }
    
            numbers.addAll(numbers2);
    
            return new ArrayList<Integer>(numbers);
        }
    
        /**
         * Based on the following fuzzy question @ StackOverflow
         * http://stackoverflow.com/questions/7571934/printing-numbers-of-the-form-2i-5j-in-increasing-order
         * 
         * 
         * Result:
         * 1 2 4 5 8 10 16 20 25 32 40 64 80 100 125 128 200 256 400 625 1000 2000 10000 
         */
        public static void main(String[] args) {
            List<Integer> numbers = findIncreasingNumbers(5);
    
            for (Integer i: numbers) {
                System.out.print(i + " ");
            }
        }
    }
    
    import java.util.List;
    导入java.util.ArrayList;
    导入java.util.SortedSet;
    导入java.util.TreeSet;
    公共类递增数{
    私有静态列表FindInCreasingNumber(int maxIteration){
    SortedSet编号=新树集();
    SortedSet numbers2=新树集();
    对于(int i=0;i
    这非常适合函数式编程风格。在F#中:

    类似的事情可以在任何允许递归和将函数作为值传递的语言中完成(如果不能将函数作为变量传递,则只会稍微复杂一些)。

    如果可以在O(nlogn)中完成,下面是一个简单的解决方案:

    Get an empty min-heap
    Put 1 in the heap
    while (you want to continue)
        Get num from heap
        print num
        put num*2 and num*5 in the heap
    
    就是这样。对于最小堆,我的意思是,对于O(N)解,可以使用到目前为止找到的数字列表和两个索引:一个表示要乘以2的下一个数字,另一个表示要乘以5的下一个数字。然后在每次迭代中,有两个候选值可供选择较小的一个

    在Python中:

     numbers = [1]
     next_2 = 0
     next_5 = 0
    
     for i in xrange(100):
         mult_2 = numbers[next_2]*2
         mult_5 = numbers[next_5]*5
    
         if mult_2 < mult_5:
            next = mult_2
            next_2 += 1
         else:
            next = mult_5
            next_5 += 1
    
         # The comparison here is to avoid appending duplicates
         if next > numbers[-1]:
            numbers.append(next)
    
     print numbers
    
    number=[1]
    下一个_2=0
    下一个_5=0
    对于X范围内的i(100):
    mult_2=数字[下一个_2]*2
    mult_5=数字[下一个_5]*5
    如果mult_2数字[-1]:
    数字。追加(下一步)
    打印号码
    
    作为一名数学家,当我看到这样的事情时,我总是首先想到的是“对数有帮助吗?”

    在这种情况下,可能是这样

    如果我们的系列A在增加,那么系列日志(A)也在增加。由于A的所有项的形式为2^i.5^j,那么系列日志(A)的所有成员的形式为i.log(2)+j.log(5)

    然后我们可以查看系列日志(A)/log(2),其中
    let rec PrintAll(s:stream)=
        if (s.current > 0) then
            do System.Console.WriteLine(s.current)
            PrintAll(s.next());;
    
    PrintAll(Results);
    
    let v = System.Console.ReadLine();
    
    Get an empty min-heap
    Put 1 in the heap
    while (you want to continue)
        Get num from heap
        print num
        put num*2 and num*5 in the heap
    
     numbers = [1]
     next_2 = 0
     next_5 = 0
    
     for i in xrange(100):
         mult_2 = numbers[next_2]*2
         mult_5 = numbers[next_5]*5
    
         if mult_2 < mult_5:
            next = mult_2
            next_2 += 1
         else:
            next = mult_5
            next_5 += 1
    
         # The comparison here is to avoid appending duplicates
         if next > numbers[-1]:
            numbers.append(next)
    
     print numbers
    
    void Main()
    {
        double C = Math.Log(5)/Math.Log(2);
        int i = 0;
        int j = 0;
        int maxi = i;
        int maxj = j;
    
        List<int> outputList = new List<int>();
        List<Transform> transforms = new List<Transform>();
        outputList.Add(1);
        while (outputList.Count<500)
        {
        Transform tr;
            if (i==maxi)
            {
                //We haven't considered i this big before. Lets see if we can find an efficient transform by getting this many i and taking away some j.
                maxi++;
                tr = new Transform(maxi, (int)(-(maxi-maxi%C)/C), maxi%C);
                AddIfWorthwhile(transforms, tr);
            }
            if (j==maxj)
            {
                //We haven't considered j this big before. Lets see if we can find an efficient transform by getting this many j and taking away some i.
                maxj++;
                tr = new Transform((int)(-(maxj*C)), maxj, (maxj*C)%1);
                AddIfWorthwhile(transforms, tr);
            }
            //We have a set of transforms. We first find ones that are valid then order them by score and take the first (smallest) one.
            Transform bestTransform = transforms.Where(x=>x.I>=-i && x.J >=-j).OrderBy(x=>x.Score).First();
            //Apply transform
            i+=bestTransform.I;
            j+=bestTransform.J;
            //output the next number in out list.
            int value = GetValue(i,j);
            //This line just gets it to stop when it overflows. I would have expected an exception but maybe LinqPad does magic with them?
            if (value<0) break;
            outputList.Add(value);
        }
        outputList.Dump();
    
    }
    
    public int GetValue(int i, int j)
    {
        return (int)(Math.Pow(2,i)*Math.Pow(5,j));
    }
    
    public void AddIfWorthwhile(List<Transform> list, Transform tr)
    {
        if (list.Where(x=>(x.Score<tr.Score && x.IncreaseI == tr.IncreaseI)).Count()==0)
        {
            list.Add(tr);
        }
    }
    
    // Define other methods and classes here
        public class Transform
        {
            public int I;
            public int J;
            public double Score;
            public bool IncreaseI
            {
                get {return I>0;}
            }
    
            public Transform(int i, int j, double score)
            {
                I=i;
                J=j;
                Score=score;
            }
        }
    
    x x x x x @
    x x x @
    x x x 
    x @
    @
    
    mu = [1,0,0,...,0];
    while (/* some terminate condition or go on forever */) {
        minNext = 0;
        nextCell = [];
        // look through all addable cells
        for (int i=0; i<mu.length; ++i) {
            if (i==0 or mu[i-1]>mu[i]) {
                // check for new minimum value
                if (minNext == 0 or 2^i * 5^(mu[i]+1) < minNext) {
                    nextCell = i;
                    minNext = 2^i * 5^(mu[i]+1)
                }
            }
        }
        // print next largest entry and update mu
        print(minNext);
        mu[i]++;
    }
    
    1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50
    
    1  2  3  5  7 10
    4  6  8  11 
    9  12
    
    1, 2, 4, 8, 16, 32...
    
    5, 10, 20, 40, 80, 160...
    
    25, 50, 100, 200, 400...
    
     void print(int N)
      {
         int arr[N];
         arr[0] = 1;
         int i = 0, j = 0, k = 1;
         int numJ, numI;
         int num;
           for(int count = 1; count < N; )
            {
              numI = arr[i] * 2;
              numJ = arr[j] * 5;
    
                if(numI < numJ)
                 {
                   num = numI;
                   i++;
                 }
    
               else
                {
                  num = numJ;
                  j++;
                }
    
                if(num > arr[k-1])
                {
                 arr[k] = num;
                 k++;
                 count++;
                }
    
           }
    
         for(int counter = 0; counter < N; counter++)
         {
          printf("%d ", arr[counter]);
         }
    }
    
    class Program
    {
    static void Main(string[] args)
    {
        var startTime = DateTime.Now;
    
        int potential = 0;
    
        do
        {
            if (ExistsIandJ(potential))
                Console.WriteLine("{0}", potential);
                potential++;
        } while (potential < 100000);
    
        Console.WriteLine("Took {0} seconds", DateTime.Now.Subtract(startTime).TotalSeconds);
    
    }
    
    private static bool ExistsIandJ(int potential)
    {
        // potential = (2^i)*(5^j)
        // 1 = (2^i)*(5^j)/potential
        // 1/(2^1) = (5^j)/potential or (2^i) = potential / (5^j)
        // i = log2 (potential / (5^j))
    
        for (var j = 0; Math.Pow(5,j) <= potential; j++)
        {
            var i = Math.Log(potential / Math.Pow(5, j), 2);
            if (i == Math.Truncate(i))
                return true;
        }
        return false;
    }
    }