我获得100美元,并告诉我必须按顺序对其进行以下操作:
添加97
添加5
乘以3%的复合利息
基本上,它变为(100 + 97 + 5)* 1.3 = 208.06
现在这就是我的问题,我知道要从208.06回到100,我必须这样做:
208.06 / 1.3 - (97 + 5)= 100
上面是一个简单的例子,但是一旦我开始混合化合物,非复合,平量,并且不仅能够添加,而且减去这些值,它变得非常复杂。例如,如果我再次获得100美元,并告诉我必须按顺序应用以下调整,我不知道如何扭转它:
1)加入化合物3%
2)加入化合物4%
3)减去90
4)减3
5)加入3%的非化合物
6)加入4%的非化合物
上述计算如下:
((100 *(1.03)*(1.04)) - 90 - 3)*(1 + 0.04 + 0.03)
对于上述情况,我不知道如何通过了解后期调整后的值以及添加的6项调整来实现逆转。
上面的公式可以简化为,这样可以更容易地看到如何反转它:
(100 * 1.03 * (1.04)) - 93 + 7 = 21.21 and to reverse it, we just do:
(100 * 1.03 * (1.04)) - 93 + 7 = 100
我的问题是如何循环并以正确的顺序应用操作。我是否必须将操作顺序及其金额存储在一个类中,然后通过每次计算进行预测?
我已经在Math.StackExchange.com上发布了这个,但他们认为它是一个很大的公式,并且从编程的角度来看,我不需要理解,我需要遍历每个调整并将其从总计中删除。这基本上是我坚持的,但我不清楚如何通过循环每个调整来解决它,因为重要的是我以正确的顺序应用调整。我并不是在寻找一个解决方案,但更多的是朝着正确的方向发展。
这是一个实现。应用它似乎适用于初始样本,但如果我做我的另一个,它似乎不起作用,除非我做错了什么:
void Main()
{
var ops = new List<Operation>
{
new CompoundInterest(3.0m),
new CompoundInterest(4.0m),
new Subtract(90.0m),
new Subtract(3.0m),
new NoncompoundInterest(3.0m),
new NoncompoundInterest(4.0m)
};
var applied = ops.Aggregate(100m, (acc, o) => o.Apply(acc));
var unapplied = ops.Reverse().Aggregate(applied, (acc, o) => o.Unapply(acc));
}
// Define other methods and classes here
abstract class Operation
{
public abstract decimal Apply(decimal value);
public abstract decimal Unapply(decimal value);
}
class CompoundInterest : Operation
{
public decimal percent {get;set;}
public CompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (1m + percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (1m + percent/100m);
}
}
class NoncompoundInterest : Operation {
public decimal percent {get;set;}
public NoncompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (percent/100m);
}
}
class Add : Operation {
public decimal amount {get;set;}
public Add(decimal amount)
{
this.amount = amount;
}
public override decimal Apply(decimal value)
{
return value + amount;
}
public override decimal Unapply(decimal value)
{
return value - amount;
}
}
class Subtract : Operation {
public decimal amount {get;set;}
public Subtract(decimal amount)
{
this.amount = amount;
}
public override decimal Apply(decimal value)
{
return value - amount;
}
public override decimal Unapply(decimal value)
{
return value + amount;
}
}
答案 0 :(得分:1)
考虑到这一点的一种方法是作为操作列表,每个操作还提供了如何撤消自身的详细信息。大致...
abstract class Operation
{
public abstract decimal Apply(decimal value);
public abstract decimal Unapply(decimal value);
}
class CompoundInterest : Operation
{
public CompoundInterest(decimal percent)
{
this.percent = percent;
}
public override decimal Apply(decimal value)
{
return value * (1m + percent/100m);
}
public override decimal Unapply(decimal value)
{
return value / (1m + percent/100m);
}
}
class NoncompoundInterest : Operation { ... }
class Add : Operation { ... }
class Subtract : Operation { ... }
现在,您可以在列表中表示您的操作链:
var ops = new List<Operation>
{
new Add(97m),
new Add(5m),
new CompoundInterest(3.0m),
};
var applied = ops.Aggregate(100m, (acc, o) => o.Apply(acc));
var unapplied = ops.Reverse().Aggregate(208.06m, (acc, o) => o.Unapply(acc));
更新: Aggregate()
的工作原理如下:
decimal acc = 100m;
foreach(Operation o in ops)
acc = o.Apply(acc);
decimal applied = acc;
(acc, o) => o.Apply(acc)
是一个lambda表达式,表示在给定当前“累加器”(o.Apply(acc)
)和序列中的当前项(acc
)的情况下返回o
的函数。 “种子”值(100m)用作第一个acc
,然后函数的返回值将作为acc
传递给下一个o
,依此类推。