上个月把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));
}
}
}