我正在用c#编写一段代码来检查给定剂量的片剂数量。例如,如果剂量为20毫克DrugA(如果DrugA含有10毫克,5毫克和2毫克片剂),那么代码将返回(2)。如果Dosage为15则代码将返回(1& 1)。如果剂量为3,则返回Invalid Dosage消息。代码必须首先使用最高面额,即10mg片剂,然后是剩余的5mg片剂,依此类推。我正在使用递归函数(GetDispenseBreakdownForSingleDosage)来实现上述功能。我的代码在我测试的大多数场景中运行良好。错误返回Invalid Dosage的一种情况是8mg剂量。代码应该返回(4),因为2mg平板电脑是一个有效的选项。我在下面给出了我的代码。我的问题是:
1)有没有比使用我的代码更好的方法来实现我的目标。
2)我应该做些什么改变以避免8mg的陷阱作为无效剂量。它返回它无效,因为代码在第二次递归调用期间将8除以5,余数变为3,第三次递归调用3不能被2整除,因此代码返回无效剂量。
我的代码如下:
public string GetDispenseBreakdown(PrescriptionsBLL Prescription, double[] IndexAndNonIndexDosageForBreakdown)
{
int[] NoOfTablets = new int[Prescription.SelectedDrug.PrescriptionsDrugWeights.Count];
for (int Index = 1; Index <= IndexAndNonIndexDosageForBreakdown.Length; Index++)
{
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, IndexAndNonIndexDosageForBreakdown[(Index - 1)], Prescription.SelectedDrug.PrescriptionsDrugWeights[0].Weight, 1);//assuming that index 0 will always contain the highest weight i.e. if a drug has 2, 5, 10 as drug weights then index 0 should always contain 10 as we are sorting by Desc
}
return ConvertNumberOfTabletsIntoString(NoOfTablets);
}
public void GetDispenseBreakdownForSingleDosage(PrescriptionsBLL Prescription, ref int[] NoOfTablets, double Dosage, double Weight, int WeightCount)
{
int LoopIteration;
string TempLoopIteration = (Dosage / Weight).ToString();
if (TempLoopIteration.Contains("."))
LoopIteration = (int)Math.Floor(Dosage / Weight);
else
LoopIteration = int.Parse(TempLoopIteration);
double TempDosage = Weight * LoopIteration;
int WeightTablets = LoopIteration;
double RemainingDosage = Math.Round((Dosage - TempDosage), 2);
NoOfTablets[(WeightCount - 1)] = NoOfTablets[(WeightCount - 1)] + WeightTablets;
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count && RemainingDosage > 0.0)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (LoopIteration == 0 && Dosage > 0.0 && WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
{
NoOfTablets[0] = -99999;//Invalid Dosage
return;
}
if (WeightCount == Prescription.SelectedDrug.PrescriptionsDrugWeights.Count)
return;
GetDispenseBreakdownForSingleDosage(Prescription, ref NoOfTablets, RemainingDosage, Prescription.SelectedDrug.PrescriptionsDrugWeights[WeightCount].Weight, ++WeightCount);
}
public bool IsDosageValid(int[] NoOfTablets)
{
if (NoOfTablets[0] == -99999)
return false;
else
return true;
}
public string ConvertNumberOfTabletsIntoString(int[] NoOfTablets)
{
if (!IsDosageValid(NoOfTablets))
return "Dosage is Invalid";
string DispenseBreakDown = "(";
int ItemsAdded = 0;
for (int Count = 0; Count < NoOfTablets.Length; Count++)
{
if (NoOfTablets[Count] != 0)
{
if (ItemsAdded > 0)
DispenseBreakDown += " & " + NoOfTablets[Count];
else
DispenseBreakDown += NoOfTablets[Count];
ItemsAdded = ItemsAdded + 1;
}
}
DispenseBreakDown += ")";
return DispenseBreakDown;
}
答案 0 :(得分:1)
这听起来像硬币更换所需的相同逻辑版本。
这个网站完成了这个逻辑: http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
您还需要进行一些调整:
答案 1 :(得分:0)
这是一个简单的递归方法。将所需剂量和空列表传递给它:
// Test if 2 floats are "equal", the difference between them
// is less than some predefined value (epsilon)
bool floatIsEqual(float f1, float f2)
{
float epsilon = 0.001f;
return Math.Abs(f1 - f2) <= epsilon;
}
static bool CalcDose(float desired, List<float> list)
{
// Order of array is important. Larger values will be attempted first
float[] sizes = new float[] { 8, 2, .4f, .2f };
// This path isn't working, return
if (desired < sizes[sizes.Length - 1])
{
return false;
}
// Try all combos
for (int i = 0; i < sizes.Length; i++)
{
if (floatIsEqual(desired, sizes[i]))
{
// Final step: perfect match
list.Add(sizes[i]);
return true;
}
if (sizes[i] <= desired)
{
// Attempt recursive call
if (true == CalcDose( desired - sizes[i], list))
{
// Success
list.Add(sizes[i]);
return true;
}
else break;
}
}
return false;
}