C#货币排列

C#货币排列,c#,.net,arrays,permutation,currency,C#,.net,Arrays,Permutation,Currency,只是想让大家知道,这是我第一次在堆栈溢出方面寻求帮助。我通常搜索网站,找到满意的答案,或者在MSDN或其他网站上进一步挖掘。但这一次,我真的被卡住了 我从一位招聘人员那里收到一个编程问题,我必须完成这个问题,然后提交给客户,看他们是否愿意给我打电话。这是一个挑战:对于任何给定的值,确定所述值可以用面额$100、$50、$20、$10、$5、$1、.25、.10、.05、.01表示的方式的数量 在我14年的编程生涯中,我从未学过三角函数或微积分,也从未遇到过如此复杂的数学问题。他们希望答案是C#,

只是想让大家知道,这是我第一次在堆栈溢出方面寻求帮助。我通常搜索网站,找到满意的答案,或者在MSDN或其他网站上进一步挖掘。但这一次,我真的被卡住了

我从一位招聘人员那里收到一个编程问题,我必须完成这个问题,然后提交给客户,看他们是否愿意给我打电话。这是一个挑战:对于任何给定的值,确定所述值可以用面额$100、$50、$20、$10、$5、$1、.25、.10、.05、.01表示的方式的数量

在我14年的编程生涯中,我从未学过三角函数或微积分,也从未遇到过如此复杂的数学问题。他们希望答案是C#,因为这是微软的.NET商店

招聘人员给了我另一个候选人提交的代码。这个人一定是一位才华横溢的数学美术师,因为她真正编写了整个算法,以达到预期的结果。我把它插入了一个网页,它实际上满足了要求。问题是,我甚至不能以一种允许我自己编写实现的方式来理解它

我真的非常想要这份工作,因为这是在纽约的一家初创公司,听起来很棒。我能够回答第二个问题,因为这是一个架构/设计问题,但这个问题让我很困惑

顺便说一句,我在维基百科上查到了硬币兑换问题和背包类问题,这远远超出了我的数学能力。我连答案都看不懂,因为我不懂微积分。所以我需要一些认真的帮助

下面是她的代码,顺便说一句:

protected void Page_Load(object sender, EventArgs e)
{
    var numberToSplit = new List<int>() {123};  
    foreach (int a in numberToSplit)
    {
        Response.Write(a + "  can be split in ");
        foreach (List<double> splits in GetDenominations(a).Values)
        {
            foreach (double b in splits)
            {
                Response.Write(b + ",");
            }
            //next split
            Response.Write("<br/>");
        }      
        Response.Write("<br/>");
    }
}

public Dictionary<double, List<double>> GetDenominations(int value)
{
    var denominations = new List<double> {100, 50, 20,10,5,1,0.25,0.10,0.05,0.01};
    var AllPossibleSplits = new Dictionary<double, List<double>>();
    var hightestdenomination = 100.0;

    while (hightestdenomination != 0)
    {
        var remainingDenominations =
                denominations.Where(a => (a <= value && !AllPossibleSplits.Keys.Contains(a)));

        if (remainingDenominations.Count() > 0)
            hightestdenomination = remainingDenominations.Max();
        else
            hightestdenomination = 0;

        var splits = new List<double>(); 

        if (hightestdenomination != 0)
        {
            int valueToSplit = value;
            while (valueToSplit > 0)
            {
                foreach (double denomination in remainingDenominations.Where(a => a <= valueToSplit))
                {
                    int absoluteValue = (int) (valueToSplit/denomination);
                    valueToSplit = valueToSplit - (int) (absoluteValue*denomination);
                    int absoluteValueSplit = 0;

                    while (absoluteValueSplit < absoluteValue)
                    {
                        splits.Add(denomination);
                        absoluteValueSplit++;
                    }
                }
           }   
        }

        AllPossibleSplits[hightestdenomination] = splits;
    }

    return AllPossibleSplits;
}
受保护的无效页面加载(对象发送方,事件参数e)
{
var numberToSplit=new List(){123};
foreach(numberToSplit中的int a)
{
响应。写入(a+“可拆分为”);
foreach(列表拆分为getNominations(a).Values)
{
foreach(拆分中的双b)
{
响应。写入(b+“,”);
}
//下一次拆分
响应。写入(“
”); } 响应。写入(“
”); } } 公共字典getNominations(int值) { var面额=新列表{100,50,20,10,5,1,0.25,0.10,0.05,0.01}; var AllPossibleSplits=new Dictionary(); var Hightest面额=100.0; while(最高面值!=0) { 剩余面值= 面额。其中(a=>(a 0) hightest面额=剩余面额.Max(); 其他的 hightest面额=0; var splits=新列表(); if(最高面值!=0) { int valueToSplit=值; while(valueToSplit>0) {
foreach(剩余面额中的双面额)。其中(a=>a您可能想看看a。

虽然我觉得这是一次求职面试,您应该能够编写此代码,但我更愿意为您推动正确的方向。 这是一个经典的编程任务,需要简单的数学,我将在下面解释。 想想每种面额各有一种,在现实生活中你会如何区分它们。 首先,你会把每种面额堆起来,在这种情况下,它们对应于一个变量,即var Hundredollarnotes,var fiftyDollarNotes,或者是一个具有类似属性的对象

而你的金额不等于零。 从金额中减去100美元,并将一个变量添加到100美元变量中,重复此操作直到无法减去100美元为止。 继续降低金额,直到您没有剩余金额


这是一个装在坚果壳里的贪婪算法。

不要让问题变得更难

假设你有51枚硬币。使用你最大的钞票(50)51-50=1 然后用你最大的硬币(1)1-1=1

你在这儿

代码只需遍历整个价值列表,使用尽可能大的钞票/面额,并对剩下的任何东西执行相同的操作,直到什么都不剩。

好吧, 发布的算法只会让您浏览所有可能的排列,尝试使用值1,它给出如下答案:

  • 一,
  • 0,25,0,25,0,25,0,25,0,25
  • 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1 . .
但这只是对整个答案的一瞥,缺少的答案有 0,25 , 0,25 , 0,1 , 0,1 , 0,1 , 0,1 , 0,1 仅举一例。 实现自己的算法是一种很好的方法。 我是一名计算机科学的实习生,我可以在脑海中想出一个算法来解决这个问题,虽然不那么复杂,但很有效。 就在我前面发帖子的那个人给了我一个很好的暗示: 从最大可能的分割到最小可能的分割,计算发生的最大数量,然后继续进行较小数量的分割,直到最后得到0剩余。
要获得所有可能的解决方案,需要做更多的工作,但您提供的解决方案提供了不同最大数量的解决方案。

您可以将其视为一个树遍历问题:

在这里,您将遍历树并检查以下内容

Is the cost of the path currently lower then what I want 
 -> Go deeper in the tree

Is the cost of the path currently higher then what I want 
 -> Stop

Is the cost of the path currently the same as what I want 
 -> Permutation found
下面是一个示例:您希望获得所有可能的25美元排列,包括5美元、10美元和20美元的钞票。蓝色表示成本
为25
,红色表示成本
为25
,绿色表示成本
为25
图片免责声明:可能有一些错误,但你明白了


另外,如果你这样做,它会给出像5,5,5,10,5,5,10这样的排列,所以保留一个你已有的解决方案列表,这样你就不会得到这些倍数。此外,这棵树有一个较大的(有争议的)分支因子(10),因此,如果你得到的数字很大,有很多可能的选择。不要先创建整棵树并遍历它。它可以累加起来(我无法想象有多少可能赚到1.000.000美元)。

你不怕他们看到这篇文章吗?我当然不想帮你获得j