换零钱问题
关键字: 算法上个月把sicp第一章看了看,领略到scheme 语言的美妙,非常之简洁,呵呵,
1.2.2 节 是讲的树型递归,里面有个换零钱问题,属于很老问题了,问题简单的说就是 1块钱,要换成 5分,1分,10分,50分,25分,总共有几种换法。
以前我大学的时候好象是用穷举
实现的,现在发现scheme,发现递归实现也不错,然后看了算法,决定用C# 重新写以下,
从scheme 翻译到c# 非常简单,后来发现书上的例子只能得到换法的总数,不能把所有换法 的零钱数的组合输出,
比如, 假设 10分 成 5分和1分,他只能输出 有3种换法,不能把
(1 1 1 1 1 1 1 1 1 1)
(5 1 1 1 1 1)
(5 1)
using System;
namespace CountChange
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
static int[] changeArray = new int[100];
static int arrayIndex = 0;
static void InitArray()
{
for(int i = 0 ; i < 100 ; i++)
{
changeArray[i] = 0;
}
arrayIndex = 0;
}
static void PrintChange()
{
for(int i = 0 ; i < 100 ; i++)
if ( changeArray[i] != 0)
Console.Write(changeArray[i] + " ");
// Console.WriteLine();
}
static void RollBackArray()
{
int lastIndex = 0;
int lastChange;
for(int i = 0 ; i < 100 ; i++)
{
if ( changeArray[i] == 0)
{
if( i > 0)
lastIndex = i -1;
else return;
break;
}
}
lastChange = changeArray[lastIndex];
//delete all the same change
int step;
for( step = lastIndex ; step >=0 ; step--)
{
if(changeArray[step] == lastChange)
{
changeArray[step] = 0;
continue;
}
else
break;
}
//reset the arrayindex;
arrayIndex = step + 1;
}
static int CountChange(int amount ,int kindOfCoins)
{
if( amount == 0 )
{
Console.WriteLine("-----------------------------------------------");
PrintChange();
Console.WriteLine();
Console.WriteLine("-----------------------------------------------");
RollBackArray();
return 1;
}
else if(amount < 0 )
{
RollBackArray();
return 0;
}
else if( kindOfCoins == 0)
{
return 0;
}
else
{
//
int num1 = CountChange(amount ,kindOfCoins -1);
// push the change
changeArray[arrayIndex++] = FirstDenomination(kindOfCoins);
int num2 = CountChange(amount - FirstDenomination(kindOfCoins) ,kindOfCoins );
return num1 + num2 ;
}
}
static int FirstDenomination(int kindOfCoins)
{
switch (kindOfCoins)
{
case 1: return 1;
case 2: return 2;
case 3: return 3;
default:
Console.WriteLine("FirstDenomination error kindOfCoins = " + kindOfCoins);
return -1;
}
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
// init array
InitArray();
// CountChange(10 ,2);
Console.WriteLine(CountChange(10 ,3));
}
}
}
评论
理想状态下他能把迷宫的所有可能性都走遍。。。。
(不过每走一步都进行压栈。。
如果有传说中的左死墙不知道会怎么样。。。。)
他用这种方式的空间复杂度非常的大,但非常的好写
才不到十行的代码。。。。。
PS:好写不代表好想。。。。我的脑子也是非常的头痛。。。
看来普通人与大牛的区别不在于马力小时(对普通问题的思考),
(我们老师讲递归时用了走迷宫的例子。PS:我们大学没有算法课只有pascal)
- 浏览: 12130 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最新评论
-
scheme语言的可读性??
lambda (m) (m x y)换成Z就出来了的
-- by ychael -
scheme语言的可读性??
zhuyi8319 写道: 结果 12就出来,绕口吧,^_^,无聊的时 ...
-- by javaeye000 -
scheme语言的可读性??
Joard推荐的文章里的Scheme程序就很好读阿。特别是实现矩阵转置和list ...
-- by codemonkey -
换零钱问题
zhuyi8319 写道我在大学讲递归的时候,用的是 八皇后,呵呵,当时觉得很难 ...
-- by 抛出异常的爱 -
scheme语言的可读性??
是比较无语,楼主没搞清楚书中想表达什么,扯到可读性上去了。。。 丘奇数实在是天才 ...
-- by dennis_zane






评论排行榜