StringBuilder APIの基本操作
主要なStringBuilderメソッド
append(String str):文字列を末尾に追加します。insert(int offset, String str):指定位置に文字列を挿入します。delete(int start, int end):指定範囲の文字を削除します。deleteCharAt(int index):指定位置の文字を削除します。reverse():文字列を反転します。toString():StringBuilderをStringに変換します。setCharAt(int index, char ch):指定位置の文字を設定します。charAt(int index):指定位置の文字を取得します。length():文字列の長さを返します。substring(int start, int end):指定範囲の部分文字列を返します。
サンプルコード
public class StringManipulator {
public static void main(String[] args) {
// StringBuilderインスタンスの作成
StringBuilder builder = new StringBuilder("こんにちは");
// append()メソッド:末尾に文字列を追加
builder.append(" 世界");
System.out.println("追加後: " + builder.toString()); // 出力: "こんにちは 世界"
// insert()メソッド:指定位置に文字列を挿入
builder.insert(5, " Java");
System.out.println("挿入後: " + builder.toString()); // 出力: "こんにちは Java 世界"
// delete()メソッド:指定範囲の文字を削除
builder.delete(5, 10);
System.out.println("削除後: " + builder.toString()); // 出力: "こんにちは 世界"
// deleteCharAt()メソッド:指定位置の文字を削除
builder.deleteCharAt(5);
System.out.println("文字削除後: " + builder.toString()); // 出力: "こんにちは世界"
// reverse()メソッド:文字列を反転
builder.reverse();
System.out.println("反転後: " + builder.toString()); // 出力: "界世 はちにんこ"
// toString()メソッド:StringBuilderをStringに変換
String result = builder.toString();
System.out.println("String変換: " + result); // 出力: "界世 はちにんこ"
// setCharAt()メソッド:指定位置の文字を設定
builder.setCharAt(0, '界');
System.out.println("文字設定後: " + builder.toString()); // 出力: "界世 はちにんこ"
// charAt()メソッド:指定位置の文字を取得
char character = builder.charAt(1);
System.out.println("インデックス1の文字: " + character); // 出力: "世"
// length()メソッド:文字列の長さを取得
int size = builder.length();
System.out.println("長さ: " + size); // 出力: 10
// substring()メソッド:部分文字列を取得
String portion = builder.substring(0, 5);
System.out.println("部分文字列 (0, 5): " + portion); // 出力: "界世 は"
}
}
各メソッドの説明
append(String str):
- 文字列
strをStringBuilderの末尾に追加します。
builder.append(" 世界"); // "こんにちは 世界"
insert(int offset, String str):
- 指定位置
offsetに文字列strを挿入します。
builder.insert(5, " Java"); // "こんにちは Java 世界"
delete(int start, int end):
startからendまでの文字を削除します。
builder.delete(5, 10); // "こんにちは 世界"
deleteCharAt(int index):
- 指定位置
indexの文字を削除します。
builder.deleteCharAt(5); // "こんにちは世界"
reverse():
- 文字列を反転します。
builder.reverse(); // "界世 はちにんこ"
toString():
- StringBuilderをStringに変換します。
String result = builder.toString(); // "界世 はちにんこ"
setCharAt(int index, char ch):
- 指定位置
indexの文字をchに設定します。
builder.setCharAt(0, '界'); // "界世 はちにんこ"
charAt(int index):
- 指定位置
indexの文字を取得します。
char character = builder.charAt(1); // '世'
length():
- 文字列の長さを取得します。
int size = builder.length(); // 10
substring(int start, int end):
startからendまでの部分文字列を取得します。
String portion = builder.substring(0, 5); // "界世 は"
問題解決
問題分析
最初はJavaの組み込みメソッドを使用していましたが、実行時間とメモリ使用量が最適ではなかったため、より効率的なアプローチを学び直しました。
主な戦略:
- 前後の空白と余分な空白を削除
- 全体の文字列を反転
- 個々の単語を反転(上記の関数を再利用)
最適化前:
最適化後:
ループによる回転操作は後ろから前へ進むのが最適で、そうしないとエラーが発生する可能性があります。
コード実装
問題151:単語の反転
class Solution {
public String reverseWords(String input) {
StringBuilder processed = cleanString(input);
reverseFull(processed, 0, processed.length() - 1);
reverseEachWord(processed);
return processed.toString();
}
// 前後の空白と余分な空白を削除
private StringBuilder cleanString(String text) {
int begin = 0;
int finish = text.length() - 1;
// 前後の空白を削除
while(text.charAt(begin) == ' ') begin++;
while(text.charAt(finish) == ' ') finish--;
StringBuilder builder = new StringBuilder();
while(begin <= finish){
char c = text.charAt(begin);
// 余分な空白を削除
// 1. 文字自体が空白
// 2. 文字が空白で、前の文字が空白でない
if(c != ' ' || builder.charAt(builder.length() - 1) != ' '){
builder.append(c);
}
begin++;
}
return builder;
}
// 全体の文字列を反転
private void reverseFull(StringBuilder builder, int start, int end){
while(start < end){
char temp = builder.charAt(start);
builder.setCharAt(start, builder.charAt(end));
builder.setCharAt(end, temp);
start++; end--;
}
}
// 各単語を反転
private void reverseEachWord(StringBuilder builder){
int start = 0;
int end = 1;
int n = builder.length();
while(start < n){
while(end < n && builder.charAt(end) != ' '){
end++;
}
reverseFull(builder, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
問題55:文字列の回転
import java.util.*;
public class StringRotator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 整数nを読み込む
int rotations = scanner.nextInt();
scanner.nextLine(); // 改行文字を消費
// 文字列を読み込みStringBuilderを作成
StringBuilder text = new StringBuilder(scanner.nextLine());
// 回転回数を文字列長で割った余りを計算
rotations = rotations % text.length();
// 文字列を回転
while (rotations > 0) {
char lastChar = text.charAt(text.length() - 1);
for (int i = text.length() - 1; i > 0; i--) {
text.setCharAt(i, text.charAt(i - 1));
}
text.setCharAt(0, lastChar);
rotations--;
}
// 結果を出力
System.out.println(text.toString());
}
}