The art of computer programming中一道组合数学问题(附带源码)

lafanda217 2010-10-11 02:02:16
问题来自<The art of computer programming>vol1, 2.2.1节第四题。
大体意思是把N项数据经由一个fifo栈移至另外一个结构体中,问新的结构体可能的排列有多少个。难度为M36
数学解法超级变态,所以写了个程序求他的数值解。
本人笔记本电脑处理器为T550, 1.83ghz,穷举10!=3628800次使用时间为4.659s
贴出源码,希望能和同道中人交流下,欢迎算法方面的建议。

源码如下

#include "stdafx.h"
#include <time.h>
#define MAX 11
//#define PRINTALL 1
class SourceStack
{
int currentIndex;
int data[MAX];
public:
SourceStack();
int GetItem();
int PeekItem();
};
class InterStack
{
int currentIndex;
int data[MAX];
public:
InterStack();
void PutItem(int item);
int GetItem();
int PeekItem();
};
bool IsPossible(int* checkData)
{
SourceStack sk1;
InterStack ik;

bool isPossible=true;
int idx;
for (idx=0;idx<MAX;++idx)
{
if (checkData[idx]==ik.PeekItem())
{
ik.GetItem();
}
else if(checkData[idx]>ik.PeekItem())
{
if (checkData[idx]!=sk1.PeekItem())
{
do
{
ik.PutItem(sk1.GetItem());
} while (sk1.PeekItem()!=checkData[idx]);
}
sk1.GetItem();
}
else
{
isPossible=false;
break;
}
}
//printf("At %d: %s",idx,isPossible?"Possible\r\n":"Impossible\r\n");
return isPossible;
}
int GetMaxLiveNumIndex(int* checkData,bool* liveDirection)
{
int maxNum=-1;
int maxLiveNumIndex=-1;
for(int index=0;index<MAX;++index)
{
if (liveDirection[index])//Point to right
{
if (index!=MAX-1)//NOT last num
{
if (checkData[index]>checkData[index+1])
{
if (checkData[index]>maxNum)
{
maxNum=checkData[index];
maxLiveNumIndex=index;
}

}
}
}
else//Point to left
{
if (index!=0)
{
if (checkData[index]>checkData[index-1])
{
if (checkData[index]>maxNum)
{
maxNum=checkData[index];
maxLiveNumIndex=index;
}
//int x=checkData[index];
}
}
}
}
return maxLiveNumIndex;

}
int Permute(int maxLiveNumIndex,int* checkData,bool* liveDirection)
{
int temp;
int otherIndex=liveDirection[maxLiveNumIndex]?maxLiveNumIndex+1:maxLiveNumIndex-1;
temp=checkData[otherIndex];
checkData[otherIndex]=checkData[maxLiveNumIndex];
checkData[maxLiveNumIndex]=temp;

bool bltemp;
bltemp=liveDirection[otherIndex];
liveDirection[otherIndex]=liveDirection[maxLiveNumIndex];
liveDirection[maxLiveNumIndex]=bltemp;

return checkData[otherIndex];//last max live num
}
void ChangeDirection(int lastMaxLiveNum,int* checkData,bool* liveDirection)
{
for (int index=0;index<MAX;++index)
{
if (checkData[index]>lastMaxLiveNum)
{
liveDirection[index]=!liveDirection[index];
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
clock_t start, finish;
double duration;
start = clock();

int checkData[MAX];
bool liveDirection[MAX];
int index;
for (index=0;index<MAX;++index)
{
checkData[index]=index+1;
liveDirection[index]=false;
}
int maxLiveNumIndex;
int allCount=0;
int allowedCount=0;

printf("Allowed Permutaion are: \r\n");
do
{
++allCount;
if (IsPossible(checkData))
{
++allowedCount;
#ifdef PRINTALL
printf("Permutation %d:\t\t",allowedCount);

for (index=0;index<MAX;++index)
{
printf("%d\t",checkData[index]);
}
printf("\r\n");
#endif
}
maxLiveNumIndex=GetMaxLiveNumIndex(checkData,liveDirection);
if (maxLiveNumIndex!=-1)
{
int lastMaxLiveNum=Permute(maxLiveNumIndex,checkData,liveDirection);
ChangeDirection(lastMaxLiveNum,checkData,liveDirection);
}
} while (maxLiveNumIndex!=-1);

printf("All Count=%d, Allowed Permutation Count=%d\r\n",allCount,allowedCount);

finish=clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("%.3f seconds elapsed.", duration);
return 0;
}


int SourceStack::GetItem()
{
return data[currentIndex++];
}
SourceStack::SourceStack()
{
currentIndex=0;
for (int idx=0;idx<MAX;++idx)
{
data[idx]=idx+1;
}
}
int SourceStack::PeekItem()
{
return data[currentIndex];
}
InterStack::InterStack()
{
currentIndex=MAX;
for (int idx=0;idx<MAX;++idx)
{
data[idx]=-1;
}
}
int InterStack::GetItem()
{
if (currentIndex==MAX)
{
return -1;
}
else
{
return data[currentIndex++];
}
}
void InterStack::PutItem(int item)
{
data[--currentIndex]=item;
}

int InterStack::PeekItem()
{
if (currentIndex==MAX)
{
return -1;
}
else
{
return data[currentIndex];
}
}
...全文
102 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yshuise 2010-10-11
  • 打赏
  • 举报
回复
这本书很好,以后研究算法我就把这本书作为教材。
lafanda217 2010-10-11
  • 打赏
  • 举报
回复
是有公式可以算出来
只是那他来练手的。。
ps,今晚我也咖啡喝多了,悲剧
FancyMouse 2010-10-11
  • 打赏
  • 举报
回复
catalan数。干啥穷举?

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧