一个humble numbers 的算法的解答

今天,我们同事不知道从哪儿弄来一道有意思的题目,我做了觉得很有意思,而且这个算法运行速度也还过得去,个人觉得对算法的实践也相当有帮助,所以就写了以下内容来分享一下。

题目: 寻找这样一种数列,它仅仅能被2,3,5,7整除。请输出这样的数列。

问题的分析,一种是对每个数字进行遍历,这是一种很直觉的方法,从算法复杂度考虑,它耗费的时间必然是很大的。后来,我们想到问题可以转化为对2,3,5,7这些数据以及由它们组合(因式分解为2,3,5,7)的数据相乘得到。于是我按照这个想法写了以下的算法,算法中使用了有向双向队列(链表方式实现),作为数据的排序所用。

/*
the program cal 2,3,5,7
programer: jeyawn
finished date: 2008-5-21 23:30
*/
#include "stdafx.h"
#include <stdlib.h>
#include <memory.h>
#define MAX_LENGTH 4000
#define NULL ((void *)0)

typedef struct tagElem 
{
 unsigned long a;
 unsigned long b;

 struct tagElem *next;
 struct tagElem *prev;
}Elem;

Elem *pHead = (Elem *)NULL;
Elem *pEnd = (Elem *)NULL;
long Length = 0;

/*basic op of list*/
void InQue(const Elem &e, unsigned long *pData)
{
 Elem *pElem = new Elem;
 memset(pElem, 0, sizeof(Elem));
 pElem->a = e.a;
 pElem->b = e.b;
 Length++;
 if (Length == 1)
 {
  pElem->next = (Elem *)NULL;
  pElem->prev = (Elem *)NULL;
  pHead = pElem;
  pEnd = pElem;
 }
 else
 {
  Elem *pTmp = pEnd;
  while (pTmp != NULL)
  {
   if (pData[pTmp->a] * pData[pTmp->b] > pData[e.a] * pData[e.b])
   {
    pTmp = pTmp->prev;
   }
   else
    break;
  }
  if (pTmp != NULL)
  {
   pElem->next = pTmp->next;
   if(pTmp->next)
    pTmp->next->prev = pElem;
   pElem->prev = pTmp;
   pTmp->next = pElem;
  }
  else
  {
   pElem->prev = (Elem *)NULL;
   pElem->next = pHead;
   pHead->prev = pElem;
   pHead = pElem;
  }
  if (pTmp == pEnd)
  {
   pEnd->next = pElem;
   pElem->prev = pEnd;
   pElem->next = (Elem *)NULL;
   pEnd = pElem;
  }

 }
}

void OutQue()
{
 if (Length > 0)
 {
  Elem *pElem = pHead;
  pHead = pHead->next;
  delete pElem;
  if (Length == 1)
  {
   pHead = (Elem *)NULL;
   pEnd = (Elem *)NULL;
  }
  else
  {
   pHead->prev = (Elem *)NULL;
  }
  Length--;
 }
}

void PrintList(unsigned long *pData)
{
 printf("/n");
 Elem *pTmp = pHead;
 while (pTmp!=NULL)
 {
  printf("[%d, %d] = [%d, %d]$$", pTmp->a, pTmp->b, pData[pTmp->a], pData[pTmp->b]);
  pTmp = pTmp->next;
 }
 printf("/n");
}

#include <stdio.h>
void main()
{
 unsigned long *pData = new unsigned long [MAX_LENGTH]; 
 pData[0] = 2;
 pData[1] = 3;
 pData[2] = 4;
 pData[3] = 5;
 pData[4] = 6;
 pData[5] = 7;
 int Index0 = 6;
 int Index1 = 0;
 int Index2 = 2;
 int Index3 = 1;
 while (Index0 < MAX_LENGTH)
 {
  //printf("%d/n", Index0);
  //PrintList(pData);
  unsigned long result = pData[Index1] * pData[Index2];
  // compare the list head and result and next data;
  unsigned long next_data = pData[Index3] * pData[Index3];

  //
  if (result <= next_data)
  {
   if (Length > 0)
   {
    unsigned long list_head = pData[pHead->a] * pData[pHead->b];
    unsigned long list_end = pData[pEnd->a] * pData[pEnd->b];
    //
    if (next_data <= list_end)
    {
     Elem e;
     memset((Elem *)&e, 0, sizeof(Elem));
     e.a = Index3;
     e.b = Index3;
     Index3++;
     InQue(e, pData);
    }
    if (list_head > result)
    {
     if (pData[Index0 - 1] != result)
     {
      pData[Index0++] = result;
     }
     
     Index2++;
     continue;
    }
    else if (list_head == result)
    {
     if (pData[Index0 - 1] != result)
     {
      pData[Index0++] = result;
     }
     Index2++;
     continue;
    }
    else if (list_head < result)
    {
     Elem e;
     e.a = Index1;
     e.b = Index2;
     InQue(e, pData);
     
     Index1 = pHead->a;
     Index2 = pHead->b;
     OutQue();
     continue;
    }

   }
   else
   {
    if (result != pData[Index0 - 1])
    {
     pData[Index0++] = result;
    } 
    Index2++;
    continue;
   }

  }
  else
  {
   Elem e;
   memset((Elem *)&e, 0, sizeof(Elem));
   e.a = Index1;
   e.b = Index2;
   InQue(e, pData);
   if (Length > 0)
   {
    unsigned long list_head = pData[pHead->a] * pData[pHead->b];
    unsigned long list_end = pData[pEnd->a] * pData[pEnd->b];
    if (pData[Index3] * pData[Index3] <= list_head)
    {
     Index1 = Index3;
     Index2 = Index3;
     Index3++;
     continue;
    }
    if (pData[Index3] * pData[Index3] <= list_end)
    {
     memset((Elem *)&e, 0, sizeof(Elem));
     e.a = Index3;
     e.b = Index3;
     Index3++;
     InQue(e, pData);
     Index1 = pHead->a;
     Index2 = pHead->b;
     OutQue();

     continue;
    }
   }
   Index1 = Index3;
   Index2 = Index3;
   Index3++;
   continue;
  }

 }
 for (int i = 0; i < MAX_LENGTH; i++)
 {
  printf("%d ", pData[i]);
 }
 system("pause");
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值