Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++递归函数_C++ - Fatal编程技术网

C++递归函数

C++递归函数,c++,C++,大家下午好,我是递归新手,正在尝试创建一个程序,以获取用户输入来构建数学函数。它在执行简单的操作(如3+4)时有效,但在尝试3+4+6时,main会打印一个空字符串。该程序的目的是将嵌套的数字放在括号内,以便于阅读。我已经试着遵循代码,但递归似乎是我不理解的。谢谢你的时间和帮助 代码 正确输出 Welcome to the equation builder! Each step can only have one operation between two numbers. So the eq

大家下午好,我是递归新手,正在尝试创建一个程序,以获取用户输入来构建数学函数。它在执行简单的操作(如3+4)时有效,但在尝试3+4+6时,main会打印一个空字符串。该程序的目的是将嵌套的数字放在括号内,以便于阅读。我已经试着遵循代码,但递归似乎是我不理解的。谢谢你的时间和帮助

代码

正确输出

Welcome to the equation builder!

Each step can only have one operation between two numbers.
So the equation (3 + 4) + 6 would have one 'nested' operation.

For this step, is there nesting? (y/n): n
What number would you like to enter: 3
What operation would you like to perform? (+, -, /, *): +
What number would you like to enter: 4

The equation you have built is... 3 + 4

Thanks for coming!
Press <RETURN> to close this window...
函数结果为空

Welcome to the equation builder!

Each step can only have one operation between two numbers.
So the equation (3 + 4) + 6 would have one 'nested' operation.

For this step, is there nesting? (y/n): y
        For this step, is there nesting? (y/n): n
        What number would you like to enter: 3
        What operation would you like to perform? (+, -, /, *): +
        What number would you like to enter: 4

The equation you have built is...

Thanks for coming!
Press <RETURN> to close this window...

可能有点过头了,但我认为这个问题本身并不是理解递归的简单例子

为了理解递归部分,我们需要查看一般问题,并了解如何从一个调用到另一个调用(递归步骤),以及基本情况下的停止点是什么。您的目标是创建一个有效的等式,为此,您的输入应该遵循某些准则。具体地说,为了验证此类问题,您需要验证每个输入是否遵循称为上下文无关语法的语法,由以下规则表示:N表示数字或嵌套,O表示操作,D表示数字,而$表示零:

N ->  ( N ) O | D O
D ->   0-9
O ->  + N | - N | * N | / N | $
这里有两个递归。在每个阶段,我们都需要得到一个有效的等式,这些规则确保它保持不变

下面的代码正在从用户创建一个适当的等式

注意一些重要的注意事项-

我使用的是std::stringstream,它在创建字符串和附加到现有字符串时更有效

您不应该过度使用std::endl,因为除了添加换行符之外,它还刷新到stdout,这是非常昂贵的

使用名称空间std;这不是一个好习惯

看看我是如何传递相同的stringstream的,每个阶段都会添加到这个过程中,以便创建通用字符串。如果您的代码没有添加到所携带的值,这意味着您在这个递归步骤中什么都没有做

守则:

#include <sstream>
#include <iostream>
#include <string>
#include <cctype>

#include <assert.h>

void get_num_or_nested(std::stringstream& eq);
void get_operation_or_stop(std::stringstream& eq);

bool is_number(const std::string& s)
{
    int digit_count = 0;

    for (const char& character : s)
    {
        if (std::isdigit(character))
        {
            ++digit_count;
        }
    }

    return !s.empty() && s.size() == digit_count;
}

bool is_operation(char c)
{
    return (c == '+' || c == '-' || c == '*' || c == '/');
}

std::string get_input_from_user()
{
    std::string input;
    std::cin >> input;

    return input;    
}

void get_operation_or_stop(std::stringstream& eq)
{
    std::cout << "Insert one of the following:\n";
    std::cout << "An operation - [ + | - | * | / ]\n";
    std::cout << "s for Stop" << std::endl;

    std::string input = get_input_from_user();

    if (input.size() == 1)
    {
        if (is_operation(input[0]))
        {
            eq << input;
            get_num_or_nested(eq);
        }
        else if (input != "s")
        {
            assert(false);
        }
        // stops!
    }
    else
    {
        assert(false);
    }
}

void get_num_or_nested(std::stringstream& eq)
{
    std::cout << "Insert one of the following:\n";
    std::cout << "A number\n";
    std::cout << "n for Nested" << std::endl;

    std::string input = get_input_from_user();

    if (input == "n")
    {
        eq << "(";
        get_num_or_nested(eq);
        eq << ")";
        get_operation_or_stop(eq);
    }
    else if (is_number(input))
    {
        eq << input;
        get_operation_or_stop(eq);
    }
    else
    {
        assert(false);
    }
}

int main()
{
    std::cout << "Welcome to the equation builder!\n" << std::endl;

    std::stringstream eq;

    get_num_or_nested(eq);

    std::cout << "The equation you have built is... " << eq.str() << std::endl;
    std::cout << "Thanks for coming!" << std::endl;
}

唯一错误的是当用户同意嵌套时。您需要返回函数返回的内容,而不是调用函数并丢弃它返回的内容

if(nesting == "y")
{
    nested = true;
    tab += "\t";
    return buildEq(true, tab);
}

递归函数通常会调用它们自己,并对该输出执行某些操作。当你在buildEq中调用buildEq时,你不会对输出做任何事情。想想你需要的基本情况,然后从这里开始经验法则:在解决后面的错误之前先看看前面的错误。注意:可能无法解决之前的错误,但请务必查看它们。一旦你的程序偏离了轨道,看看它有多严重地陷入了真空可能是无用的。在这种情况下,我看到的第一个错误行为不是空等式;这是因为没有机会在嵌套的情况下输入+6。请注意,在发布版本中,所有这些断言都不是ops。
if(nesting == "y")
{
    nested = true;
    tab += "\t";
    return buildEq(true, tab);
}