Как я могу сравнить следующий символ, который содержит файл? - PullRequest
1 голос
/ 01 ноября 2019

У меня мало проблем при чтении кода. Это текстовый файл.

2X^6+3X^3+4X^0=0
5X^6+X^2+X^1-4X^0=0

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

Вы можете видеть во второй строке с X нет целого числа, теперь проблема вторая, когда цикл работает непрерывно. Если я добавлю 1 в текстовый файл с X, файл будет читаться отлично. Кроме того, как я могу поставить условие для удовлетворения этого, что когда есть непосредственно X или -X , он должен хранить 1 или -1 и переходит к следующему персонажу? Также вы можете видеть ^ Я должен хранить это в переменной, тогда как я должен игнорировать это, но не как игнорировать это?

Заранее спасибо

int main()
{
int in;
int power;
char x;
char f;
fstream fin;
fin.open("input1.txt");
list l1,l2;

while(fin.peek() != 61)
{
        fin>>in;
        fin>>x;
        fin>>f;
        fin>>power;
        cout<<in<<endl<<x<<endl<<f<<endl<<power<<endl;
        l1.addtoend(in,power,x);
        cout<<endl;
}
fin.ignore(2,'\n');

while(fin.peek() != 61)
{
        fin>>in;
        fin>>x;
        fin>>f;
        fin>>power;
        cout<<in<<endl<<x<<endl<<f<<endl<<power<<endl;
        l2.addtoend(in,power,x);
        cout<<endl;
}
l1.display();
l2.display();
}

1 Ответ

1 голос
/ 02 ноября 2019

К сожалению, это не так просто, как ожидалось.

Нам нужно разбить задачу на более мелкие части.

То, что вы хотите сделать, - это разбить ваше уравнение по терминам и извлечь из этого коэффициенты и показатели.

Разделение чего-либо на похожие части также называется токенизацией.

Итак, ваше уравнение состоит из терминов, которые следуют одному и тому же шаблону. Сначала необязательный знак, за которым следуют коэффициенты, затем «X ^» и, в конце, показатель степени (который может иметь или не иметь знак).

И поскольку все термины имеют одинаковую структуру,мы можем найти их с помощью так называемого регулярного выражения. C ++ поддерживает эту функциональность. Также для разделения текста на более мелкие токены / термины / сопоставления с образцами у нас есть специальный итератор std::sregex_token_iterator. Как и любой другой итератор в C ++, он перебирает исходную строку и извлекает (и копирует) все совпадающие шаблоны.

ОК, тогда мы уже нашли решение для первой подзадачи. Извлеките все термины и поместите их в std::vector. Мы будем использовать конструктор диапазона std::vector s, чтобы сделать это при определении переменной.

Следующий шаг - получить коэффициент. Здесь нам нужна особая обработка, потому что коэффициент можно опустить с предполагаемым 1. Используя это предположение, мы будем читать термин и преобразовывать коэффициент в целое число. И поскольку мы хотим сделать это в одном операторе, мы используем std::transform из библиотеки алгоритмов STL.

Получение показателей проще. Мы просто конвертируем что-либо в члене после знака «^» в целое число. Мы снова используем std::transform для работы со всеми терминами в одном выражении.

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

Обратите внимание:

Все это можно сделать также со значениями типа с плавающей запятой. Мы также можем разрешить пробелы в уравнении

. Для этого мы просто изменим строку std::regex.

См. Полный пример ниже:

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <regex>
#include <algorithm>
#include <iomanip>

int main() {

    std::string equation{ "5X^6+X^2+X^1-4X^0=0" };

    const std::regex re(R"(([+-]?\d?X\^[+-]?\d+))");
    std::vector<std::string> terms{ std::sregex_token_iterator(equation.begin(), equation.end(), re,1),std::sregex_token_iterator() };


    std::vector<int> coefficients(terms.size());
    std::vector<int> exponents(terms.size());
    int rightHandSite{ 0 };

    // Everything in front of X is the coefficient. Handle special case, when no digit is given
    std::transform(terms.begin(), terms.end(), coefficients.begin(), [](const std::string& s) {
        std::string temp = s.substr(0U, s.find('X'));
        if (1 == temp.size() && !std::isdigit(temp[0])) temp += '1';
        return std::stoi(temp); });

    // Get all exponents
    std::transform(terms.begin(), terms.end(), exponents.begin(), [](const std::string & s) {
        return std::stoi(s.substr(s.find('^') + 1)); });

    // Get right Hand site of equation
    rightHandSite = std::stoi(equation.substr(equation.find('=') + 1));

    // Show result
    std::cout << "\nEquation: " << equation << "\n\nFound '" << terms.size() << "' terms.\n\nCoeffient  Exponent\n";
    for (size_t i = 0U; i < terms.size(); ++i)
        std::cout << std::right << std::setw(9) << coefficients[i] << std::setw(10) << exponents[i] << "\n";
    std::cout << "\n                  --> " << rightHandSite << "\n";

    return 0;
}

Существует множество других возможных решений. Но, возможно, это даст вам представление о том, что вы могли бы сделать.

...