在C++中的意外输出

问题描述 投票:0回答:2

这不是编程比赛的问题,而是C++语言的问题。

codeforces上有一个老的编程问题。解决方法是用C++。我已经用Python解决了,但我不明白C++的这种行为。在我的电脑和onlinegdb的C++编译器中,我得到了预期的输出,但是在codeforces的法官上,我得到了不同的输出。

如果对这个问题感兴趣的话。http:/codeforces.comcontest8problemA 很简单,小编看了一下。虽然阅读它不是本题的要求。

任务简述。

Print("forward") if string a 见于字符串 s 和弦 b 也见于 s

Print("backward") 如果字符串 a 与字符串相反 s 和弦 b 反过来说也是 s

Print("both")如果以上两个都是 true

Print("fantasy"),如果以上两个都是。false

#include<bits/stdc++.h>
using namespace std;
#define int long long

//initializing all vars because blogs said uninitialized vars sometimes give unexpected result
string s="", a="", b="";
bool fw = false;
bool bw = false;
string now="";
string won="";
int pa=-1, pb=-1, ra=-1, rb=-1;

signed main()
{
    //following 2 lines can be ignored
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //taking main input string s and then two strings we need to find in s are a & b
    cin >> s >> a >> b;
    //need reverse string of s to solve the problem
    string r = s;
    reverse(r.begin(), r.end());
    //pa is index of a if a is found in s else pa = -1 if not found
    pa = s.find(a);

    //if a was a substring of s
    if (pa != -1) {
        //now is substring of s from the next letter where string a was found i.e. we remove the prefix of string till last letter of a
        now = s.substr(pa + a.size(), s.size() - (pa + a.size()));
        //pb stores index of b in remaining part s i.e. now
        pb = now.find(b);

        //if b is also in now then fw is true
        if (pb != -1) {
            fw = true;
        }
    }
    //same thing done for the reverse of string s i.e. finding if a and b exist in reverse of s
    ra = r.find(a);
    if (ra != -1) {
        won = r.substr(ra + a.size(), r.size() - (ra + a.size()));
        rb = won.find(b);
        if (rb != -1) {
            bw = true;
        }
    }
    if (fw && bw) {
        cout << "both" << endl;
    }
    else if (fw && !bw) {
        cout << "forward" << endl;
    }
    else if (!fw && bw) {
        cout << "backward" << endl;
    }
    else {
        cout << "fantasy" << endl;
    }
    return 0;
}

用于输入

atob
a
b

S="ATOB", A="A", B="B"

这里是反向的 atobbota.

a 是在 atob.

所以,字符串 now = tob.

b 是在 tob 所以 fwtrue.

现在 a 是在 bota.

所以,字符串 won = "" (空,因为后面什么都没有 a). 所以。b 不在 won.

所以.., rwfalse.

这里的答案是打印 forward 而在我的电脑和onlinegdb上的C++14中,输出的是 forward 但在codeeforces法官上,它是 both.

我做了许多代码的变化,但没有结果。

最后,我观察到,如果我在PC上运行我的程序,不给任何输入,在终端上用Ctrl-C终止程序,它打印出的是 both 这就奇怪了,因为只有当这两个人都是 fwrw 为真。

C++的这种行为是什么?

c++ string boolean c++14
2个回答
4
投票

我们来剖析一下这段代码,看看能发现什么问题。它有点提示进入代码审查,但有 除了故障的近因外,还有多个问题。

#include<bits/stdc++.h>

千万不要这样做. 如果你在一个例子中看到它,你就会知道这是一个。坏的 的例子来遵循。

using namespace std;

好吧,我们不在头,样本代码的简洁是一个合理的目标。

#define int long long

哦,不,为什么有人会这样做呢?第一个问题是 前处理程序替换 无论如何禁止替换关键词(如 int).

即使没有这一禁令,后面这一行

int pa=-1, pb=-1, ra=-1, rb=-1;

现已成为 故意撒谎就好像你在混淆代码一样。如果只是写一个 long long pa ... 如果这是你的意思,它不会是欺骗性的。

//initializing all vars because blogs said uninitialized vars sometimes give unexpected result
string s="", a="", b="";

但是... std::string 是一个有缺省构造函数的类类型,所以它不能被取消初始化(它会被缺省初始化,这很好,而写下的 ="" 是额外的噪音)。)

这些博客都在警告你 默认初始化 的非类类型(这使得它们的值不确定),所以

bool fw = false;

仍然是合理的。

NB. 这些都是 globals,反正都是零初始化的 (cf).

signed main()

在此 脸是可以接受的 main - 你不应该再打别的字了,否则会被视为 "行为不端"。

int main() { ... }
int main(int argc, char *argv[]) { ... }

接下来,这些字符串的位置都是(潜在的)错误的类型,并与错误的值进行比较。

ra = r.find(a);
if (ra != -1) {

可能是

auto ra = r.find(a);
if (ra != std::string::npos) {

(你可以写 std::string::size_type 而不是 auto但我看不出这里有什么好处--无论哪种方式,接口、返回类型和返回值都与 std::string::find 证据充分)。)

唯一剩下的反对意见是,没有一个国家 now, won 或尾部子串搜索对应你问题陈述中的任何内容。


1
投票

上面的回答和评论对你的问题来说,信息量已经够大了。我还不能评论,所以我想在这里补充一个简化的答案,因为我自己也在学习。

从不同的编译器上的不同输出,你可以回溯逻辑,发现这一行的代码流程是不同的。

if (rb != -1) {

只要在这一行前加一个日志,或者用调试器就可以了。

cout << "rb:" << rb << endl;

你可以在你的电脑上看到: rb:-1

但在codeforces上:rb:4294967295。

won.find(b) return npos,这意味着你有一个任务:rb = npos。

这是我的推测,但一个可能的情况是:

在你的电脑上, rb被编译成int(关键字), 它不能容纳4294967295, 并赋值给 -1.

但在codeforces上,rb被编译成long长,按照定义,4294967295反而被赋值。

因为你重新定义了关键字int,这又是C++编程语言的标准所建议的,所以不同的编译器会对这行代码有不同的处理。

© www.soinside.com 2019 - 2024. All rights reserved.