#c #composition #chemistry
#c #состав #химия
Вопрос:
Приведенная ниже программа, которая вычисляет молярную массу по заданной молекулярной формуле химического соединения, не содержащего никаких других элементов, кроме углерода, водорода, азота и кислорода.
При запуске программа должна отображать сообщение на консоли Please enter the formula in the form CcHhNnOo (c, h, n, o - integers)
Затем пользователь должен ввести формулу в соответствии с приведенным выше шаблоном. Если химические индексы любого из атомов равны 0 или 1, они должны быть заданы числом.
Например, для соединений меньшего размера введите текст синим цветом:
C0H2N0O1 (water, H2O) MW = 18.015
C17H4N0O0 (methane, CH4) MW = 16.043
C7H5N3O6 (trinitrotoluene, C7H5N3O6) MW = 227.132
C9H13N103 (adrenaline, C9H13NO3) MW = 183.207
C12H22N0O11 (sucrose, C12H22O11) MW = 342.297
Расчет может быть выполнен в соответствии с приведенной ниже формулой:
MW = nC.AC nH.AH nN.AN nO.AO
где MW — требуемая молярная масса. nC, nH, nN and nO
— соответственно, количество атомов углерода, водорода, азота и кислорода в молекуле
соединение и AC, AH, AN and AO
— соответствующие атомные массы:
AC = 12.011
AH = 1.008
AN = 14.007
AO = 15.999
После ввода формулы программа должна вычислить и записать в
консоль запрашивала молярную массу. Если формула не содержит атомов, расположенных в строке порядка, вместо таблицы молярности программа должна отобразить следующее сообщение: Wrong formula! Please use the form CcHhNnOo!
На данный момент мы создали полную программу, но с большим количеством проверок, которые следует убрать, поскольку мы пытаемся сделать программу такой же простой, как 10 строк кода. Программа до сих пор была написана на C в рамках CodeBlocks, и поэтому мы предпочли бы запустить ее.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char formula[512];
cout << "Please enter formula in the form CcHhNnOo (c, h, n, o - integers):" << endl;
cin >> formula;
if (formula[0] != 'C')
{
cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
return 0;
}
int len = strlen(formula);
char curr_element = ' ';
bool C_entered = false, H_entered = false, N_entered = false;
int nC = 0, nH = 0, nN = 0, nO = 0;
for (int i = 0; i < len; i )
{
if (formula[i] >= '0' amp;amp; formula[i] <= '9')
{
switch (curr_element)
{
case 'C':
nC *= 10;
nC = formula[i] - '0';
break;
case 'H':
nH *= 10;
nH = formula[i] - '0';
break;
case 'N':
nN *= 10;
nN = formula[i] - '0';
break;
case 'O':
nO *= 10;
nO = formula[i] - '0';
break;
}
}
else
{
switch (formula[i])
{
case 'C':
curr_element = 'C';
C_entered = true;
break;
case 'H':
curr_element = 'H';
H_entered = true;
break;
case 'N':
curr_element = 'N';
N_entered = true;
break;
case 'O':
curr_element = 'O';
break;
default:
cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
return 0;
}
if ((curr_element == 'H' amp;amp; C_entered == false) ||
(curr_element == 'N' amp;amp; H_entered == false) ||
(curr_element == 'O' amp;amp; N_entered == false))
{
cout << "Wrong formula! Please use the form CcHhNnOo!" << endl;
return 0;
}
}
}
float weight = nC * 12.011f nH * 1.008f nN * 14.007f nO * 15.999f;
cout << "MW = " << weight << endl;
return 0;
}
В идеале идеальным сценарием было бы упростить приведенный выше код.
Комментарии:
1. но вместо этого программа не компилируется, и, похоже, появляются некоторые сообщения об ошибках, которые мы не можем разрешить Итак, какие сообщения об ошибках? coliru.stacked-crooked.com/a/d15d5ab00716ecf3
2. Извиняюсь @Amadeus, сейчас она компилируется и запускается, похоже, я запускал не ту. Итак, вопрос теперь в том, можем ли мы упростить это, поскольку это для школьного проекта моей двоюродной сестры, и то, что я собрал, слишком сложно для нее. Честно говоря, я не могу придумать другого способа, более простого для вышеупомянутой программы, поэтому, если вы можете помочь мне в этом, я был бы очень признателен.
3. Сложную формулу трудно представить в простых терминах. Но один из способов — разбить это на очень-очень простые шаги. (Однако, для скорости — это на самом деле стало бы намного сложнее, но это не ваш вопрос)
4. Вы получаете правильный ответ? Попробуйте использовать longs и doubles вместо int и float. Если вы получите правильный ответ, то сможете сократить свой код
5. Понятно, спасибо за это. Не могли бы вы предоставить мне свое представление кода @ Grantly, возможно, реализующего double вместо int и floats :/
Ответ №1:
Вот что-то не обязательно менее сложное, но, по крайней мере, более короткое:
#include <iostream>
#include <numeric>
#include <string>
#include <regex>
#include <cctype>
#include <map>
int main() {
std::string formula;
std::map<char, int> mapper;
std::cout << "Enter formula (CcHhNnOo): ";
std::getline( std::cin, formula );
if ( std::regex_match( formula.begin(), formula.end(), std::regex( "^((C[0-9] )?)((H[0-9] )?)((N[0-9] )?)((O[0-9] )?)$" ) ) ) {
std::vector<int> value;
char last_char = 'S';
for ( unsigned int i = 0; i < formula.size(); i ) {
char c = formula[i];
if ( (std::isalpha( c ) amp;amp; last_char != 'S') || i == formula.size() - 1 ) {
if ( i == formula.size() - 1 ) value.push_back( static_cast<int>(c) - 48 );
int mul = 1;
mapper[last_char] = std::accumulate( value.rbegin(), value.rend(), 0, [amp;mul](int a, int b) {
int new_value = mul * b a;
mul *= 10;
return new_value;
});
}
if ( std::isalpha( c ) ) {
value = std::vector<int>();
last_char = c;
} else { value.push_back( static_cast<int>(c) - 48 ); }
}
float weight = mapper['C'] * 12.011f mapper['H'] * 1.008f mapper['N'] * 14.007f mapper['O'] * 15.999f;
std::cout << weight << "n";
}
return 0;
}
Имейте в виду, что вы могли бы избежать этого, если бы запрашивали у пользователя только цифры:
#include <iostream>
int main() {
int C, H, N, O;
std::cout << "Enter formula in order C H N O: ";
std::cin >> C >> H >> N >> O;
float weight = C * 12.011f H * 1.008f N * 14.007f O * 15.999f;
std::cout << "MW = " << weight << "n";
return 0;
}