练习 - 从方法返回数组

已完成

在开发应用程序时,你经常需要生成和修改数据集。 方法可用于对数据执行操作,它们是用于自行生成数据集的特别强大的工具。 开发用于创建表示数据集的数组的方法有助于使代码可重用、保持井井有条和简化。 在本练习中,你将练习从方法返回数组。

查找硬币进行找零

假设你有一些不同面值的硬币。 你的任务是找到总和等于目标值的两个硬币。 在本练习中,可用的硬币用整数数组表示。 你需要在新数组中返回两个硬币的索引。 让我们开始吧!

  1. 在 Visual Studio Code 编辑器中,删除前面练习中的任何现有代码。

  2. 在 Visual Studio Code 编辑器中输入以下代码:

    int[] TwoCoins(int[] coins, int target) 
    {
        return  new int[0];
    }
    

    在没有找到两个硬币的情况下,方法将返回一个空数组。 花点时间来考虑返回结果的语法。 虽然可以创建一个变量来存储新的 int[] 数组并返回该变量,但 return 语句使你能够同时创建和返回值。

  3. 可以通过多种方法解决此问题。 花点时间来考虑如何在一个数组中搜索两个总和等于给定值的数。

    在本练习中,将使用以下方法:

    1. 从数组中选择一个数
    2. 每次检查一个剩余的数字,看看它们加起来是否等于目标值
    3. 找到匹配项后立即返回结果
  4. 要检查数组中的每个数字,请使用以下代码更新 TwoCoins 方法:

    int[] TwoCoins(int[] coins, int target) 
    {
        for (int curr = 0; curr < coins.Length; curr++) 
        {
            for (int next = curr + 1; next < coins.Length; next++) 
            {
    
            }
        }
    
        return  new int[0];
    }
    

    这里,curr 代表一个固定的硬币索引,next 代表后续的硬币索引。 你将尝试将每个 next 硬币与固定的 curr 硬币相加,看看它们是否等于目标值。

  5. 接下来,添加逻辑以检查两个硬币之和是否等于目标值。 为此,请使用以下代码更新之前的 for 循环:

    for (int curr = 0; curr < coins.Length; curr++) 
    {
        for (int next = curr + 1; next < coins.Length; next++) 
        {
            if (coins[curr] + coins[next] == target) 
            {
                return new int[]{curr, next};
            }
    
        }
    }
    

    在此代码中,你将检查数组中 currnext 处的值之和是否等于目标值。 如果总和相等,你将创建一个数组来存储这些索引并返回它。 如果不相等,则可以忽略它们并继续检查。

测试解决方案

在此步骤中,你将测试代码以确保其正常运行。 首先,你将初始化一些变量来存储输入数据,然后调用该方法并打印结果。

  1. TwoCoins 方法签名上方创建一个新的空白代码行。 然后输入以下代码:

    int target = 60;
    int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5};
    int[] result = TwoCoins(coins, target);
    

    回想一下,如果未找到零钱,TwoCoins 方法将返回一个空数组。 在尝试打印 result 数组之前,需要检查数组大小。

  2. 输入新的空白代码行。 然后输入以下代码:

    if (result.Length == 0) 
    {
        Console.WriteLine("No two coins make change");
    } 
    else 
    {
        Console.WriteLine($"Change found at positions {result[0]} and {result[1]}");
    }
    
  3. 如有必要,打开 Visual Studio Code 的集成终端面板。

  4. 在终端命令提示符处,输入 dotnet run。 将输出与以下内容进行比较:

    Change found at positions 2 and 5
    

    如果代码显示意外结果,则需要查看代码以查找错误并进行更新。 再次运行代码以查看是否已解决问题。 继续更新并运行代码,直到代码生成预期结果。

找到多对用于找零的硬币

在此步骤中,你将扩展 TwoCoins 方法以查找总和等于目标值的更多硬币对。 在本练习中,最多可以找到五对。 这意味着返回类型将是 2D 数组而不是 1D 数组,你需要修改代码返回结果的方式。 让我们开始吧!

  1. 将方法签名中的返回类型从 int[] 更改为 int[,],方法是将代码更新为以下内容:

    int[,] TwoCoins(int[] coins, int target)
    

    接下来,你将创建一个 int[,] 数组来存储和返回结果,并创建一个计数器变量来跟踪添加到该数组的硬币对的数量。

  2. 使用以下代码更新 TwoCoins 方法:

    int[,] TwoCoins(int[] coins, int target) 
    {
        int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        int count = 0;
    

    请注意,你将结果数组元素初始化了为 -1。 这对你在以后想要打印找到的硬币对时起到帮助作用。

    接下来,你将使用 result 数组存储找到的每个硬币对,而不是返回第一个匹配项。

  3. 使用以下代码更新 TwoCoins 方法:

    int[,] TwoCoins(int[] coins, int target) 
    {
        int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        int count = 0;
    
        for (int curr = 0; curr < coins.Length; curr++) 
        {
            for (int next = curr + 1; next < coins.Length; next++) 
            {
                if (coins[curr] + coins[next] == target) 
                {
                    result[count, 0] = curr;
                    result[count, 1] = next;
                    count++;
                }
    
            }
        }
    

    请注意,每次将一硬币对添加到数组时,count 都会递增。 如果找到超过五对,这可能会导致索引超出界限的错误。 为防止此错误,可以添加代码来检查 count 的值并返回填充 result 数组的结果。

  4. 使用以下代码更新 TwoCoins 方法中的逻辑:

    for (int next = curr + 1; next < coins.Length; next++) 
    {
        if (coins[curr] + coins[next] == target) 
        {
            result[count, 0] = curr;
            result[count, 1] = next;
            count++;
        }
        if (count == result.GetLength(0)) 
        {
            return result;
        }
    }
    

    最后,如果根本没有找到匹配项,或者找到的匹配项少于五个,你需要更新最终的返回语句以返回正确的结果。

  5. 导航到 return 方法中的 TwoCoins 语句。 修改 return 语句以匹配以下代码:

    if (count == 0) 
    {
        return new int[0,0];
    }
    return result;
    

    还可以使用三元运算符缩短此返回代码,如下所示:

    return (count == 0) ? new int[0,0] : result;
    

    重要

    return 关键字的灵活性使你能够返回表达式的值,前提是结果与方法的指定返回类型匹配。

  6. 此时,TwoCoins 方法应匹配以下代码:

    int[,] TwoCoins(int[] coins, int target) 
    {
        int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        int count = 0;
    
        for (int curr = 0; curr < coins.Length; curr++) 
        {
            for (int next = curr + 1; next < coins.Length; next++) 
            {
                if (coins[curr] + coins[next] == target) 
                {
                    result[count, 0] = curr;
                    result[count, 1] = next;
                    count++;
                }
                if (count == result.GetLength(0)) 
                {
                    return result;
                }
            }
        }
        return (count == 0) ? new int[0,0] : result;
    }
    

捕获新的返回数组

你的方法正返回一个 2D 数组,可以更新代码以检索和打印结果了。 由于结果数组元素被初始化为 -1,因此,可以添加检查以打印所有硬币对,直到找到 -1 值为止。

  1. 导航到定义 target 变量的程序的开头。 按如下所示修改代码:

    int target = 30;
    int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5};
    int[,] result = TwoCoins(coins, target);
    

    接下来,将更新对 Console.WriteLine 的调用以正确打印 result 值。

  2. 导航到 Console.WriteLine 调用。 更新代码以匹配以下内容:

    if (result.Length == 0) 
    {
        Console.WriteLine("No two coins make change");
    } 
    else 
    {
        Console.WriteLine("Change found at positions:");
        for (int i = 0; i < result.GetLength(0); i++) 
        {
            if (result[i,0] == -1) 
            {
                break;
            }
            Console.WriteLine($"{result[i,0]},{result[i,1]}");
        }
    }
    

    在这里,可以按原样保留空数组的检查,并在 for 循环中打印 2D 数组的值。 找到 -1 值时,将跳出循环,因为没有下一对了。

检查你的工作

在此任务中,从集成终端运行应用程序,并验证代码是否正常工作。 现在就开始吧。

  1. 将代码与以下内容进行比较,确保其正确:

    int target = 30;
    int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5};
    int[,] result = TwoCoins(coins, target);
    
    if (result.Length == 0) 
    {
        Console.WriteLine("No two coins make change");
    } 
    else 
    {
        Console.WriteLine("Change found at positions:");
        for (int i = 0; i < result.GetLength(0); i++) 
        {
            if (result[i,0] == -1) 
            {
                break;
            }
            Console.WriteLine($"{result[i,0]},{result[i,1]}");
        }
    }
    
    int[,] TwoCoins(int[] coins, int target) 
    {
        int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
        int count = 0;
    
        for (int curr = 0; curr < coins.Length; curr++) 
        {
            for (int next = curr + 1; next < coins.Length; next++) 
            {    
                if (coins[curr] + coins[next] == target) 
                {
                    result[count, 0] = curr;
                    result[count, 1] = next;
                    count++;
                }
                if (count == result.GetLength(0)) 
                {
                    return result;
                }
            }
        }
        return (count == 0) ? new int[0,0] : result;
    }
    
  2. 使用 Ctrl + S 或使用 Visual Studio Code 文件菜单保存工作。

  3. 如有必要,打开 Visual Studio Code 的集成终端面板。

    在“资源管理器”面板中,若要在 TestProject 文件夹位置打开终端,请右键单击“TestProject”,然后选择“在集成终端中打开”。

  4. 在终端命令提示符处,输入 dotnet run

  5. 验证代码是否生成以下输出:

    Change found at positions:
    0,3
    0,4
    1,3
    1,4
    3,6
    

    如果代码显示不同的结果,则需要查看代码以查找错误并进行更新。 再次运行代码以查看是否已解决问题。 继续更新并运行代码,直到代码生成预期结果。

  6. 接下来,将 target 的值更新为 80 的值:

    int target = 80;
    
  7. 保存工作,然后在终端命令提示符下输入 dotnet run

  8. 要验证代码是否按预期工作,请将应用程序的输出与以下输出进行比较:

    No two coins make change
    

    如果代码显示不同的结果,则需要查看代码以查找错误并进行更新。 再次运行代码以查看是否已解决问题。 继续更新并运行代码,直到代码生成预期结果。