0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
1

Расчет среднего значения в колонке ListView с учетом значения в ComboBox

20.05.2016, 21:32. Показов 1335. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите решить такую задачу.Пользователь заполняет таблицу ListView данными о моторах, включающими тип мотора, получаемый от ComboBox, и его КПД, получаемый от TEdit.Необходимо рассчитать средний КПД по типу мотора.
Неудачная попытка реализации:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include "Unit1.h"
#include <string.h>
 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
         typedef struct
        {
        char mot[40]; //тип мотора
        char m[40];
        float t;
        float v;
        float r;
        float k; //кпд мотора
        } A;
        A dat[200];
int emot=0;
//---------------------------------------------------------------------------
 __fastcall TForm1::func()
{
         ListView1->Items->Clear();
        for (int i=0; i<emot; i++)
 {
 
 TListItem * ListIt= ListView1->Items->Add();
 ListIt->Caption= i+1 ;
 ListIt->SubItems->Add(dat[i].mot);
 ListIt->SubItems->Add(dat[i].m) ;
 ListIt->SubItems->Add(dat[i].t) ;
 ListIt->SubItems->Add(dat[i].v) ;
 ListIt->SubItems->Add(dat[i].r) ;
 ListIt->SubItems->Add(dat[i].k) ;
 }
}
 
//---------------------------------------------------------------------------
void __fastcall TForm1::vvodClick(TObject *Sender)
{
{
 if (model->Text.IsEmpty(),
 tok->Text.IsEmpty(),
 volt->Text.IsEmpty(),
 rev->Text.IsEmpty(),
 kpd->Text.IsEmpty())
 {
 ShowMessage("Введены не все данные");
 return;
 }
 {
        sscanf(MotorType->Text.c_str(), "%s" , &dat[emot].mot);
        sscanf(model->Text.c_str(), "%s" , &dat[emot].m);
        sscanf(tok->Text.c_str(), "%g" , &dat[emot].t);
        sscanf(volt->Text.c_str(), "%g" , &dat[emot].v);
        sscanf(rev->Text.c_str(), "%g" , &dat[emot].r);
        sscanf(kpd->Text.c_str(), "%g" , &dat[emot].k);
        emot++   ;
           func();
 
 }
}
}
//---------------------------------------------------------------------------
 
 
void __fastcall TForm1::midClick(TObject *Sender)
{
char mot[40];
if(MotorType->Text!="")sscanf(MotorType->Text.c_str(),"%s",&dat[emot].mot);
else
  {
  ShowMessage("Вы не указали тип мотора");
  return;
  }
 
float kpd=0;
int n;
for(int i=0; i<emot ;i++)
{
 if(!strcmp(mot,dat[emot].mot))
 {
  kpd+=dat[i].k;
  n++;
 }
}
float mid=kpd/n  ;
kpds->Text = FloatToStr(mid);
}
//---------------------------------------------------------------------------
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.05.2016, 21:32
Ответы с готовыми решениями:

Все элементы массива, значения которых на 50% меньше среднего или на 50% больше среднего значения, заменить нулем
Вычислить среднее значение элементов массива. Вывести на дисплей полученное значение. После этого...

Расчет среднего значения помесячно
Доброго времени суток. Вопрос. Как можно посчитать среднее &quot;помесячное&quot; значение за год, не...

Расчёт среднего значения цифр в числе
Вводится последовательность из N целых элементов. Для каждого элемента последовательности найти...

Расчет среднего значения помесячно за год
Всем привет. Подскажите, как можно посчитать средние помесячные траты за год в MySQL. Пробую...

19
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
20.05.2016, 21:46 2
Для чего переходить на char, а потом снова преобразовывать при добавлении? Используй String.
Не ясно, что делает func(). Выбрось её и добавляй сразу во vvodClick()
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
20.05.2016, 22:12  [ТС] 3
char использую т.к. тип мотора представляется символьно. Конкретно здесь использую его чтобы учесть тип мотора при расчете.
func() используется еще для кнопки загрузки данных. Эту кнопку тут не показываю т.к. для расчетов она не важна.
Можете показать пример: как тут использовать String?
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
21.05.2016, 08:33 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
        struct A
        {
        String mot; //тип мотора
        String m;
        float t;
        float v;
        float r;
        float k; //кпд мотора
        } dat[200];
 
int emot=0;
 
void __fastcall TForm1::vvodClick(TObject *Sender)
{
 if (model->Text.IsEmpty() ||
 tok->Text.IsEmpty() ||
 volt->Text.IsEmpty() ||
 rev->Text.IsEmpty() ||
 kpd->Text.IsEmpty())
 {
 ShowMessage("Введены не все данные");
 return;
 }
        dat[emot].mot = MotorType->Text;
        dat[emot].m = model->Text;
        dat[emot].t = StrToFloat(tok->Text);
        dat[emot].v = StrToFloat(volt->Text);
        dat[emot].r = StrToFloat(rev->Text);
        dat[emot].k = StrToFloat(kpd->Text);
        ++emot;
}
 
void __fastcall TForm1::midClick(TObject *Sender)
{
String mot;
if(!MotorType->Text.IsEmpty()) mot = MotorType->Text;
else
  {
  ShowMessage("Вы не указали тип мотора");
  return;
  }
 
float kpd=0;
int n;
for(int i=0; i<emot ;i++)
 if(mot == dat[i].mot))
 {
  kpd += dat[i].k;
  n++;
 }
 
float mid=kpd/n;
kpds->Text = FloatToStr(mid);
}
А тип мотора при вводе и при поиске среднего вводится через одно и то же поле MotorType?
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
21.05.2016, 10:10  [ТС] 5
Да, при вводе и поиске тип мотора задается в MotorType.
Попробовал сделать как вы предложили, теперь выдает ошибки:
[C++ Error] Unit1.cpp(150): E2188 Expression syntax в этой строчке
C++
1
 if(mot == dat[i].mot))
[C++ Error] Unit1.cpp(157): E2034 Cannot convert 'TButton *' to 'long double'
[C++ Error] Unit1.cpp(157): E2342 Type mismatch in parameter 'Value' (wanted 'long double', got 'TButton *') в этой строчке
C++
1
kpds->Text = FloatToStr(mid);
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
21.05.2016, 11:00 6
Скобка лишняя. Сам бы исправил.
C++
1
if (mot == dat[i].mot)
Добавлено через 34 секунды
kpds - это строка ввода?
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
21.05.2016, 11:03  [ТС] 7
Каюсь, недосмотрел.
kpds - это компонент TEdit.
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
21.05.2016, 11:08 8
Ну, теперь работает?
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
21.05.2016, 11:14  [ТС] 9
Все время считает 0.
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
21.05.2016, 12:30 10
Проще всего посмотреть отладчиком. Поставь точку останова на цикл суммирования и в пошаговом режиме смотри за содержимым переменных и за проверкой условия.
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
22.05.2016, 01:07  [ТС] 11
Попробовал сделать так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void __fastcall TForm1::midClick(TObject *Sender)
{
char mot[40];
sscanf(MotorType->Text.c_str(), "%s", &mot);
int kpd=0;
int n=0;
int mid;
for(int i=0; i<emot ;i++)
{
 if(strcmp(dat[i].mot,mot)==0);
 {
  kpd+=dat[i].k;
  n++;
 }
}
mid=kpd/n  ;
kpds->Text = mid;
}
Рассчитывает среднее по всем данным.
Пробовал как вы предложили:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __fastcall TForm1::midClick(TObject *Sender)
{
String mot;
int kpd=0;
int n=0;
int mid;
for(int i=0; i<emot ;i++)
{
 if(mot == dat[i].mot);
 {
  kpd+=dat[i].k;
  n++;
 }
}
mid=kpd/n  ;
kpds->Text = mid;
}
Аналогичный результат.
Очевидно надо по другому условие или функцию strcmp задать. Но как, придумать не получается.
Среди вариантов было:
C++
1
 if(strcmp(ListView1->Items->Item[i]->SubItems->Strings[0].c_str(), MotorType->Text.c_str()) != 0);
Учитывать MotorType никак не хочет.
0
Практикантроп
4823 / 2717 / 524
Регистрация: 23.09.2011
Сообщений: 5,777
22.05.2016, 01:25 12
Цитата Сообщение от uran924 Посмотреть сообщение
if(mot == dat[i].mot);
У вас же String mot не определено, как можно его с чем-то сравнивать?
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
22.05.2016, 08:42 13
Так куда делась строка с присвоением mot и что показал отладчик?
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
22.05.2016, 12:26  [ТС] 14
А как String mot определить?
Отладчик пишет сначала mot:{"S<Ш<ГиВя\x01"} потом mot:{NULL}
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
22.05.2016, 14:01 15
C++
1
2
3
4
5
6
7
String mot;
if(!(MotorType->Text.IsEmpty())) mot = MotorType->Text;
else
  {
  ShowMessage("Вы не указали тип мотора");
  return;
  }
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
22.05.2016, 14:56  [ТС] 16
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __fastcall TForm1::midClick(TObject *Sender)
{
String mot;
if(!(MotorType->Text.IsEmpty()))
mot= MotorType->Text;
else
  {
  ShowMessage("Âû íå óêàçàëè òèï ìîòîðà");
  return;
  }
int kpd=0;
int n=0;
int mid;
for(int i=0; i<emot ;i++)
{
 if(mot==dat[i].mot);
 {
  kpd+=dat[i].k;
  n++;
 }
}
mid=kpd/n  ;
kpds->Text = mid;
}
По отладчику mot получает значение MotorType , но строчка:
C++
1
 if(mot==dat[i].mot);
ни на что не влияет.
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
22.05.2016, 16:21 17
У тебя там нет пробелов лишних в начале и в конце названий?
А в dat[i].mot названия есть? Цикл перебирает их?
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
22.05.2016, 16:58  [ТС] 18
В MotorType варианты такие:
постоянного_тока
переменного_тока
специальные
прочие

dat[i].mot получает одно из вышеперечисленных текстовых значений, но если тексты mot и dat[i].mot не совпадают
программа все равно продолжает обрабатывать эти строки:
C++
1
2
kpd+=dat[i].k;
  n++;
вероятно надо чтобы после
C++
1
 if(mot==dat[i].mot);
при несовпадении программа возвращалась в начало цикла и обрабатывала следующую строку таблицы.
0
7785 / 6553 / 2983
Регистрация: 14.04.2014
Сообщений: 28,617
22.05.2016, 17:01 19
Лучший ответ Сообщение было отмечено uran924 как решение

Решение

Точку с запятой убери после if.
0
0 / 0 / 0
Регистрация: 20.05.2016
Сообщений: 10
22.05.2016, 17:20  [ТС] 20
Заработало!
Спасибо вам огромное!
0
22.05.2016, 17:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.05.2016, 17:20
Помогаю со студенческими работами здесь

Расчет среднего значения для конкретного столбца матрицы
Добрый день! Имеется матрица из нескольких столбцов. Расчет среднего значения для конкретного...

Автоматический расчет среднего значения после указания периода времени
Здравствуйте! Помогите пожалуйста сделать автоматический расчет среднего значения из имеющихся...

Excel. Автоматический расчет среднего значения после указания периода времени
Здравствуйте! Помогите пожалуйста сделать автоматический расчет среднего значения из имеющихся...

Расчет среднего значения по динамическому диапазону. Excel 2016, без макросов
Есть таблица с числовыми значениями, нужно вытаскивать средние значения с определенным периодом. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru