C# 递归收缩数组并将其作为新参数传递

C# 递归收缩数组并将其作为新参数传递,c#,recursion,C#,Recursion,是否可以继续消除数组的元素(即在处理第一个、第二个等时缩小数组),并将其作为新参数传递给同一个函数(即递归) 我正试图想出一个简单的方法来计算顾客找零所需的每一枚硬币的数量(例如在自动售货机中),但由于我被所有使用嵌套循环等的谷歌搜索结果弄糊涂了。。。(我的意思是我发现它们很难理解)我决定看看是否可以将我的想法转化为一个简单的递归调用来解决这个问题 到目前为止,我掌握的情况如下。假设机器应该返回80美分的零钱,给出10、20、50、100和200个硬币的面额列表。一个人会想:第一枚小于80的硬币

是否可以继续消除数组的元素(即在处理第一个、第二个等时缩小数组),并将其作为新参数传递给同一个函数(即递归)

我正试图想出一个简单的方法来计算顾客找零所需的每一枚硬币的数量(例如在自动售货机中),但由于我被所有使用嵌套循环等的谷歌搜索结果弄糊涂了。。。(我的意思是我发现它们很难理解)我决定看看是否可以将我的想法转化为一个简单的递归调用来解决这个问题

到目前为止,我掌握的情况如下。假设机器应该返回80美分的零钱,给出10、20、50、100和200个硬币的面额列表。一个人会想:第一枚小于80的硬币是50美分,所以我需要一枚50美分,现在剩下的是30美分

第一个小于30的硬币是20美分,所以我需要一个20美分,现在剩下的只有10美分。第一枚硬币少于(或在本例中等于)剩下的硬币是10美分,这就完成了这个过程

因此,在每一步中,在处理了对我有帮助的最大面值的硬币之后,我“忽略”了其他太多的大硬币;i、 我正在清除对我没有帮助的无用硬币面额

现在,在对我过于简单的思维方式进行编码之后,我想到了以下几点,现在我想知道如何将这个“硬币面额数组收缩”映射到代码中?这突出显示在我放置
temp
数组的位置

我的意思是,当我出发时,我检查了2欧元硬币(200),它是
硬币[1]
,太大了。硬币[2]也是如此,1欧元。然后50美分的硬币帮助(
coins[3]
)进行排序,但现在我想对
coins[4]
coins[5]
运行相同的方法,这可以被认为是一个新的axed数组,现在只包含索引4和索引5,可以继续解决问题

这可能吗

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace CoinsConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] coins = new int[5] { 200, 100, 50, 20, 10 };

            Calculate(coins, 80); // 50 + 20 + 10

            Console.ReadLine();
        }


        static []int Calculate(int[] coins, int change)
        {
            int[] counts = new int[5] { 0, 0, 0, 0, 0 };
            int remaining;

            for (int i = 1; i <= coins.Length; i++)
            {
                if (coins[i] <= change)
                {
                    remaining = change - coins[i];
                    ++counts[i];
                    []int temp = coins.Skip(i);
                    Calculate(temp, remaining);
                }
            }

            return counts;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间协同解决方案
{
班级计划
    {
静态void Main(字符串[]参数)
        {
int[]硬币=新的int[5]{200,100,50,20,10};
计算(硬币,80);/50+20+10
Console.ReadLine();
        }
静态[]整数计算(整数[]硬币,整数变化)
        {
int[]计数=新的int[5]{0,0,0,0};
剩余整数;

(int i=1;i<p>),通过对每个递归调用提取子数组,通常这样做的方式是<强>不<强>。相反,它总是通过完全相同的数组,以及起始索引和要考虑的元素的数量来完成。< /P> 这样,您就不必从事提取子数组的繁琐工作,您的代码将执行得更好

如果您不想更改该方法的公共接口,那么让它调用一个内部(私有)方法,该方法执行所有工作(包括递归),将0作为起始索引,将array.length作为长度


如果您坚持提取子数组,则必须自己分配它,然后使用
array.Copy
将一系列元素从旧数组复制到新数组。请参见通常的方法是而不是为每次递归调用提取子数组。相反,它是通过始终传递完全相同的数组来完成的数组,以及开始索引和要考虑的元素的数量。

这样,您就不必从事提取子数组的繁琐工作,您的代码将执行得更好

如果您不想更改该方法的公共接口,那么让它调用一个内部(私有)方法,该方法执行所有工作(包括递归),将0作为起始索引,将array.length作为长度


如果您坚持提取子数组,则必须自己分配它,然后使用
array.Copy
将一系列元素从旧数组复制到新数组。请参见这并不能回答您的问题,但它可能会让您看到其他可能且更简单的方法

为什么你没有一个分类的硬币堆栈容器?考虑下面的结构:<代码>字典<代码>。这个容器将有价值(美分)分类的硬币堆栈。

硬币[10]
将为您提供一堆机器中可用的10美分硬币。
硬币[25]
将为您提供25美分硬币等

当客户添加硬币时,您只需将其放入相应的堆栈中:
coins[enteredCoin.Value].Push(enteredCoin)

这也使得为不同的货币配置自动售货机变得很容易。在启动时,在字典中注册硬币(钥匙),你将接受自动售货机并对其预充电(更新堆叠和推送硬币)

检查输入的硬币是否可以接受也很容易,只需检查该值是否是字典的有效键,如果不是,则将其返回给客户


通过这种方法,事情变得容易多了。

这并不能回答您的问题,但它可能会让您看到其他可能的更简单的方法

为什么你没有一个分类的硬币堆栈容器?考虑下面的结构:<代码>字典<代码>。这个容器将有价值(美分)分类的硬币堆栈。

硬币[10]
将为您提供一堆机器中可用的10美分硬币。
硬币[25]
将为您提供25美分硬币等

当客户添加硬币时,您只需将其放入相应的堆栈中:
c
static void CalculateChange(int change, int[] coins)
{
    Console.Write(change + " = ");

    int j = 0;
    while (change > 0)
    {
        for (int i = j; i < coins.Length; i++)
        {
            int coin = coins[i];
            if (coin <= change)
            {
                change = change - coin;
                j = i; // remmeber the position of the biggest possible coin, to start from next loop
                Console.Write(coin + " ");
                break;
            }
        }
    }
}