换零钱问题

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

你可能感兴趣的:(算法,Scheme,pascal)