Подмножество сумм
У меня проблема со счетом, который является продолжениемэтот вопрос. Я на самом деле не математик, поэтому мне очень трудно понять этоsubset sum problem
который был предложен в качестве резолюции.
У меня 4ArrayList
в котором я храню данные: 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;
}
}
В основном я добавляю и удаляю вещи из массива в зависимости от типа транзакции, идентификатора транзакции и номеров. Я добавляю числа в ArrayList, такие как 156, 340 (когда это TransferIn или Buy) и т. Д., А затем я удаляю их, как 156, 340 (когда это TransferOut, Sell). Мое решение работает для этого без проблем. У меня проблема в том, что для некоторых старых данных сотрудники вводили сумму как 1500 вместо 500 + 400 + 100 + 500. Как бы я изменил это так, чтобы, когда естьSell/TransferOut
или жеBuy/Transfer In
и нет никакого совпадения внутри ArrayList, он должен попытаться добавить несколько элементов из этогоArrayList
и найти элементы, которые объединяются в совокупность.
Внутри своего кода я попытался решить эту проблему простым суммированием всего, когда нет совпадения (index == 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);
}
}
}
Но это работает только при соблюдении определенных условий и не работает для остальных.
Редактировать: Поскольку некоторые из вас были настолько поражены (и ослеплены) моими польскими именами переменных, я перевел их все на английский для простоты и наглядности. Надеюсь, это поможет мне получить некоторую помощь :-)