c++ - C++中字符串的加法和乘法

标签 c++ string

我正在做C++作业,但无法弄清楚算法。

我必须编写一个使用字符串操作的程序。

字符串和运算符(+和*)应以空格('')区分

乘法先于加法

+)使用atoi将字符串更改为整数

例如 :

输入:abc + b * 4 + xy * 2 + z

输出:abcbbbbxyxyz

到目前为止,这是我所做的↓

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include<sstream>
using namespace std;

enum classify {NUMBER, STRING, OPERATION, SPACE};

int char_type(string c)
{
        if (c >= "0" && c <= "9") return NUMBER;
        else if (c == "*" || c == "+") return OPERATION;
        else if (c == " ") return SPACE;
        else return STRING;
}

int main(void)
{
        string input;
        getline(cin, input);
        istringstream token(input);
        string buffer;

        while (getline(token, buffer, ' '))
                { after I classify them using enum, how can I
                  let the computer to know "multiplication first"? }
}

最佳答案

算法:

  • 将输入字符串转换为标记。 token 由空格分隔。例如,“abc + b * 4 + xy * 2 + z”将转换为标记“abc”,“b”,“”,“4”,“+”,“xy”,“”,“2”, “+”和“z”。
  • 执行乘法运算。
  • 一对一地浏览 token 。
  • 如果 token 是乘法符号(“*”):
  • 确定 token 之前还是之后的 token 是数字。
  • 如果之前的 token 是数字:
  • 创建一个临时字符串,将(字母)之后的标记重复添加到临时字符串中,直到 token 之前(数字)指定的次数。
  • 如果后面的标记是数字:
  • 创建一个临时字符串,将(字母)之前的标记重复添加到临时字符串中,次数为该 token 之后(数字)指定的次数。
  • 将 token 之前设置为临时字符串。
  • 使当前标记(乘法符号)和下一个标记为空标记。
  • 删除空 token 。
  • 执行添加操作。
  • 一对一地浏览 token 。
  • 如果 token 是加号(“*”):
  • 将 token 后连接到 token 前。
  • 使当前标记(乘法符号)和下一个标记为空标记。
  • 删除空 token 。
  • 将 token 转换回字符串。

  • 代码:
    #include <iostream>
    #include <string>
    #include <vector>
    
    typedef std::string Token;
    typedef std::vector<Token> Tokens;
    
    Tokens tokenise(std::string str)
    {
        Tokens tokens;
    
        int startOfToken = 0;
    
        // Move through until you find a space (" ") and then add the token (the start of the token is the previous space) and the end is the current space
        for (int i = 0; i < str.size(); i++)
        {
            if (str.substr(i, 1) == " ")
            {
                tokens.push_back(str.substr(startOfToken, i - startOfToken));
    
                startOfToken = i + 1;
            }
        }
    
        // Add last token (there is no space after it to mark it)
        tokens.push_back(str.substr(startOfToken));
    
        return tokens;
    }
    
    bool containsNumber(Token token)
    {
        if (token.find("0") != std::string::npos)
        {
            return true;
        }
        else if (token.find("1") != std::string::npos)
        {
            return true;
        }
        else if (token.find("2") != std::string::npos)
        {
            return true;
        }
        else if (token.find("3") != std::string::npos)
        {
            return true;
        }
        else if (token.find("4") != std::string::npos)
        {
            return true;
        }
        else if (token.find("5") != std::string::npos)
        {
            return true;
        }
        else if (token.find("6") != std::string::npos)
        {
            return true;
        }
        else if (token.find("7") != std::string::npos)
        {
            return true;
        }
        else if (token.find("8") != std::string::npos)
        {
            return true;
        }
        else if (token.find("9") != std::string::npos)
        {
            return true;
        }
    
        return false;
    }
    
    Tokens removeEmptyTokens(Tokens tokens)
    {
        Tokens newTokens;
    
        for (int i = 0; i < tokens.size(); i++)
        {
            // Only add token to new tokens if it isn't empty
            if (tokens[i] != "")
            {
                newTokens.push_back(tokens[i]);
            }
        }
    
        return newTokens;
    }
    
    Tokens performMultiplicationOperations(Tokens tokens)
    {
        // Iterate through the tokens
        for (int i = 0; i < tokens.size(); i++)
        {
            // If a token is a multiplication sign ("*")
            if (tokens[i] == "*")
            {
                // Store token before sign and after sign
                std::string* previousToken = &tokens[i - 1];
                std::string* nextToken = &tokens[i + 1];
    
                // Find out whether the previous token or the next token is a number
                bool tokenThatIsNumber = containsNumber(*nextToken); // False if previous token is a number, true if next token is a number
    
                // If previous token is a number:
                if (tokenThatIsNumber == false)
                {
                    // Convert previous token to a number
                    int previousTokenAsInteger = std::stoi(*previousToken);
    
                    // Temp variable to store final string
                    std::string tempString;
    
                    // Add next token to temp string as many times as previous token specifies
                    for (int j = 0; j < previousTokenAsInteger; j++)
                    {
                        tempString += *nextToken;
                    }
    
                    // Set previous token to temp string
                    *previousToken = tempString;
    
                    // Get rid of current token ("*") and next token
                    tokens[i] = "";
                    *nextToken = "";
                }
                // If next token is a number:
                else
                {
                    // Convert next token to a number
                    int nextTokenAsInteger = std::stoi(*nextToken);
    
                    // Temp variable to store final string
                    std::string tempString;
    
                    // Add previous token to temp string as many times as next token specifies
                    for (int j = 0; j < nextTokenAsInteger; j++)
                    {
                        tempString += *previousToken;
                    }
    
                    // Set previous token to temp string
                    *previousToken = tempString;
    
                    // Make current token ("*") and next token empty
                    tokens[i] = "";
                    *nextToken = "";
                }
            }
        }
    
        // Remove empty tokens
        tokens = removeEmptyTokens(tokens);
    
        return tokens;
    }
    
    Tokens performAdditionOperations(Tokens tokens)
    {
        // Iterate through the tokens
        for (int i = 0; i < tokens.size(); i++)
        {
            // If a token is an addition sign ("+")
            if (tokens[i] == "+")
            {
                // Store token before sign and after sign
                std::string* previousToken = &tokens[i - 1];
                std::string* nextToken = &tokens[i + 1];
    
                // Concatenate next token onto end of previous token
                *previousToken += *nextToken;
    
                // Make current token ("+") and next token empty
                tokens[i] = "";
                *nextToken = "";
            }
        }
    
        // Remove empty tokens
        tokens = removeEmptyTokens(tokens);
    
        return tokens;
    }
    
    std::string tokensToString(Tokens tokens)
    {
        std::string tempString;
    
        for (int i = 0; i < tokens.size(); i++)
        {
            tempString += tokens[i];
        }
    
        return tempString;
    }
    
    int main()
    {
        // Get user input
        std::string input = "";
    
        std::cout << "Please enter something: ";
    
        std::getline(std::cin, input);
    
        // Tokenise
        Tokens tokens = tokenise(input);
    
        // Perform multiplication operations
        tokens = performMultiplicationOperations(tokens);
    
        // Perform addition operations
        tokens = performAdditionOperations(tokens);
    
        // Convert tokens to strings
        std::string finalString = tokensToString(tokens);
    
        std::cout << finalString;
    }
    

    关于c++ - C++中字符串的加法和乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61027763/

    相关文章:

    c++ - 如何从Opencv中的图像矩阵中提取数值梯度矩阵

    c++ - 如何为索引创建类型

    c# - 字符串到日期时间无法转换 - C#

    php - 轻松从以特定方式格式化的字符串中提取数据

    c++ - 阅读字符串和 double

    c++ - 在c++中初始化一些数据数组

    c++ - 动态分配内存和取消引用

    c++ - 为什么这个 .c 文件只有一行 "../xx/xx.c"?

    java - 我可以使用正则表达式或其他方式更快地执行此操作吗?

    c# - 替换字符串 C# 中的换行符