【问题标题】:Are they the "same" CodeWars. My code doesn't pass all tests它们是“相同”的 CodeWars。我的代码没有通过所有测试
【发布时间】: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] 进行比较会便宜得多。

标签: c# arrays algorithm


【解决方案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])

那该怎么办?这很简单。

  1. 计算字典中的每个数组,但计算方式不同。
    1. 计算 a 时,将其平方,然后计算平方值。字典键 = a[i]*a[i];字典值 += 1;
    2. 计算 b 时,按原样计算。字典键 = b;字典值 -= 1;
  2. 验证您的字典是否为空/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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2021-09-25
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多