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

本文关键字:构造函数 比较 数组 char string | 更新日期: 2023-09-27 18:09:16

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

有经验的人能告诉我底层数据中发生了什么,导致这个比较失败吗?

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

为什么它失败的相等比较时,使用一个字符数组,有空元素来构建字符串?有趣的是,当使用String.Compare(res, "hll wrld") == 0

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

时,测试通过了

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

使用调试器,可以看到"hll wrld" !== "hll wrld'0'0'0"。这里有3个'0 's,每去掉一个元音。您需要charArray不包含这些空字符。

解决这个问题的一种方法是将return语句修改如下:

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

但是,我推荐这个简单的LINQ一行代码,而不是你的Remove()方法。HashSet对Contains的调用为0(1)。

var str = "hello world";
var rmv = new HashSet<char>("aeiou".ToArray());
var res = new string(str.Where(x => !rmv.Contains(x)).ToArray());