0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java研修】新入社員向けコーディング問題⑥ 文字列操作(String)編

0
Last updated at Posted at 2026-02-15

はじめに

Java研修コーディング問題集の第6回は 文字列操作(String) です。

Javaでは文字列操作は最も頻繁に行う処理の一つです。Stringクラスの主要メソッドを使いこなせるようにしましょう。

難易度の見方

マーク 難易度 目安
基本 研修1週目レベル
⭐⭐ 応用 少し考える必要あり
⭐⭐⭐ チャレンジ 複数の知識を組み合わせる

問題1:文字列の基本操作 ⭐

問題

文字列 "Hello, Java World!" に対して以下の操作を行い、結果を出力してください。

  1. 文字列の長さ
  2. 大文字に変換
  3. 小文字に変換
  4. 7文字目以降を取得(substring
  5. 先頭の文字を取得(charAt

期待する出力

元の文字列: Hello, Java World!
長さ: 18
大文字: HELLO, JAVA WORLD!
小文字: hello, java world!
7文字目以降: Java World!
先頭の文字: H
模範解答
public class Exercise01 {
    public static void main(String[] args) {
        String str = "Hello, Java World!";

        System.out.println("元の文字列: " + str);
        System.out.println("長さ: " + str.length());
        System.out.println("大文字: " + str.toUpperCase());
        System.out.println("小文字: " + str.toLowerCase());
        System.out.println("7文字目以降: " + str.substring(7));
        System.out.println("先頭の文字: " + str.charAt(0));
    }
}

ポイント: Stringは**イミュータブル(不変)**です。toUpperCase() などのメソッドは元の文字列を変更せず、新しい文字列を返します。インデックスは 0始まり です。


問題2:文字列の比較 ⭐

問題

以下の文字列比較の結果を予想してから、実際に実行して確認してください。

String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
String s4 = "hello";

比較内容:

  1. s1 == s2
  2. s1 == s3
  3. s1.equals(s3)
  4. s1.equals(s4)
  5. s1.equalsIgnoreCase(s4)

期待する出力

s1 == s2 : true
s1 == s3 : false
s1.equals(s3) : true
s1.equals(s4) : false
s1.equalsIgnoreCase(s4) : true
模範解答
public class Exercise02 {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = new String("Hello");
        String s4 = "hello";

        System.out.println("s1 == s2 : " + (s1 == s2));
        System.out.println("s1 == s3 : " + (s1 == s3));
        System.out.println("s1.equals(s3) : " + s1.equals(s3));
        System.out.println("s1.equals(s4) : " + s1.equals(s4));
        System.out.println("s1.equalsIgnoreCase(s4) : " + s1.equalsIgnoreCase(s4));
    }
}

ポイント: ==参照(アドレス)の比較.equals()内容の比較です。文字列リテラル同士は文字列プール(String Pool)で共有されるため s1 == s2true ですが、new String() で作成すると別オブジェクトになります。文字列の内容比較には必ず .equals() を使いましょう。


問題3:文字列の検索と判定 ⭐

問題

文字列 "Java Programming Language" に対して以下の検索・判定を行ってください。

期待する出力

元の文字列: Java Programming Language
"Program" を含む: true
"python" を含む: false
"Java" で始まる: true
"Language" で終わる: true
"gram" の位置: 10
空白の位置(最初): 4
空白の位置(最後): 16
模範解答
public class Exercise03 {
    public static void main(String[] args) {
        String str = "Java Programming Language";

        System.out.println("元の文字列: " + str);
        System.out.println("\"Program\" を含む: " + str.contains("Program"));
        System.out.println("\"python\" を含む: " + str.contains("python"));
        System.out.println("\"Java\" で始まる: " + str.startsWith("Java"));
        System.out.println("\"Language\" で終わる: " + str.endsWith("Language"));
        System.out.println("\"gram\" の位置: " + str.indexOf("gram"));
        System.out.println("空白の位置(最初): " + str.indexOf(" "));
        System.out.println("空白の位置(最後): " + str.lastIndexOf(" "));
    }
}

ポイント: contains() は大文字小文字を区別します。indexOf() は見つからない場合に -1 を返します。これらのメソッドは入力値のバリデーションや文字列解析で頻繁に使います。


問題4:文字列の分割と結合 ⭐⭐

問題

CSV形式の文字列 "田中,25,東京,エンジニア" を分割して整形し、再度別の区切り文字で結合してください。

期待する出力

=== CSV解析 ===
元のデータ: 田中,25,東京,エンジニア
---
名前: 田中
年齢: 25
住所: 東京
職業: エンジニア
---
タブ区切り: 田中	25	東京	エンジニア
パイプ区切り: 田中 | 25 | 東京 | エンジニア
模範解答
public class Exercise04 {
    public static void main(String[] args) {
        String csv = "田中,25,東京,エンジニア";

        System.out.println("=== CSV解析 ===");
        System.out.println("元のデータ: " + csv);
        System.out.println("---");

        String[] parts = csv.split(",");
        String[] labels = {"名前", "年齢", "住所", "職業"};

        for (int i = 0; i < parts.length; i++) {
            System.out.println(labels[i] + ": " + parts[i]);
        }

        System.out.println("---");
        System.out.println("タブ区切り: " + String.join("\t", parts));
        System.out.println("パイプ区切り: " + String.join(" | ", parts));
    }
}

ポイント: split() は正規表現で文字列を分割し配列を返します。String.join() は区切り文字で配列を結合します。CSV解析は実務でよく行う処理です。split("\\.") のように正規表現の特殊文字はエスケープが必要です。


問題5:文字列の置換とトリム ⭐⭐

問題

以下の文字列を処理してください。

  1. " Hello, World! " → 前後の空白を除去(trim
  2. "2024-01-15"/ 区切りに変換
  3. "I like Java. Java is great. Java!""Java""Python" に全置換
  4. "abc123def456" → 数字をすべて除去(正規表現)

期待する出力

1. trim: [Hello,  World!]
2. 区切り変換: 2024/01/15
3. 全置換: I like Python. Python is great. Python!
4. 数字除去: abcdef
模範解答
public class Exercise05 {
    public static void main(String[] args) {
        // 1. trim
        String padded = "   Hello,  World!   ";
        System.out.println("1. trim: [" + padded.trim() + "]");

        // 2. 区切り変換
        String date = "2024-01-15";
        System.out.println("2. 区切り変換: " + date.replace("-", "/"));

        // 3. 全置換
        String sentence = "I like Java. Java is great. Java!";
        System.out.println("3. 全置換: " + sentence.replace("Java", "Python"));

        // 4. 数字除去(正規表現)
        String mixed = "abc123def456";
        System.out.println("4. 数字除去: " + mixed.replaceAll("[0-9]", ""));
    }
}

ポイント: replace() はリテラル文字列の置換、replaceAll() は正規表現での置換です。trim() は前後の空白のみ除去し、途中の空白はそのままです。Java 11以降では strip() メソッドも利用できます。


問題6:文字列の逆転 ⭐⭐

問題

文字列を逆順にするメソッドを2つの方法で実装してください。

  1. ループを使う方法
  2. StringBuilder を使う方法

文字列 "Java Programming" を逆転させてください。

期待する出力

元の文字列: Java Programming
方法1(ループ): gnimmargorP avaJ
方法2(StringBuilder): gnimmargorP avaJ
模範解答
public class Exercise06 {
    public static void main(String[] args) {
        String str = "Java Programming";

        System.out.println("元の文字列: " + str);
        System.out.println("方法1(ループ): " + reverseByLoop(str));
        System.out.println("方法2(StringBuilder): " + reverseByBuilder(str));
    }

    static String reverseByLoop(String str) {
        String result = "";
        for (int i = str.length() - 1; i >= 0; i--) {
            result += str.charAt(i);
        }
        return result;
    }

    static String reverseByBuilder(String str) {
        return new StringBuilder(str).reverse().toString();
    }
}

ポイント: ループ版は += で文字列を結合するたびに新しいStringオブジェクトが作られるため効率が悪いです。StringBuilder は内部バッファを変更するため高速です。実務では StringBuilder を使いましょう。


問題7:回文チェック ⭐⭐

問題

入力された文字列が回文(前から読んでも後ろから読んでも同じ)かどうかを判定するメソッドを作成してください。大文字小文字は区別しないものとします。

期待する出力

"level" → 回文です
"Java" → 回文ではありません
"Madam" → 回文です
"racecar" → 回文です
"12321" → 回文です
模範解答
public class Exercise07 {
    public static void main(String[] args) {
        String[] words = {"level", "Java", "Madam", "racecar", "12321"};

        for (String word : words) {
            String result = isPalindrome(word) ? "回文です" : "回文ではありません";
            System.out.println("\"" + word + "\" → " + result);
        }
    }

    static boolean isPalindrome(String str) {
        String lower = str.toLowerCase();
        int left = 0;
        int right = lower.length() - 1;

        while (left < right) {
            if (lower.charAt(left) != lower.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

ポイント: 両端から中央に向かって比較する ツーポインタ法 を使っています。先頭と末尾から1文字ずつ比較し、すべて一致すれば回文です。大文字小文字を無視するために toLowerCase() で統一しています。


問題8:文字の出現回数カウント ⭐⭐

問題

文字列 "programming" に含まれる各文字の出現回数をカウントして、出現回数順(多い順)に出力してください。

期待する出力

文字列: programming
--- 出現回数 ---
g: 2回
r: 2回
m: 2回
p: 1回
o: 1回
a: 1回
i: 1回
n: 1回
模範解答
public class Exercise08 {
    public static void main(String[] args) {
        String str = "programming";
        System.out.println("文字列: " + str);
        System.out.println("--- 出現回数 ---");

        // 出現する文字を記録(重複なし)
        String checked = "";
        // 文字と回数を配列で管理
        char[] chars = new char[str.length()];
        int[] counts = new int[str.length()];
        int uniqueCount = 0;

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (checked.indexOf(c) == -1) {
                chars[uniqueCount] = c;
                int count = 0;
                for (int j = 0; j < str.length(); j++) {
                    if (str.charAt(j) == c) count++;
                }
                counts[uniqueCount] = count;
                uniqueCount++;
                checked += c;
            }
        }

        // 出現回数順にソート(バブルソート)
        for (int i = 0; i < uniqueCount - 1; i++) {
            for (int j = 0; j < uniqueCount - 1 - i; j++) {
                if (counts[j] < counts[j + 1]) {
                    int tmpCount = counts[j];
                    counts[j] = counts[j + 1];
                    counts[j + 1] = tmpCount;
                    char tmpChar = chars[j];
                    chars[j] = chars[j + 1];
                    chars[j + 1] = tmpChar;
                }
            }
        }

        for (int i = 0; i < uniqueCount; i++) {
            System.out.println(chars[i] + ": " + counts[i] + "回");
        }
    }
}

ポイント: 配列だけで文字の出現回数を管理しています。後の回で学ぶ HashMap を使えばもっと簡潔に書けますが、ここではデータ構造の基礎を学ぶため配列で実装しています。


問題9:簡易テンプレートエンジン ⭐⭐⭐

問題

テンプレート文字列中の {変数名} を実際の値に置換する簡易テンプレートエンジンを作成してください。

期待する出力

=== テンプレート ===
{name}様

いつもご利用ありがとうございます。
{date}付けで{product}のご注文を承りました。
合計金額は{price}円です。

=== 変換後 ===
田中太郎様

いつもご利用ありがとうございます。
2024年4月1日付けでノートPCのご注文を承りました。
合計金額は98000円です。
模範解答
public class Exercise09 {
    public static void main(String[] args) {
        String template = "{name}様\n\n"
            + "いつもご利用ありがとうございます。\n"
            + "{date}付けで{product}のご注文を承りました。\n"
            + "合計金額は{price}円です。";

        String[] keys = {"name", "date", "product", "price"};
        String[] values = {"田中太郎", "2024年4月1日", "ノートPC", "98000"};

        System.out.println("=== テンプレート ===");
        System.out.println(template);

        String result = applyTemplate(template, keys, values);

        System.out.println("\n=== 変換後 ===");
        System.out.println(result);
    }

    static String applyTemplate(String template, String[] keys, String[] values) {
        String result = template;
        for (int i = 0; i < keys.length; i++) {
            result = result.replace("{" + keys[i] + "}", values[i]);
        }
        return result;
    }
}

ポイント: テンプレートエンジンはWebアプリケーションやメール送信でよく使われるパターンです。replace() はすべての一致箇所を置換します。実務では Thymeleaf などのテンプレートエンジンを使いますが、基本的な考え方は同じです。


問題10:パスワード強度チェッカー ⭐⭐⭐

問題

パスワードの強度を判定するメソッドを作成してください。

判定基準:

  • 8文字以上か
  • 大文字を含むか
  • 小文字を含むか
  • 数字を含むか
  • 特殊文字(!@#$%^&*)を含むか

強度レベル:

  • 5つすべて満たす → 「非常に強い」
  • 4つ満たす → 「強い」
  • 3つ満たす → 「普通」
  • 2つ以下 → 「弱い」

期待する出力

=== パスワード強度チェック ===
"abc" → 弱い(1/5)
  [ ] 8文字以上  [✓] 小文字  [ ] 大文字  [ ] 数字  [ ] 特殊文字

"password" → 弱い(2/5)
  [✓] 8文字以上  [✓] 小文字  [ ] 大文字  [ ] 数字  [ ] 特殊文字

"Pass1234" → 強い(4/5)
  [✓] 8文字以上  [✓] 小文字  [✓] 大文字  [✓] 数字  [ ] 特殊文字

"P@ss1234!" → 非常に強い(5/5)
  [✓] 8文字以上  [✓] 小文字  [✓] 大文字  [✓] 数字  [✓] 特殊文字
模範解答
public class Exercise10 {
    public static void main(String[] args) {
        String[] passwords = {"abc", "password", "Pass1234", "P@ss1234!"};

        System.out.println("=== パスワード強度チェック ===");

        for (String pw : passwords) {
            checkPassword(pw);
            System.out.println();
        }
    }

    static void checkPassword(String password) {
        boolean hasLength = password.length() >= 8;
        boolean hasLower = false;
        boolean hasUpper = false;
        boolean hasDigit = false;
        boolean hasSpecial = false;
        String specialChars = "!@#$%^&*";

        for (int i = 0; i < password.length(); i++) {
            char c = password.charAt(i);
            if (Character.isLowerCase(c)) hasLower = true;
            if (Character.isUpperCase(c)) hasUpper = true;
            if (Character.isDigit(c)) hasDigit = true;
            if (specialChars.indexOf(c) >= 0) hasSpecial = true;
        }

        int score = 0;
        if (hasLength) score++;
        if (hasLower) score++;
        if (hasUpper) score++;
        if (hasDigit) score++;
        if (hasSpecial) score++;

        String level;
        if (score >= 5) {
            level = "非常に強い";
        } else if (score >= 4) {
            level = "強い";
        } else if (score >= 3) {
            level = "普通";
        } else {
            level = "弱い";
        }

        System.out.println("\"" + password + "\" → " + level + "(" + score + "/5)");
        System.out.println("  " +
            mark(hasLength) + " 8文字以上  " +
            mark(hasLower) + " 小文字  " +
            mark(hasUpper) + " 大文字  " +
            mark(hasDigit) + " 数字  " +
            mark(hasSpecial) + " 特殊文字");
    }

    static String mark(boolean condition) {
        return condition ? "[✓]" : "[ ]";
    }
}

ポイント: Character.isLowerCase(), Character.isUpperCase(), Character.isDigit() などのCharacterクラスのメソッドは文字の判定に便利です。パスワード検証は実務でもよくある処理で、セキュリティの基本です。


まとめ

問題 テーマ 難易度
問題1 文字列の基本操作
問題2 文字列の比較(==とequals)
問題3 文字列の検索と判定
問題4 分割と結合(split / join) ⭐⭐
問題5 置換とトリム ⭐⭐
問題6 文字列の逆転 ⭐⭐
問題7 回文チェック ⭐⭐
問題8 文字の出現回数カウント ⭐⭐
問題9 簡易テンプレートエンジン ⭐⭐⭐
問題10 パスワード強度チェッカー ⭐⭐⭐

次回は クラスとオブジェクト のコーディング問題です!


シリーズ一覧:Java研修コーディング問題集

  1. 変数・データ型・演算子 編
  2. 条件分岐(if / switch)編
  3. 繰り返し処理(for / while)編
  4. 配列 編
  5. メソッド 編
  6. 👉 文字列操作(String)編(本記事)
  7. クラスとオブジェクト 編
  8. 継承とインターフェース 編
  9. 例外処理 編
  10. コレクションと Stream API 編

著者: @kotaro_ai_lab
AI駆動開発やテック情報を毎日発信しています。フォローお気軽にどうぞ!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?