Sample.java
import java.util.HashMap;
import java.util.Map;
public class HalfKanaSample {
// 半角カナ → 全角カナ の基本変換テーブル(1文字対1文字の変換)
private static final String HALF_KANA =
"ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン";
private static final String FULL_KANA =
"ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン";
// 濁音変換テーブル(半角カナ + ゙ → 全角濁音1文字)
private static final Map<Character, Character> DAKUTEN_MAP = new HashMap<>();
// 半濁音変換テーブル(半角カナ + ゚ → 全角半濁音1文字)
private static final Map<Character, Character> HANDAKUTEN_MAP = new HashMap<>();
static {
String[] dakutenPairs = {
"カガ", "キギ", "クグ", "ケゲ", "コゴ",
"サザ", "シジ", "スズ", "セゼ", "ソゾ",
"タダ", "チヂ", "ツヅ", "テデ", "トド",
"ハバ", "ヒビ", "フブ", "ヘベ", "ホボ",
"ウヴ"
};
for (String pair : dakutenPairs) {
DAKUTEN_MAP.put(pair.charAt(0), pair.charAt(1));
}
String[] handakutenPairs = {
"ハパ", "ヒピ", "フプ", "ヘペ", "ホポ"
};
for (String pair : handakutenPairs) {
HANDAKUTEN_MAP.put(pair.charAt(0), pair.charAt(1));
}
}
/**
* 半角カナを全角カナに変換する。
* 濁音(ガ → ガ)・半濁音(パ → パ)の2文字結合も処理する。
* 変換対象外の文字(英数字・ひらがな・漢字など)はそのまま返す。
*/
public static String toFullWidth(String input) {
if (input == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
char next = (i + 1 < input.length()) ? input.charAt(i + 1) : 0;
// 濁音: 半角カナ + ゙ の2文字 → 全角濁音1文字
if (next == '゙' && DAKUTEN_MAP.containsKey(c)) {
sb.append(DAKUTEN_MAP.get(c));
i++; // ゙ をスキップ
continue;
}
// 半濁音: 半角カナ + ゚ の2文字 → 全角半濁音1文字
if (next == '゚' && HANDAKUTEN_MAP.containsKey(c)) {
sb.append(HANDAKUTEN_MAP.get(c));
i++; // ゚ をスキップ
continue;
}
// 基本変換: 半角カナ1文字 → 全角カナ1文字
int idx = HALF_KANA.indexOf(c);
if (idx >= 0) {
sb.append(FULL_KANA.charAt(idx));
} else {
sb.append(c); // 変換対象外はそのまま
}
}
return sb.toString();
}
/**
* 全角カナを半角カナに変換する。
* 濁音(ガ → ガ)・半濁音(パ → パ)は2文字に展開する。
*/
public static String toHalfWidth(String input) {
if (input == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
boolean converted = false;
// 濁音の逆変換(全角濁音 → 半角カナ + ゙)
for (Map.Entry<Character, Character> entry : DAKUTEN_MAP.entrySet()) {
if (entry.getValue() == c) {
sb.append(entry.getKey()).append('゙');
converted = true;
break;
}
}
if (converted) { continue; }
// 半濁音の逆変換(全角半濁音 → 半角カナ + ゚)
for (Map.Entry<Character, Character> entry : HANDAKUTEN_MAP.entrySet()) {
if (entry.getValue() == c) {
sb.append(entry.getKey()).append('゚');
converted = true;
break;
}
}
if (converted) { continue; }
// 基本変換(全角カナ → 半角カナ)
int idx = FULL_KANA.indexOf(c);
if (idx >= 0) {
sb.append(HALF_KANA.charAt(idx));
} else {
sb.append(c); // 変換対象外はそのまま
}
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println("【半角 → 全角】");
System.out.println(toFullWidth("カナ")); // カナ
System.out.println(toFullWidth("ガギグゲゴ")); // ガギグゲゴ(濁音)
System.out.println(toFullWidth("パピプペポ")); // パピプペポ(半濁音)
System.out.println(toFullWidth("ABC アイウ 123")); // ABC アイウ 123
System.out.println("\n【全角 → 半角】");
System.out.println(toHalfWidth("カタカナ")); // カタカナ
System.out.println(toHalfWidth("ガギグゲゴ")); // ガギグゲゴ
System.out.println(toHalfWidth("パピプペポ")); // パピプペポ
System.out.println("\n【往復変換テスト】");
String original = "ガギグゲゴ";
String full = toFullWidth(original);
String back = toHalfWidth(full);
System.out.println("往復一致: " + original.equals(back));
}
}