C++ VS17 给出的输出与 Linux 子系统中的相同代码不同

Posted

技术标签:

【中文标题】C++ VS17 给出的输出与 Linux 子系统中的相同代码不同【英文标题】:C++ VS17 gives different output than same code in Linux Subsystem 【发布时间】:2018-11-18 01:15:45 【问题描述】:

我很难找到答案。我希望它不是重复的。我为 leetcode.com 挑战编写了代码,该挑战在 VS17 中按预期工作,但不适用于 leetcode 或我用 g++ 编译的 Ubuntu WSL。该代码搜索具有唯一字母的最长子字符串。字符串“pwwkew”的答案是 3(VS17 得到 3),但在 Linux 和 leetcode 上却是 4。我猜这与 MinGW 与 G++ 有关。在 Ubuntu 上,我使用多个不同版本的 C++ 编译了该程序:g++ -Wall -Wextra -Werror string.cpp -std=c++1y -o string

提前致谢!这也是我的第一篇文章,所以请放轻松:)。

#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include <set>
#include <unordered_set>
using namespace std;


/*
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
*/

int main()

    string s = "pwwkew";

    //this algorithm adds unique chars to a set in the order that they appear in the string
    //after each for loop, the maximum number between maxLen and the size of the set is recorded
    //when a duplicate letter is found, all of the letters up until and including the last
    //occurence of that letter are erased, so the remaining letters are only the uniques in the current 'substring'
    unordered_set<char> seen;
    int maxLen = 0;
    for (int end = 0; end < s.size(); end++)
           
        if (seen.insert(s[end]).second == false)
        
            if (seen.begin() == seen.find(s[end]))
            
                seen.erase(seen.begin());
            
            else 
                seen.erase(seen.begin(), seen.find(s[end+1]));
            
            seen.insert(s[end]);
        
        maxLen = max(maxLen, (int)seen.size());
    


    return 0;
    

编辑:我添加了一个迭代器循环以在每次初始 for 循环执行后打印集合中的值,VS17 打印:

p
p w
w
w k
w k e
k e w

Linux 打印时:

p
w p
w p
k p w
e k p w
w

所以我猜插入顺序被一个编译器颠倒了,这会导致我的 set.erase 以错误的顺序执行?

【问题讨论】:

【参考方案1】:

您似乎在假设 unordered_set 中的值排序。请记住,顺序可能取决于实现,并且您可以使用不同的实现有不同的行为。

【讨论】:

感谢您的回复!因此,即使它们每次在调试器和打印语句中都以相同的顺序显示,它们在被发现和删除时可能不会按该顺序显示? 除了内容之外,您永远不应该考虑集合中的任何内容。因此,订单是绝对的否。也许您可以使用向量/列表来获得正确性,我猜是 set+vector 或 set+stack 以获得最佳解决方案。或者您可以编写自己的实现【参考方案2】:

unordered_set 以不确定的顺序存储其元素。尝试使用 seen.erase 删除您添加到集合中的前 2 个元素,并且两个迭代器将不起作用。

重新考虑你在做什么并选择一个不同的容器。

【讨论】:

谢谢!我会看看我是否可以用有序集合来调整逻辑。

以上是关于C++ VS17 给出的输出与 Linux 子系统中的相同代码不同的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统Linux入门(中) {基本指令:输入输出,重定向输入输出,管道,显示时间和日期,打包和压缩,打包VS压缩,包和文件}

VS2019 C++ x64 与 x86 编译器的坑

c++(vs上)与g++(linux下)对于++操作的汇编代码解读

我在 C++ 编码方面非常陌生,我无法设置 vs 代码给出错误 [关闭]

使用VS2019 开发Linux C++ 程序

ubuntu(Linux)安装Vs code并配置c++编译及cmake多文件编译