C#: 演習:配列とメソッドの組み合わせ

1. バブルソート

目標:バブルソートアルゴリズムを実装し、整数配列を昇順に並べ替え、ソート前後の結果を表示する。

要件

▶ サンプル

CSHARP
int[] numbers = { 64, 34, 25, 12, 22, 11, 90, 5 };

Console.WriteLine("Before sorting: " + string.Join(", ", numbers));

int swapCount = 0;

for (int i = 0; i < numbers.Length - 1; i++)
{
    bool swapped = false;
    for (int j = 0; j < numbers.Length - 1 - i; j++)
    {
        if (numbers[j] > numbers[j + 1])
        {
            (numbers[j], numbers[j + 1]) = (numbers[j + 1], numbers[j]);
            swapped = true;
            swapCount++;
        }
    }
    if (!swapped) break;
}

Console.WriteLine("After sorting: " + string.Join(", ", numbers));
Console.WriteLine($"Swap count: {swapCount}");
▶ 試してみよう
TEXT 📖 参照専用
Before sorting: 64, 34, 25, 12, 22, 11, 90, 5
After sorting: 5, 11, 12, 22, 25, 34, 64, 90
Swap count: 20

2. 生徒の得点統計

目標:配列を使用して生徒の得点を格納し、メソッドを用いて平均点、最高点、最低点、および平均点以上の生徒の人数を算出する。

要件

▶ サンプル

CSHARP
int[] scores = { 85, 92, 78, 60, 95, 88, 72, 66, 91, 83 };

double average = CalcAverage(scores);
int max = CalcMax(scores);
int min = CalcMin(scores);
int aboveAvg = CountAbove(scores, average);

Console.WriteLine($"Score list: {string.Join(", ", scores)}");
Console.WriteLine($"Average: {average:F1}");
Console.WriteLine($"Highest: {max}");
Console.WriteLine($"Lowest: {min}");
Console.WriteLine($"Above average count: {aboveAvg}");

double CalcAverage(int[] arr)
{
    double sum = 0;
    foreach (int s in arr) sum += s;
    return sum / arr.Length;
}

int CalcMax(int[] arr)
{
    int max = arr[0];
    foreach (int s in arr) if (s > max) max = s;
    return max;
}

int CalcMin(int[] arr)
{
    int min = arr[0];
    foreach (int s in arr) if (s < min) min = s;
    return min;
}

int CountAbove(int[] arr, double threshold)
{
    int count = 0;
    foreach (int s in arr) if (s > threshold) count++;
    return count;
}
▶ 試してみよう
TEXT 📖 参照専用
Score list: 85, 92, 78, 60, 95, 88, 72, 66, 91, 83
Average: 81.0
Highest: 95
Lowest: 60
Above average count: 5

3. やることリスト

目標:文字列配列を使用して、追加、削除、表示の操作に対応したシンプルなToDoリストを実装する。

要件

▶ サンプル

CSHARP 📖 参照専用
string[] todos = new string[10];
int count = 0;

AddItem("Learn C# arrays");
AddItem("Complete exercises");
AddItem("Review methods and parameters");
ListAll();
RemoveItem(1);
ListAll();

void AddItem(string item)
{
    if (count >= todos.Length)
    {
        Console.WriteLine("⚠️ To-do list is full, cannot add.");
        return;
    }
    todos[count] = item;
    count++;
    Console.WriteLine($"Added: {item}");
}

void RemoveItem(int index)
{
    if (index < 0 || index >= count)
    {
        Console.WriteLine("⚠️ Invalid index, removal failed.");
        return;
    }
    string removed = todos[index];
    for (int i = index; i < count - 1; i++)
    {
        todos[i] = todos[i + 1];
    }
    todos[count - 1] = null;
    count--;
    Console.WriteLine($"Removed: {removed}");
}

void ListAll()
{
    Console.WriteLine("--- To-Do List ---");
    if (count == 0)
    {
        Console.WriteLine("(empty)");
        return;
    }
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine($"{i}. {todos[i]}");
    }
}
論理コード 48 行(40 行制限超過、参照専用)
TEXT 📖 参照専用
Added: Learn C# arrays
Added: Complete exercises
Added: Review methods and parameters
--- To-Do List ---
0. Learn C# arrays
1. Complete exercises
2. Review methods and parameters
Removed: Complete exercises
--- To-Do List ---
0. Learn C# arrays
1. Review methods and parameters

4. 簡易テキスト解析ツール

目標:入力テキストに対して単語の出現頻度分析を行い、StringBuilder を使用して結果を連結し、分析関数をメソッドにカプセル化する。

要件

▶ サンプル

CSHARP
string text = "CSharp is a powerful programming language and programming is fun";

int wordCount = CountWords(text);
int charCount = CountChars(text);
string longest = FindLongestWord(text);

var report = BuildReport(text, wordCount, charCount, longest);
Console.WriteLine(report);

int CountWords(string input)
{
    if (string.IsNullOrWhiteSpace(input)) return 0;
    string[] words = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
    return words.Length;
}

int CountChars(string input)
{
    return input.Length;
}

string FindLongestWord(string input)
{
    if (string.IsNullOrWhiteSpace(input)) return "";
    string[] words = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
    string longest = words[0];
    foreach (string w in words)
    {
        if (w.Length > longest.Length) longest = w;
    }
    return longest;
}

StringBuilder BuildReport(string input, int words, int chars, string longestWord)
{
    var sb = new StringBuilder();
    sb.AppendLine("===== Text Analysis Report =====");
    sb.AppendLine($"Original: {input}");
    sb.AppendLine($"Word count: {words}");
    sb.AppendLine($"Character count: {chars}");
    sb.AppendLine($"Longest word: {longestWord} ({longestWord.Length} chars)");
    sb.Append("===== Analysis Complete =====");
    return sb;
}
▶ 試してみよう
TEXT 📖 参照専用
===== Text Analysis Report =====
Original: CSharp is a powerful programming language and programming is fun
Word count: 10
Character count: 60
Longest word: programming (11 chars)
===== Analysis Complete =====

❓ よくある質問

Q バブルソートにおいて、if (!swapped) breakはどのような役割を果たしますか?
A 1回のパスで入れ替えが発生しなければ、配列はすでにソート済みです。早期に処理を終了させることで、不要な反復を避け、時間を節約できます。
Q ToDoリストから要素を削除した後、なぜ配列を前方へずらす必要があるのですか?
A 配列は連続した領域に格納されます。中央の要素を削除した後、その後に続く要素を前方へずらして空きを埋める必要があります。そうしないと、空白の領域ができてしまいます。
Q StringBuilderと、+を使った文字列の連結との違いは何ですか?
A StringBuilderはメモリ内の同じバッファを再利用するため、連結のたびに新しい文字列オブジェクトが作成されるのを防ぎます。連結回数が多くなるほど、パフォーマンスが向上します。
Q StringSplitOptions.RemoveEmptyEntriesはどのような働きをしますか?
A デフォルトでは、Split は空の文字列エントリを保持します。このオプションを追加すると、連続する区切り文字によって生成された空の項目が自動的に削除されます。

📖 まとめ

📝 練習問題

  1. バブルソートを修正して降順で並べ替え、各パス終了後に中間結果を出力するようにする
  2. 学生の得点統計に、不合格(60未満)のすべての得点のインデックスのリストを返すメソッドを追加する
  3. ToDoリストに「完了マーク」機能を追加する。完了した項目には、先頭に[✓]と表示されるようにする
  4. テキストアナライザーに単語出現頻度の集計機能を追加し、各単語の出現回数を出力するようにする
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%