它们是“相同”的 CodeWars。我的代码没有通过所有测试

Posted

技术标签:

【中文标题】它们是“相同”的 CodeWars。我的代码没有通过所有测试【英文标题】:Are they the "same" CodeWars. My code doesn't pass all tests 【发布时间】:2020-11-27 08:16:26 【问题描述】:

问题的条件: 给定两个数组 a 和 b,编写一个函数 comp(a, b) 来检查两个数组是否具有“相同”元素,是否具有相同的多重性。这里的“相同”意味着b中的元素是平方中的元素,无论顺序如何。

我的函数如下所示:

public static bool comp(int[] a, int[] b)
        
            bool result = false;
            if (a == null || b == null)
                return false;
            for (int i = 0; i < b.Length; i++)
            
                for (int j = 0; j < a.Length; j++)
                
                    if (Math.Sqrt(b[i]) == a[j])
                    
                        result = true;
                        break;
                    
                    result = false;
                
                if (result == false) break;
            
            return result;
        

但是这个函数并没有通过所有的测试。我的代码中的错误在哪里?解决这个问题的最佳方法是什么?

【问题讨论】:

if(a == null &amp;&amp; b == null) -- 从技术上讲应该返回 true 吗?还是我太善变了:) Math.Sqrt(b[i]) == a[j] - 如果a 是-2,那么b 是什么,那么b 的平方根是多少? 解决这个问题的最好方法是编写覆盖问题空间的测试用例,然后在发现失败时开始调试。 Protip:Math.Sqrt 很贵。将b[i]a[j] *a[j] 进行比较会便宜得多。 【参考方案1】:

你的代码的问题是这样的:

for (int i = 0; i < b.Length; i++)
            
                for (int j = 0; j < a.Length; j++)

您正在为 b 中的每个值循环 a。那么当有多个相同的值时,您的代码将无法处理。 即 b = 1,1,2,3,4; a=1,2,3,4,5 这将为您的代码返回 true,这显然是不正确的。

而且,这条线真的很糟糕:

if (Math.Sqrt(b[i]) == a[j])

那该怎么办?这很简单。

    计算字典中的每个数组,但计算方式不同。
      计算 a 时,将其平方,然后计算平方值。字典键 = a[i]*a[i];字典值 += 1; 计算 b 时,按原样计算。字典键 = b;字典值 -= 1;
    验证您的字典是否为空/0 已填充。

在 Java 中,这变成:

Map<Long, Integer> count = new HashMap<>();
for (int av : a)

    long av2 = ((long) av) * av;
    map.put(av2, map.getOrDefault(av2, 0) + 1);


for (int bv : b)

    map.put(bv, map.getOrDefault(bv, 0) - 1);


boolean isEqual = true;
for (long k : count.keySet())

    isEqual &= map.get(k) == 0;

用map代替字典,用map上的方法代替字典上的方法,你就有了c#代码。

【讨论】:

我不懂java,但是long av2 = av * av;`真的能避免溢出吗?看起来它只会在 int 乘法溢出后才转换为 long。 好吧,长期存在的目的是为了避免溢出,但尚未对其进行测试。它可能需要 long av2 = ((long) av) * av... 很可能它确实需要它【参考方案2】:

注意描述的最后一部分,regardless of the order。这表明您不能假设平方值与其源的索引相同。在这方面我会首先尝试对两个数组进行排序。

【讨论】:

【参考方案3】:
            if (a == null || b == null)
                return false;
            for (int i = 0; i < b.Length; i++)
                for (int j = 0; j < a.Length; j++)

因此,您正在测试 b[] 中的所有值是否“匹配”a[] 中的至少一个值。但是 a[] 中的任何值与 b[] 中的任何值都不匹配吗?如果数组的长度不同怎么办?还是有重复值?

Math.Sqrt(b[i])

Sqrt 比a[i]^2 慢,加上返回值是一个不能准确表示所有整数的双精度数。那么a[]中的负值呢?

【讨论】:

double 可以表示所有java整数。 (double 有 52 或 53 位有效位,而 java int 是 32 位)。 但是Math.Sqrt 是否计算出足够有效数字的答案,直到Sqrt(int.MaxValue)?我不知道。我仍然不会打扰,特别是当有一个更简单的替代方案也可以处理a&lt;0

以上是关于它们是“相同”的 CodeWars。我的代码没有通过所有测试的主要内容,如果未能解决你的问题,请参考以下文章

从 list-codewars 问题中查找单词的 Anagrams

.emacs 代码来识别操作系统?

codewars另一个可以锻炼代码编程能力的网站

codewars另一个可以锻炼代码编程能力的网站

codewars-random

java构造函数