2014-09-24 1 views
1

Я работаю над написанием простого линейного калькулятора. Например, пользователь может ввести два уравнения (строки), такие как y = 5x + 3 и y = -3x + 6. Самая основная особенность этого калькулятора заключается в том, что он вернет точку пересечения этих двух линий.Как использовать std :: stod правильно

Препятствие, которое я не могу понять, состоит в том, как разобрать строку на две части данных: наклон и y-перехват. Это простой калькулятор, поэтому формат обеих строк будет равен y = mx + b, однако как наклон, так и/или y-перехват могут быть нецелыми числами (т. Е. Плавает).

Я столкнулся с функцией в строковой библиотеке с именем stod, которая преобразует число в строку в числовое значение (я правильно понимаю это?).

http://www.cplusplus.com/reference/string/stod/

Мой вопрос, будет эта функция сделать работу? Если да, то как именно я использую параметр «idx»? Я не совсем понимаю.

Если это не сработает, как я могу разобрать данные, введенные пользователем?

  • оба уравнениями являются строками (у = х + б)
  • м и б имеет частные переменные, посвященные в хранении десятичного значения (т.е. двойной m_ и двойная b_ частные переменные-членов)
+0

Каким образом вы можете получить вход? Можете ли вы потребовать, чтобы вход всегда ** точно ** формы 'y = mx + b'? – druckermanly

+0

Вид. Как я уже сказал, они вводят точно «y = mx + b», который, я думаю, можно переставить в «y = b + mx», но наклон всегда связан с x. Большая дисперсия - это значения наклона/перехвата. Они удваиваются, поэтому пользователь может ввести -5, 5.2, -0.5 и т. Д. – nickfoss32

+0

@ nickfoss32, код примера на вашей связанной странице показывает, как использовать параметр 'idx'. –

ответ

3

Это, как работает параметр IDX:

#include <string> 
#include <iostream> 

int main(void) 
{ 
    std::string data = "y=5.9568x+3.14"; //say you have a string like this.. 

    double y, x, m, b; 
    y = 0; 
    x = 0; 

    std::size_t offset = 0; //offset will be set to the length of characters of the "value" - 1. 
    m = std::stod(&data[2], &offset); //So we want to get the value "5.9568 
    b = std::stod(&data[offset + 3]); //When we reach this line, offset has a value of 6 

    std::cout<<b; 
    return 0; 
} 

Так что теперь вы спрашиваете, почему это имеет значение 6? Хорошо, потому что:

5.9568 ровно: 6 символов в длину. Таким образом, на следующей строке, когда мы делаем

b = std::stod(&data[offset + 3]);

мы фактически подавая ему указатель на адрес x + 3 .. и что оказывается в самом начале 3.14.

Другими словами, это эквивалентно:

std::stod(&data[9]);

Так что параметр IDX на самом деле индекс/длина двойника в символов в строке. Если строка:

str = "3.14159"

Тогда std::stod(str, &idx) сделает IDX равным: 6.

если строка:

str = "y = 1024.789" тогда std::stod(&str[4], &idx) составит IDX, равное: 8 ЗАПУСК ОТ & str [4] ..

1

Вот что-то просто с не проверяя никаких ошибок, чтобы вы начали:

Если предположить, что входная строка всегда точно формы y=mx+b и вы хотите, чтобы разобрать его, чтобы получить численные значения m и b йо u может сначала обозначить строку с помощью y, =, x и в качестве разделителей.

Пример функции токенизации может быть найден here. Здесь воспроизводится:

void tokenize(const std::string &str, 
       std::vector<std::string> &tokens, 
       const std::string &delimiters) 
{ 
    // Skip delimiters at beginning. 
    std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); 
    // Find first "non-delimiter". 
    std::string::size_type pos  = str.find_first_of(delimiters, lastPos); 

    while (std::string::npos != pos || std::string::npos != lastPos) 
    { 
    // Found a token, add it to the vector. 
    tokens.push_back(str.substr(lastPos, pos - lastPos)); 
    // Skip delimiters. Note the "not_of" 
    lastPos = str.find_first_not_of(delimiters, pos); 
    // Find next "non-delimiter" 
    pos = str.find_first_of(delimiters, lastPos); 
    } 
} 

Первый аргумент является строкой, чтобы разметить, вторая ссылка на vector<string> которой функция будет ставить маркеры в, и третий аргумент является строкой, содержащей все символы-разделители , Вы можете использовать его с разделителями, упомянутых выше, как это:

string s = "y=-3x + 10"; 
vector<string> tokens; 
tokenize(s, tokens, "y=x "); 

Для примера строки выше tokens будет содержать следующие строки: -3, + и 10.

Теперь вы можете перебрать tokens и позвонить по номеру stod() на каждый токен. Вы можете поместить результаты stod() в vector<double>:

vector<double> doubles; 
for (vector<string>::iterator iter = tokens.begin(); iter != tokens.end(); ++iter) { 
    try { 
     doubles.push_back(stod(*iter)); // size_t* idx is an optional argument 
    } catch (...) { 
     // handle exceptions here. stod() will throw an exception 
     // on the "+" token but you can throw it away 
    } 
} 

Теперь doubles должны иметь ровно два элемента - один для наклона и другой для перехвата.Предполагая, что наклон пришел первый (строка была в форме y=mx+b вместо y=b+mx), то вы можете извлечь их из doubles:

double m = doubles[0]; 
double b = doubles[1]; 

Синтаксические начальная строка является более сложной, если пользователь имеет различные формы, как y=b+mx (в в этом случае перехват был первым) и намного сложнее, если пользователь может ввести даже более странные (но действительные) формы, такие как x*m+b=y (теперь вы не можете просто предположить, что число до символа x - это наклон). Из вашего вопроса неясно, какие альтернативные формы считаются действительными, но тем не менее это должно вас начать.

Наконец, что касается вашего вопроса о *idx, stod() вставляет в него положение первого символа после номера, который он разбирает. Это позволяет легко анализировать несколько номеров в одной строке, пропуская число, которое было просто проанализировано. Используя пример в вашей ссылке с некоторыми дополнительными комментариями:

std::string orbits ("365.24 29.53"); 
std::string::size_type sz;  // alias of size_t 

double earth = std::stod (orbits,&sz); 
// sz now holds the position of the first character after 365.24, which is whitespace 
// the next call to stod() will start from the sz position 
double moon = std::stod (orbits.substr(sz)); 
Смежные вопросы