C#货币排列
只是想让大家知道,这是我第一次在堆栈溢出方面寻求帮助。我通常搜索网站,找到满意的答案,或者在MSDN或其他网站上进一步挖掘。但这一次,我真的被卡住了 我从一位招聘人员那里收到一个编程问题,我必须完成这个问题,然后提交给客户,看他们是否愿意给我打电话。这是一个挑战:对于任何给定的值,确定所述值可以用面额$100、$50、$20、$10、$5、$1、.25、.10、.05、.01表示的方式的数量 在我14年的编程生涯中,我从未学过三角函数或微积分,也从未遇到过如此复杂的数学问题。他们希望答案是C#,因为这是微软的.NET商店 招聘人员给了我另一个候选人提交的代码。这个人一定是一位才华横溢的数学美术师,因为她真正编写了整个算法,以达到预期的结果。我把它插入了一个网页,它实际上满足了要求。问题是,我甚至不能以一种允许我自己编写实现的方式来理解它 我真的非常想要这份工作,因为这是在纽约的一家初创公司,听起来很棒。我能够回答第二个问题,因为这是一个架构/设计问题,但这个问题让我很困惑 顺便说一句,我在维基百科上查到了硬币兑换问题和背包类问题,这远远超出了我的数学能力。我连答案都看不懂,因为我不懂微积分。所以我需要一些认真的帮助 下面是她的代码,顺便说一句:C#货币排列,c#,.net,arrays,permutation,currency,C#,.net,Arrays,Permutation,Currency,只是想让大家知道,这是我第一次在堆栈溢出方面寻求帮助。我通常搜索网站,找到满意的答案,或者在MSDN或其他网站上进一步挖掘。但这一次,我真的被卡住了 我从一位招聘人员那里收到一个编程问题,我必须完成这个问题,然后提交给客户,看他们是否愿意给我打电话。这是一个挑战:对于任何给定的值,确定所述值可以用面额$100、$50、$20、$10、$5、$1、.25、.10、.05、.01表示的方式的数量 在我14年的编程生涯中,我从未学过三角函数或微积分,也从未遇到过如此复杂的数学问题。他们希望答案是C#,
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