【发布时间】:2023-03-19 06:14:01
【问题描述】:
我遇到了计数问题,这是this 问题的延续。我不是一个真正的数学人,所以我很难弄清楚这个建议为解决方案的subset sum problem。
我有 4 个ArrayList 来保存数据:alId、alTransaction、alNumber、alPrice
类型 |交易 |号码 |价格
8 |购买 | 95.00000000 | 305.00000000
8 |购买 | 126.00000000 | 305.00000000
8 |购买 | 93.00000000 | 306.00000000
8 |转出 | 221.00000000 | 305.00000000
8 |转入 | 221.00000000 | 305.00000000
8 |出售 | 93.00000000 | 360.00000000
8 |出售 | 95.00000000 | 360.00000000
8 |出售 | 126.00000000 | 360.00000000
8 |购买 | 276.00000000 | 380.00000000
最后,我试图将剩下的内容留给客户,并将剩下的内容放入 3 个数组列表中:
- alNewHowMuch(对应于 alNumber),
- alNewPrice(对应于 alPrice),
- alNewInID(对应于 alID)
ArrayList alNewHowMuch = new ArrayList();
ArrayList alNewPrice = new ArrayList();
ArrayList alNewInID = new ArrayList();
for (int i = 0; i < alTransaction.Count; i++) {
string transaction = (string) alTransaction[i];
string id = (string) alID[i];
decimal price = (decimal) alPrice[i];
decimal number = (decimal) alNumber[i];
switch (transaction) {
case "Transfer out":
case "Sell":
int index = alNewHowMuch.IndexOf(number);
if (index != -1) {
alNewHowMuch.RemoveAt(index);
alNewPrice.RemoveAt(index);
alNewInID.RemoveAt(index);
} else {
ArrayList alTemp = new ArrayList();
decimal sum = 0;
for (int j = 0; j < alNewHowMuch.Count; j ++) {
string tempid = (string) alNewInID[j];
decimal tempPrice = (decimal) alNewPrice[j];
decimal tempNumbers = (decimal) alNewHowMuch[j];
if (id == tempid && tempPrice == price) {
alTemp.Add(j);
sum = sum + tempNumbers;
}
}
if (sum == number) {
for (int j = alTemp.Count - 1; j >= 0; j --) {
int tempIndex = (int) alTemp[j];
alNewHowMuch.RemoveAt(tempIndex);
alNewPrice.RemoveAt(tempIndex);
alNewInID.RemoveAt(tempIndex);
}
}
}
break;
case "Transfer In":
case "Buy":
alNewHowMuch.Add(number);
alNewPrice.Add(price);
alNewInID.Add(id);
break;
}
}
基本上,我根据事务类型、事务 ID 和编号从数组中添加和删除内容。我正在向 ArrayList 添加数字,例如 156、340(当它是 TransferIn 或 Buy 时)等,然后我删除它们像 156、340(当它是 TransferOut、Sell 时)一样。我的解决方案可以毫无问题地解决这个问题。我遇到的问题是,对于一些旧数据,员工输入的总和是 1500 而不是 500+400+100+500。我将如何更改它,以便当有 Sell/TransferOut 或 Buy/Transfer In 并且 ArrayList 内部没有匹配项时,它应该尝试从 thatArrayList 添加多个项目并找到组合成聚合的元素。
在我的代码中,我尝试在没有匹配项时通过简单的求和所有内容来解决这个问题(索引 == 1)
int index = alNewHowMuch.IndexOf(number);
if (index != -1) {
alNewHowMuch.RemoveAt(index);
alNewPrice.RemoveAt(index);
alNewInID.RemoveAt(index);
} else {
ArrayList alTemp = new ArrayList();
decimal sum = 0;
for (int j = 0; j < alNewHowMuch.Count; j ++) {
string tempid = (string) alNewInID[j];
decimal tempPrice = (decimal) alNewPrice[j];
decimal tempNumbers = (decimal) alNewHowMuch[j];
if (id == tempid && tempPrice == price) {
alTemp.Add(j);
sum = sum + tempNumbers;
}
}
if (sum == number) {
for (int j = alTemp.Count - 1; j >= 0; j --) {
int tempIndex = (int) alTemp[j];
alNewHowMuch.RemoveAt(tempIndex);
alNewPrice.RemoveAt(tempIndex);
alNewInID.RemoveAt(tempIndex);
}
}
}
但它只有在满足某些条件时才有效,其余的则失败。
编辑:由于你们中的一些人对我的波兰变量名称感到非常惊讶(和蒙蔽),为了简单和可见,我将它们全部翻译成英文。希望这能帮助我获得一些帮助:-)
【问题讨论】:
-
您选择的标识符令人难以置信......
-
switch 使用不当,两个 if 就足够了..
-
@Joren:波兰语可能更有意义。
-
@Srinivas -> 我已经剪掉了这个开关的其他部分以使其更容易。在这个 switch 中有 6 个案例,其中 3 个我已经删除以简化问题。
-
@Joren, Mark -> 是的,它在波兰语中更有意义,我也将一些变量翻译成英语(更难的变量,如购买然后“Papiery wartościowe - Kupno”)也以简化事情。我一个人编写这个代码,它特定于波兰文化,所以用英语保留标识符是没有意义的。
标签: c# sql-server algorithm .net-3.5