Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.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++_Algorithm_Qt_Text Editor_Curly Braces - Fatal编程技术网

C++ 自动括号插入算法

C++ 自动括号插入算法,c++,algorithm,qt,text-editor,curly-braces,C++,Algorithm,Qt,Text Editor,Curly Braces,有关详细信息,请参阅 我想写一个算法,当用户在一个大括号后点击回车键时调用。下面详细介绍了预期的行为 一,。假设我们有一个空文档。如果键入左大括号并按Enter键,则预期行为如下: 这可以描述为以下简单算法: 如果在大括号后按Enter键,请将光标移动到下一行,并在大括号缩进之外再缩进一级 如果开口撑杆未配对,请在下一行插入与开口撑杆相同缩进级别的闭合撑杆。否则,如果已配对,则在1之后不执行任何操作 换句话说,如果在已经配对的左大括号后按Enter键,我们不希望插入另一个右大括号。相反,我们只想

有关详细信息,请参阅

我想写一个算法,当用户在一个大括号后点击回车键时调用。下面详细介绍了预期的行为

一,。假设我们有一个空文档。如果键入左大括号并按Enter键,则预期行为如下:

这可以描述为以下简单算法:

如果在大括号后按Enter键,请将光标移动到下一行,并在大括号缩进之外再缩进一级

如果开口撑杆未配对,请在下一行插入与开口撑杆相同缩进级别的闭合撑杆。否则,如果已配对,则在1之后不执行任何操作

换句话说,如果在已经配对的左大括号后按Enter键,我们不希望插入另一个右大括号。相反,我们只想保持缩进的一致性:

二,。现在假设我们在光标所在的第2行键入另一个左大括号,然后按Enter键。我们希望按照上述相同的算法生成一个新的对:

三,。如果我们转到第1行,按Enter键几次,将大括号向下压,然后尝试在顶部创建一个新的块,我们希望它也成对出现:

问题

我很难实现这种行为。我用Qt开发C++中的文本编辑器,但是你不必担心框架的细节。它只是一个实用函数,它接受一个名为context的给定字符串和所讨论的左大括号的索引,并决定是否应该插入右大括号

我的解决方案满足场景1和2,但不满足场景3。它不满足3的原因是因为我正在使用一个队列来处理开始的大括号

我也尝试过使用一个堆栈作为开始的大括号。有趣的是,结果满足1和3,但不满足2

问题:

如何根据上述预期行为编写算法来确定给定的大括号是否已经有匹配对?请注意,我已经在网站上对此进行了研究,并且知道如何确定给定的开括号是否有匹配的闭括号。然而,我上面链接的当前算法并没有按照预期工作,请参见上面的描述,了解它失败的地方


澄清:你不必担心整件事。这是照顾和工作的预期。无法按预期工作的是确定某个特定的大括号是否需要匹配的大括号。

要确定是否存在右大括号,这不是一个复杂的问题,困难的是缩进。如果ope大括号后面有任何不匹配的右大括号,则表示有匹配项。关键是大括号是否在打开的大括号之后。您可以通过以下方式确定这一点:

存储所有不匹配的闭合大括号的位置;如果光标后面有一个大括号,则不需要插入右大括号 动态计算光标未计数未匹配关闭前未匹配大括号的数量,并与光标后未匹配大括号的数量进行比较;如果光标后有多余的右大括号,则不需要插入右大括号 如果您选择2号,我已经扩展到您在计算大括号前后的需要:

bool foo(const string& context, const size_t pos) {
    const auto it = next(cbegin(context), pos);
    const auto before = accumulate(cbegin(context), it, 0, [](const auto output, const auto input) {
        if(input == '{') {
            return output + 1;
        }
        else if(input == '}' && output > 0) {
            return output - 1;
        }
        else {
            return output;
        }
    });
    const auto after = accumulate(it, cend(context), 0, [](const auto output, const auto input) {
        if(input == '{') {
            return output + 1;
        }
        else if(input == '}') {
            return output - 1;
        }
        else {
            return output;
        }
    });

    return before + after >= 0;
}
可以调用此函数,所讨论的文本不包括插入的大括号,并且大括号在字符串中的位置将被插入。如果文本包含在常量字符串栏中,且光标位置为常量大小_tbaz,则可以调用如下函数:foobar,baz如果返回true,则需要添加一个右大括号


在对这件事投否决票之前,请意识到这不是一个关于被打到来世平衡括号中的马的问题。这很可能是被否决的,因为我如何编写一个算法来描述这种行为?这个问题太宽泛了。您需要缩小您的提问范围。@Carcigenicate感谢您的澄清,我已经编辑了我的问题,希望它更清晰。您真的在寻找这个答案:但我可以为您键入答案。谢谢,但我很难理解这对{}->{}是如何工作的,您正在现有的一对中嵌套一组新的大括号。光标后的右大括号数将为1,这比之前多,这表明我们不需要插入右大括号。但我们有。请参见上面的2。是的,这不起作用。@AlexH我将很快尝试键入一个示例,但在您的示例中,您必须计算光标前面的内容。在本例中,+1打开,现在按照光标进行计算,即-1表示结束。由于数字大于或等于0,因此需要添加右大括号。如果已经有一个右括号,那么你的计数应该是-2,总共是-1,这意味着不需要右括号
格斯特德的解决方案不起作用。请参阅,我的解决方案适用于所有情况。@AlexH我实际上已经实现了我的解决方案,并编写了一些简单的测试。我相信它适用于某些情况,而你的情况则不然。如果你不同意,请随时与我联系?