1.穷举法<写于2004.9.28>(注:接...(一))
我给它下的定义就是将所有一定范围内得出结果值列出来,进行分析;最终得到我们需要的结果值. 例如:打印出四张扑克牌相加等于24的所有可能出现的集合. 分析:我们知道扑克牌为数字珠是1到9;只有4张牌;我们很快就知道它们之间组合就有9*9*9*9=6561种组合,我们可以利用FOR循环语句来实现.然后再用IF判断语句在6561种组合中逐一进行分析得出我们最终想要的结果值. 最后用编码实现如下: #include<stdio.h> {int ri=0,i,j,k,m; for(i=1;i<=9;i++) for(j=1;j<=9;j++) for(k=1;k<=9;k++) for(m=1;m<=9;m++) if(i+j+k+m==24) {++ri; printf("%d %d %d %d",i,j,k,m);} printf("总共有%d种组合",ri);}
2.辅助法<2004.9.28> 我给它下的定义是:为了实现某一特定的问题.常常需要增加一些看似无用却又必须增加的量来进行辅助;以最终得到想要的结果值.这种方法,就称为"辅助法". 例如:打印下列有规律的分数序列. 2/1,3/2,5/3,8/5.....
分析:细心的网友可能发现了该数列有一个比较明显的规律.后一个数的分母是前一个数的分子,而后一个数的分子是前一个数的分子与分母之和.刚开始,我看到这个题目的时候,我想利用"子函数"的方式来实现.但后来用伪代码进行分析,发现其实不需要那么麻烦。只需要在其中设制一个“辅助”的变量就可以了。我用trubo C编制的源代码如下: #include<stdio.h> main() {int i=1,j=1,k,m=2,n; printf("您想看到几个:"); scanf("%d",&n); for(k=1;k<=n;k++) {printf("%d/%d",m,j); i=m; m=m+j; j=i;} 大家可以对这个源程序直观的分析一下,会看出变量"i"的值好像是多余的;但是如果去掉它却是万万不可。可以说这道题如果不用一个辅助变量就很难实现。 假设一下,如果我们把其变量的值不要,改为: ....... m=m+j; j=m; ....... 那么,很显然是不对的,虽然,我们的想法是第二个分数的分母等于第一个分数的分子加分母;但是第二句"j=m;".本来,我们想得到的值是前一个分子的值.但是,m的值这时已经被重新定义了.所以,这样做个是完全错误的.(未完待续三)
---------------------------------------------------
个人主页:wwweye.126.com
QQ:4360538
---------------------------------------------------
[此贴子已经被作者于2004-10-05 22:50:18编辑过]
----------------解决方案--------------------------------------------------------
终于看见有人讨论算法了。
楼主的说的算法还不够完整,帮忙补充一下:
回朔法:一般的一些需要高效搜索问题都用回朔而不是穷举,
举比较经典的八皇后问题:
穷举法:穷举出每一种可能,因为每行的皇后都有八种摆放可能,那穷举的复杂度就有8^8;
但其实很多摆放都是没有必要的,回朔法和穷举的区别在于回朔在过程中判断,而穷举在举出结果后判断。
回朔法:每当我摆下一个棋子就来判断一下这种摆放是不是回被前面摆好的皇后吃掉,这样就避免了很多不必要的
列举,大大提高了效率(回朔法一般是用递归实现,如果能用递推实现,那是再好不过了)
----------------解决方案--------------------------------------------------------
再给一个:
分治法:把一个大的问题分成若干个子问题来解决,其实就是递归的思想。
看这个问题:给你任意的N位数密码,不同的密码有及种可能,
不要笑,我知道你马上可以得出答案10^N;
但这个答案的得出过程就是用分治递归得思想,我第一位数有0――9,10种可能,
那所有得可能就变成了9*(剩下N-1位密码的可能)
问题变成了一个子问题――(剩下N-1位密码的可能)
当然别指望真正的问题回那么简单,但如果你找到了一个问题和子问题的联系,你离程序就不远了。
----------------解决方案--------------------------------------------------------
需要提一下的就是数学,
其实数学和编程联系很密切,如果你能找出问题的数学规律,那你的的算法是最高效的:
给个例题,大家思考一下:
在包含N个数的数列:1,2,3,4,5,……,N中每个数的前面加上+或-,组成一个算式,
输入N,求算式的最小值
再看这个题目,打印出N^N最左边的那个数
----------------解决方案--------------------------------------------------------
排序也是一个比较重要的思想,
看这个:输入一组数,求每个数N范围内素数的个数,
输出一组数,打印出的每个数对应上面每个数的结果;
如果我们已经写好了函数A(N)它的功能是返回N以内的素数的个数,
那对于每个值,我们都要调用A(N);
但这种A(N)的调用是很浪费的,比如你已经调用了A(3),对于A(4)完全只要判断4是不是素数,但事实确不是这样,如果输入5 4 1,4建立在5的基础上是比较困难的
只要对输入的数排序就可以解决这种问题,排序保证了后面的数都可以在前面的基础上稍加扩展。从而提高效率
----------------解决方案--------------------------------------------------------
谢谢网友提供的一些我以前未听说过的提高编程效率的算法。我现在正在阅读中!
----------------解决方案--------------------------------------------------------
我看了一下,好象楼主的关于扑克牌的问题不太对,扑克牌问题是用+、-、×、÷四种方法实现的吧
----------------解决方案--------------------------------------------------------
我的举的题是“打印出四张扑克牌相加等于24的所有可能出现的集合.”
----------------解决方案--------------------------------------------------------
那如果想要实现扑克牌的呢,给个思想吧,呵,还有,扑克牌也包括J,Q.,K三根哎,代码自己编,给个系统的算法就行了
----------------解决方案--------------------------------------------------------
看了感触颇深。。太有用了
----------------解决方案--------------------------------------------------------