Как сравнить значения из одного SortedDictionary, чтобы добавить их в новый SortedDictionary? - PullRequest
2 голосов
/ 20 апреля 2019

У меня есть 2 SortedDictionary "mainsd" && "valuesd".Условия, которые я пытаюсь запрограммировать, говорят следующее:

Если , то сумма значений двух ключей над MaxValue в "mainsd" больше или равнасумма значений 2-х ключей ниже MaxValue в "mainsd"

Затем : добавьте 2 пары KeyValuePair выше MaxValue в "valuesd"

Else : добавьте 2 пары KeyValuePar ниже MaxValue к «valuesd»

Продолжайте добавлять, пока valuesd.Values.Sum () не достигнет 50% от значения mainsd.Values.Sum ()

Другими словами, сравните 2 значения выше и ниже максимального, в зависимости от того, что больше, добавьте к valuesd и расширяйте, пока мы не достигнем 50% от общего значения mainsd.

"mainsd" contains the following
{
   Key , Value
500.10 , 500
500.09 , 1000
500.08 , 2000
500.07 , 3000
500.06 , 4500 --------> Step 6: 4500+5500 > 5000+4000 (Add 500.05 & 500.06 to "valuesd")
500.05 , 5500
500.04 , 6000 --------> Step 5: 6000+7000 > 5000+4000 (Add 500.03 & 500.04 to "valuesd")
500.03 , 7000
500.02 , 8500 --------> Step 2: 8500+9500 > 9000+8000 (Add 500.01&500.02 to "valuesd")
500.01 , 9500
500.00 , 10000 -------> Step 1: Max Value (Add to "valuesd") 
499.99 , 9000
499.98 , 8000 --------> Step 3: 9000+8000 > 7000+6000 (Add 499.99 & 499.98 to "valuesd")
499.97 , 7500
499.96 , 6500 --------> Step 4: 6500+7500 > 6000+7000 (Add 499.97 & 499.96 to "valuesd")
499.95 , 5000
499.94 , 4000--------> Step 7: 4000+3500 > 3000+2000 (Add 499.94 & 499.95 to "valuesd")
499.93 , 3500
499.92 , 2500
499.91 , 1500
499.90 , 550
}
Keep going until 50% is reached.

Вот то, что я получил, но он не производитожидаемые результаты.

mainsd = new SortedDictionary<double,int>(); 
valuesd = new SortedDictionary<double,int>();

if (!valuesd.ContainsKey(mainsd.Values.Max()))
{
 valuesd.Clear();
 valuesd.Add(mainsd.FirstOrDefault(x => x.Value == (mainsd.Values.Max()).Key),(mainsd.Values.Max()))
}

var vhi = valuesd.Keys.First();
var vlo = valuesd.Keys.Last();
double u1 = vhi+0.01;
double u2 = vhi+0.02;
double d1 = vlo+0.01;
double d2 = vlo+0.02;

if (mainsd.ContainsKey(u1) && mainsd.ContainsKey(u2))
{
 int up1 = mainsd[u1];
 int up2 = mainsd[u2];
}
if (mainsd.ContainsKey(d1) && mainsd.ContainsKey(d2))
{
 int dn1 = mainsd[d1];
 int dn2 = mainsd[d2];
}

if (valuesd.Values.Sum()/mainsd.Values.Sum() < 0.5)
{
 if (up1+up2>=dn1+dn2 && !valuesd.ContainsKey(u1) && !valuesd.ContainsKey(u2))
 {
  valuesd.Add(u1,up1);
  valuesd.Add(u2,up2);
 }
 else if (up1+up2<dn1+dn2 && !valuesd.ContainsKey(l1) && !valuesd.ContainsKey(l2))
 {
  valuesd.Add(d1,dn1);
  valuesd.Add(d2,dn2);
 }
}
Print("Hi="+valuesd.Keys.First()+"Lo="+valuesd.Keys.Last());

Если значение MAX было 500.

Выход: Hi = 500,01 Lo = 499,99

Любая помощь очень ценится.

1 Ответ

1 голос
/ 21 апреля 2019

Вот неполная попытка использования LINQ для получения двух последовательностей: одна для перечисления вперед (начиная с максимального элемента) и одна для перечисления назад.После этой точки нелегко продолжить работу с LINQ, поскольку две последовательности должны быть пронумерованы параллельно сложным образом, поэтому я пошел с циклом while.

var mainsd = new SortedDictionary<double, int>()
{
    {500.10, 500}, {500.09, 1000}, {500.08, 2000}, {500.07, 3000},
    {500.06, 4500}, {500.05, 5500}, {500.04, 6000}, {500.03, 7000},
    {500.02, 8500}, {500.01, 9500}, {500.00, 10000}, {499.99, 9000},
    {499.98, 8000}, {499.97, 7500}, {499.96, 6500}, {499.95, 5000},
    {499.94, 4000}, {499.93, 3500}, {499.92, 2500}, {499.91, 1500},
    {499.90, 550},
};
var maxValue = mainsd.Max(e => e.Value);
var maxItemKey = mainsd.First(e => e.Value == maxValue).Key;
var forward = mainsd.SkipWhile(e => e.Key <= maxItemKey).ToArray();
var backward = mainsd.TakeWhile(e => e.Key < maxItemKey).Reverse().ToArray();
int i1 = 0;
int i2 = 0;
while (true)
{
    var sum1 = i1 < forward.Length - 1 ? forward[i1].Value + forward[i1 + 1].Value : 0;
    var sum2 = i2 < backward.Length - 1 ? backward[i2].Value + backward[i2 + 1].Value : 0;
    if (sum1 == 0 && sum2 == 0) break;
    if (sum1 >= sum2)
    {
        Console.WriteLine($"Forward:  {sum1}, Keys: {forward[i1].Key}, {forward[i1 + 1].Key}");
        i1 += 2;
    }
    else
    {
        Console.WriteLine($"Backward: {sum2}, Keys: {backward[i2 + 1].Key}, {backward[i2].Key}");
        i2 += 2;
    }
}

Вывод:

Forward:  18000, Keys: 500,01, 500,02
Backward: 17000, Keys: 499,98, 499,99
Backward: 14000, Keys: 499,96, 499,97
Forward:  13000, Keys: 500,03, 500,04
Forward:  10000, Keys: 500,05, 500,06
Backward: 9000, Keys: 499,94, 499,95
Backward: 6000, Keys: 499,92, 499,93
Forward:  5000, Keys: 500,07, 500,08
Backward: 2050, Keys: 499,9, 499,91
Forward:  1500, Keys: 500,09, 500,1

Обновление: Вот что не хватает для завершения программы.Перед входом в цикл while мы создаем словарь valuesd:

var valuesd = new SortedDictionary<double, int>();

Внутри цикла while есть два случая.Если sum1 >= sum2 мы добавим две записи из списка пересылки:

valuesd.Add(forward[i1].Key, forward[i1].Value);
valuesd.Add(forward[i1 + 1].Key, forward[i1 + 1].Value);

В противном случае (else) мы добавим две записи из списка пересылки:

valuesd.Add(backward[i2].Key, backward[i2].Value);
valuesd.Add(backward[i2 + 1].Key, backward[i2 + 1].Value);

В концецикл while мы проверяем, достигли ли мы цели 50%.Если мы это сделаем, пришло время выйти из цикла, вызвав break.

if (valuesd.Values.Sum() >= mainsd.Values.Sum() * 50 / 100) break;

После выхода из цикла словарь valuesd заполняется необходимыми записями.

...