这不是编程比赛的问题,而是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"
这里是反向的 atob
是 bota
.
a
是在 atob
.
所以,字符串 now
= tob
.
b
是在 tob
所以 fw
是 true
.
现在 a
是在 bota
.
所以,字符串 won
= ""
(空,因为后面什么都没有 a
). 所以。b
不在 won
.
所以.., rw
是 false
.
这里的答案是打印 forward
而在我的电脑和onlinegdb上的C++14中,输出的是 forward
但在codeeforces法官上,它是 both
.
我做了许多代码的变化,但没有结果。
最后,我观察到,如果我在PC上运行我的程序,不给任何输入,在终端上用Ctrl-C终止程序,它打印出的是 both
这就奇怪了,因为只有当这两个人都是 fw
和 rw
为真。
C++的这种行为是什么?
我们来剖析一下这段代码,看看能发现什么问题。它有点提示进入代码审查,但有 是 除了故障的近因外,还有多个问题。
#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
或尾部子串搜索对应你问题陈述中的任何内容。
上面的回答和评论对你的问题来说,信息量已经够大了。我还不能评论,所以我想在这里补充一个简化的答案,因为我自己也在学习。
从不同的编译器上的不同输出,你可以回溯逻辑,发现这一行的代码流程是不同的。
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++编程语言的标准所建议的,所以不同的编译器会对这行代码有不同的处理。