2015-11-12 3 views
-2

Я должен получить значения, введенные в текстовое поле, а затем отобразить общее количество введенных значений, среднее значение и количество введенных значений.Почему мой список полностью не вычисляется правильно? C#

До сих пор я закодированы:

List<int> intScoreList = new List<int>(20); 
decimal decScoreAverage = 0m; 
decimal decScoreTotal = 0m; 

private void btnAdd_Click(object sender, EventArgs e) 
{ 
    int intScore = Convert.ToInt32(txtScore.Text); 
    int intScoreCount = 0; 
    intScoreList.Add(intScore); 
    for (int i = 0; i < intScoreList.Count; i++) 
    { 
     intScoreList[0] = intScore; 
     decScoreTotal += intScoreList[i]; 
     intScoreCount++; //correct 
     decScoreAverage = decScoreTotal/intScoreCount; //correct 
    } 

Когда я вхожу тестовые значения 30, то 40, то общее дает мне 110 (30 + 40 * 2), а не 70 (30 + 40). Где я иду не так?

+2

Используйте скопления Linq, а не цикл 'for'. –

+6

Не совсем понятно, почему вы переписываете 'intScoreList [0]' с 'intScore' вообще ... почему вы это делаете? И почему вы вычисляете среднее значение * в цикле *? И почему вы держите отдельный счет, когда у вас есть 'intScoreList.Count'? Почему бы просто не использовать 'average = ((десятичный) intScoreList.Sum())/intScoreList.Count' –

+0

Какая платформа? ASP.NET, WinForms и т. Д.? Похоже, что обработчик нажатия кнопки может быть вызван дважды - я видел, как это происходит в ASP.NET. – Tim

ответ

1

К комментаторскому (обоснованному) пункту ниже, вот еще несколько объяснений.

Вы не правильно вычисляете, потому что вы меняете первый элемент своих записанных значений: intScoreList[0] = intScore;. Изменяя это, вы мешаете сумме.

Очень чистая операция состоит из добавления новых данных в массив и пересчета суммы.

List<int> intScoreList = new List<int>(20);  
decimal decScoreAverage = 0m; 
decimal decScoreTotal = 0m; 

private void btnAdd_Click(object sender, EventArgs e) 
{ 
    int intScore = Convert.ToInt32(txtScore.Text); 
    int intScoreCount = 0; 
    intScoreList.Add(intScore); 

    decScoreTotal = 0; 
    foreach(int i in intScoreList) { 
     decScoreTotal += i; 
    } 

    decScoreAverage = decScoreTotal/intScoreList.Count; 
    intScoreCount = inScoreList.Count; 
} 

Обратите внимание, что это не обязательно является наиболее эффективной реализации, так как число значений увеличения, цикл foreach будет становиться все более и более дорогим. Лучший подход - отслеживать текущее общее и среднее значение и корректировать их с новым значением (которое вы можете добавить в список для других целей, если вам нужно).

Среднее значение вычисляется следующим образом:

New_average = old_average * (count-1)/count + new_value /count 

И вот новый код:

List<int> intScoreList = new List<int>(20);  
decimal decScoreAverage = 0m; 
decimal decScoreTotal = 0m; 

private void btnAdd_Click(object sender, EventArgs e) 
{ 
    int intScore = Convert.ToInt32(txtScore.Text); 
    int intScoreCount = 0; 
    intScoreList.Add(intScore); 

    intScoreCount = inScoreList.Count; 
    decScoreTotal += intScore;   
    decScoreAverage = decScoreAverage * (intScoreCount- 1)/intScoreCount + intScore/intScoreCount; 

} 
+2

Вы должны добавить замечание относительно того, что изменилось и почему. – Shelby115

+0

Не могу поверить, что я не рассматривал a для каждого цикла. Я думаю, все, что вам нужно, чтобы пройти через цикл, это все значения, чтобы получить общее количество, а остальное можно сделать за пределами. Спасибо! – sugarpeas

+0

@ Shelby115 Код говорит сам за себя. Это просто небольшая вариация кода Ops, о которой он, видимо, не понимал. Довольно счастлив по триггеру downvote, кажется ... – mprivat

0

Поскольку цикл добавляет все элементы, «не требуется

decScoreTotal = 0 

перед вашей петлей?

4

Использование Linq. На событии щелчка кнопки добавления просто добавьте анализируемое значение. Затем отобразите Avg и Count.

List<decimal> scoreList = new List<decimal>(); 
    private void btnAdd_Click(object sender, EventArgs e) 
    { 
     decimalnum; 
     if (decimal.TryParse(txtScore.Text, out num)) 
     { 
      scoreList.Add(num); 
     } 

     // Assign to count label Text property = scoreList.Count; 
     // Assign to average label Text property = scoreList.Average(); 
    } 

Теперь представьте себе возможность сбросить все пользователя ввода:

private void btnReset_Click(object sender, EventArgs e) 
    { 
     scoreList.Clear(); 
    } 

Используя экземпляр списка вы можете легко добавить номер в качестве введен правильно и проанализирован от пользователя. Метод расширения AverageLinq сделает всю математику для вас, не нужно делать это самостоятельно.

+2

humm..where в этом коде вы используете 'Linq' – MethodMan

+1

. Средство() - это LINQ, https://msdn.microsoft.com/en-us/library/system.linq.enumerable.average(v=vs. 90) .aspx –

+0

это методы расширения – MethodMan