繁体   English   中英

具有超大数组的C#string(char [])构造函数无法进行相等比较

[英]C# string(char[]) constructor with oversized array fails equality comparison

我正在研究一个简单的编程面试问题,以从输入字符串中删除一组不允许的字符。

有更多经验的人可以告诉我基础数据在这里发生了什么,导致此比较失败吗?

using System;
using System.Collections.Generic;

class Solution {

    public static void Main() {

        var str = "hello world";
        var rmv = "aeiou";

        var res = Remove(str, rmv);


        Console.WriteLine(res);
        if(res == "hll wrld") Console.WriteLine("test 1 pass");
        else Console.WriteLine("test 1 fail");
    }

    public static string Remove(string input, string rmv) {

        var blacklist = new Dictionary<char, int>();

        for(int i = 0; i < rmv.Length; i++) {
            blacklist[rmv[i]] = 1;
        }

        // max length
        var charArray = new char[input.Length];
        var j = 0;

        for(int i = 0; i < input.Length; i++) {
            if(!blacklist.ContainsKey(input[i])) {
                charArray[j] = input[i];
                j++;
            }
        }

        return new string(charArray);
    }   
}

并输出:

9:05pm - me running 40 lines of C#
hll wrld
test 1 fail

当使用具有空元素的char数组构建字符串时,为什么在相等比较时失败? 有趣的是,使用String.Compare(res, "hll wrld") == 0时测试通过

问题是因为charArray的初始化长度与输入字符串的长度相同。 由于您要删除元音,因此字符数组中的每个元音都有空字符。

使用调试器,您可以看到"hll wrld" !== "hll wrld\\0\\0\\0" 如果有3 \\0 ,则每个删除的元音一个。 您需要charArray不包含那些空字符。

解决此问题的一种方法是将return语句更改为以下内容:

return new string(charArray).Replace("\\0", "");

但是,我建议使用这种简单的LINQ单线而不是Remove()方法。 HashSet使对Contains的调用为O(1)。

var str = "hello world";
var rmv = new HashSet<char>("aeiou".ToArray());

var res = new string(str.Where(x => !rmv.Contains(x)).ToArray());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM