演習 - メソッドから配列を返す

完了

アプリケーションを開発する際、多くの場合、データ セットを構築して変更する必要があります。 メソッドは、データに対して操作を実行するのに役立ち、特にデータ セット自体を構築するための強力なツールです。 データ セットを表す配列を作成するメソッドを開発すると、コードを再利用でき、整理しやすく、シンプルにすることができます。 この演習では、メソッドから配列を返す練習を行います。

両替する硬貨を見つける

金額の異なる硬貨を数枚持っているとします。 合計が両替後の金額と等しくなる 2 枚の硬貨を見つける必要があります。 この演習では、使用できる硬貨を整数の配列で表します。 2 枚の硬貨のインデックスを新しい配列で返す必要があります。 それでは始めましょう。

  1. Visual Studio Code エディターで、前の演習の既存のコードを削除します。

  2. Visual Studio Code エディターに次のコードを入力します。

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

    メソッドでは、2 枚の硬貨が見つからない場合、空の配列を返します。 返される結果の構文について考えてみましょう。 新しい int[] 配列を格納する変数を作成できますが、return ステートメントを使用すると、値を作成すると同時に返すことができます。

  3. この問題を解決するには、多くの方法があります。 合計が特定の値に等しい配列内の 2 つの数値を検索する方法を考えてみましょう。

    この演習では、次の方法を使用します。

    1. 配列から 1 つの数値を選択する
    2. 他の数値を一度に 1 つずつ確認して、それらが目標値に達するかどうかを確認する
    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 は硬貨の 1 つの固定インデックスを表し、next は硬貨の後続のインデックスを表します。 各 next 硬貨を固定の curr 硬貨に追加して、それらが目標値と等しいかどうかを確認します。

  5. 次に、2 枚の硬貨の合計が目標値かどうかを確認するロジックを追加します。 このためには、前の 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 メソッドを拡張して、合計が目標値に等しい硬貨のペアをさらに見つけます。 この演習では、最大 5 つのペアを見つけます。 つまり、戻り値の型は 1D 配列ではなく 2D 配列になり、コードによって結果が返される方法を変更する必要があります。 それでは始めましょう。

  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 が増分されることに注意してください。 これにより、5 組を超えるペアが見つかった場合、インデックス範囲外エラーが発生する可能性があります。 このエラーを回避するには、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 ステートメントを更新する必要があります。

  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
    

    コードによって表示される結果が異なる場合は、コードを確認し、エラーを見つけて更新する必要があります。 コードをもう一度実行して、問題が解決しているどうかを確認します。 想定される結果がコードによって生成されるまで、コードの更新と実行を続けます。