2016-07-25 4 views
0

Ich möchte nach Brammen Stromkosten berechnen, wie in der nachstehenden Tabelle mit C#,berechnen Slab Preise

SlabFrom SlabTo  Rate 

    0   100   5.00 
    101   500   10.00 
    501   Null  15.00 

Anzahl der Platten ändern können, benötigen eine beste Lösung Gesamtkosten
nach Gesamtverbrauch zu berechnen. Wenn Gesamtverbrauch 1000 ist, sollte es berechnen:

(100 X 5) + (400 x 10) + (500 x 15) = 12.000

public class Cost 
{ 
    public decimal SlabFrom { get; set; } 

    public decimal SlabTo { get; set; } 

    public bool SlabHour { get; set; } 

    public decimal RatePerUnit { get; set; } 
} 

     var rates = new List<Cost> 
     { 
      new Cost() 
      { 
       SlabFrom = 0, 
       SlabTo = 100, 
       RatePerUnit = 5 
      }, 
      new Cost() 
      { 
       SlabFrom = 101, 
       SlabTo = 500, 
       RatePerUnit = 10 
      }, 
      new Cost() 
      { 
       SlabFrom = 501, 
       SlabTo = 1000, 
       RatePerUnit = 15 
      }, 
      new Cost() 
      { 
       SlabFrom = 1001, 
       SlabTo = 1500, 
       RatePerUnit = 20 
      } 
     }; 
+0

Bitte einen Code zeigen und Blick auf [MCVE] – lokusking

+0

FWIW Ihre 'Cost' Klasse kann ein Null' SlabTo' nicht speichern, wie es steht. – Rup

+0

Sie erhalten jetzt einige gute Antworten, aber ich mache mir Sorgen, dass Sie nicht einmal versucht haben, diese Summe in Ihrem Beispielcode selbst zu erstellen. Sind das Hausaufgaben? Wir sollten deine Hausaufgaben nicht für dich machen. – Rup

Antwort

1

Sie können dies tun:

rates.TakeWhile(item => item.SlabFrom totalUsage) 
    .Sum(item => (double)((item.SlabTo > totalUsage ? totalUsage : item.SlabTo) - item.SlabFrom) * item.RatePerUnit); 
+0

Dies sollte für die Gesamtnutzung berechnen, Gesamtnutzung ist Eingabe, Slab's werden verwendet, um die Kosten zu berechnen, Es sollte den Bereich verwenden und berechnen die Kosten. – user6634447

+0

@ user6634447 - Dies gibt die Antwort –

+0

@Rup - ya .. nicht sicher, was mit dem 'totalUsage' gemeint ist ... - bearbeitet, um zu versuchen und nehmen, was ich denke, er will in Rechnung –

1

Wenn Sie nur die ersten 3

int usage = 503; 
int total = usage < 100 ? usage * 5 : 500 + (usage < 500 ? (usage - 100) * 10 : 4000 + (usage - 500) * 15); 
//4545 

Wenn Sie eine allgemeinere Antwort wollen
von th e Art und Weise i Ihre Cost-Klasse verwendet diese

decimal used = 1000; 
decimal LastSlabto = 0; 
decimal total = 0; 

foreach (Cost rate in rates) 
{ 
    if (used > rate.SlabTo - LastSlabto) 
     total += (rate.SlabTo - LastSlabto) * rate.RatePerUnit; 
    else 
    { 
     total += used * rate.RatePerUnit; 
     used = 0; 
     break; 
    } 
    used -= rate.SlabTo - LastSlabto; 
    LastSlabto = rate.SlabTo;    
} 
0

dieser Bereich

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace ConsoleApplication4 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("SlabFrom", typeof(int)); 
      dt.Columns.Add("SlabTo", typeof(int)); 
      dt.Columns["SlabTo"].AllowDBNull = true; 
      dt.Columns.Add("Rate", typeof(double)); 

      dt.Rows.Add(new object[] {0,100,5.00}); 
      dt.Rows.Add(new object[] {100,500,10.00}); 
      dt.Rows.Add(new object[] {501,null,15.00}); 

      int usage = 1500; 

      double cost = 0; 
      foreach(DataRow row in dt.AsEnumerable()) 
      { 
       if(usage > 0) 
       { 
        if((row.Field<int?>("SlabTo") == null) || (usage < row.Field<int>("SlabTo"))) 
        { 
         cost += usage * row.Field<double>("Rate"); 
         usage = 0; 
        } 
        else 
        { 
         cost += (row.Field<int>("SlabTo") - row.Field<int>("SlabFrom")) * row.Field<double>("Rate"); 
         usage -= (row.Field<int>("SlabTo") - row.Field<int>("SlabFrom")); 
        } 
       } 
      } 
     } 
    } 

} 
+0

Scheint ein bisschen Overkill! Ich glaube nicht, dass der 'usage Rup

+0

Code wurde getestet und hat korrekte Ergebnisse erhalten. Antwort sollte 19.500 sein, nicht 12.000. Die zweite Zeile der Tabelle sollte bei 100 (nicht 101) beginnen, um korrekte Ergebnisse zu erhalten. – jdweng

+0

Ich denke, dass Ihr Code bricht, wenn Sie eine vierte Preiszeile hinzufügen. Kannst du 19.500 erklären? Ich denke, die Summe in der Frage sieht korrekt aus. 100 vs 101 ist wahrscheinlich diskrete Platten zählen dann auch. – Rup

0

101-500 Versuchen zu testen, wird wie folgt berechnet (500-101) * 10. Er kann jedoch geändert werden, um Ihr zu passen Anforderung durch geringfügige Änderungen.

private static double CalculateRate(int totalUsage) 
{ 
    var applicableSlabRates = sr.Where(r => r.SlabFrom <= totalUsage).OrderBy(r => r.SlabFrom); 

     double cost = 0; 
     foreach (var r in applicableSlabRates) 
     { 
      int range = 0; 
      if ((r.SlabFrom < totalUsage && totalUsage <= r.SlabTo) || r.SlabTo == null) 
      { 
       range = totalUsage; 
      } 
      else 
      { 
       range = Convert.ToInt32(r.SlabTo) - r.SlabFrom; 
      } 

      cost += range * r.Rate; 

      totalUsage = totalUsage - range; 
     } 

     return cost; 
} 


public class SlabRate 
{ 
     public int SlabFrom { get; set; } 
     public int? SlabTo { get; set; } 
     public double Rate { get; set; } 
} 

static List<SlabRate> sr = new List<SlabRate>(); 
    sr.Add(new SlabRate() { SlabFrom = 0, SlabTo = 100, Rate = 5.00 }); 
    sr.Add(new SlabRate() { SlabFrom = 101, SlabTo = 500, Rate = 10.00 }); 
    sr.Add(new SlabRate() { SlabFrom = 501, SlabTo = null, Rate = 15.00 }); 
0

Von der obigen Antwort habe ich es richtig gemacht, Danke. Bitte sehen

private static double GenericCostCalculation(double units) 
    { 
     var rates = new List<Cost> 
     { 
      new Cost { SlabFrom = 0, SlabTo = 100, RatePerUnit = 10 }, 

      new Cost { SlabFrom = 101, SlabTo = 500, RatePerUnit = 20 }, 

      new Cost { SlabFrom = 501, SlabTo = 1000,RatePerUnit = 30 }, 

      new Cost { SlabFrom = 1001, SlabTo = 2000, RatePerUnit = 40 } 
     }; 

     double cost = 0; 
     foreach (var rate in rates) 
     { 
      if (units > 0) 
      { 
       if ((rate.SlabTo == rates.Max(x => x.SlabTo)) || (units < rate.SlabTo)) 
       { 
        cost += units * rate.RatePerUnit; 
        units = 0; 
       } 
       else 
       { 
        cost += (rate.SlabTo - rate.SlabFrom) * rate.RatePerUnit; 
        units -= (rate.SlabTo - rate.SlabFrom); 
       } 
      } 
     } 
     return cost; 
    } 
+0

Nein, das ist nicht richtig aus dem gleichen Grund, warum ich unten auf jdwengs Antwort geantwortet habe: Subtrahieren von Einheiten, um eine 'Nummer übrig' zu bekommen, dann Vergleich gegen 'SlabTo', was behoben ist, wird die falsche Antwort für 501 sein beispielsweise. Auch für das Aufladen des vollen Bereichs, den Sie verwenden, verwenden Sie '(rate.SlabTo - rate.SlabFrom)', was off-by-one ist, da der SlabFrom-Wert inklusive zu sein scheint - und dieser sich in den kostenintensivsten Bereich ausbreitet . Es gibt wahrscheinlich auch bessere Möglichkeiten, die "Off-the-top-of-the-range" -Prüfung durchzuführen, als Max (SlabTo) in jeder Rate-Iteration zu finden. – Rup

+0

Ja, Sie haben Recht. Bitte schlagen Sie eine Lösung vor – Shijith