substringの範囲
いまいち分かりにくい、substringの範囲について。
例えば次のプログラム。
import java.util.*; public class Main { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { String s = "abcde"; System.out.println(s.substring(1,3)); } }
文字列「”abcde”」に対してsubstring(1,3)とすると、「bc」が抜き出される。
プログラミング言語では最初の要素が0で表されるので、文字列abcdeは0~4の数字で表されることになる。つまり、1文字目は「b」であり、3文字目は「d」である。それなのにどうして「bcd」ではなく「bc」が抜き出されるのか。
まず基本的なこととして、文字列sにおいてsubstringで指定できる範囲は「0~s.length()」になる。つまり、abcdeなら0~5の範囲で指定できる。そう、abcdeは0~4の数字で表されるのに、substringでは0~5の範囲で抜き出せるのだ。いったい処理はどうなっているのか。僕が思うに、おそらく以下のような基準に基づいて抜き出している。
0 a 1 b 2 c 3 d 4 e 5
0~5までの数字が、substringで指定可能な範囲で、その間に文字列が挟まれているという具合だ。このとき、substring(1,3)とすると、1と3の間にある文字は「bc」になる。同様に、先頭の1文字を抜き出すならsubstring(0,1)になるし、末尾の1文字を抜き出すならsubstring(4,5)になる。末尾の1文字については、substring(s.length()-1,s.length())とも書ける。
判明した基準をもとにして、いくつかの例題を解き、それを確かめてみたいと思う。
【1、文字列strのn文字目を1文字抜き出す場合】
・String n = str.substring(n,n+1);
抜き出すのが1文字だけの場合、char型が使えるので、
・char n = str.charAt(n);
としても抜き出せる。
また、n文字目からm文字分抜き出したい場合は、
・String m = str.substring(n,n+m);
とすればよい。
【2、文字列を真ん中で二分する場合】
import java.util.*; public class Main { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { String a = "1113555"; //文字列の長さが奇数の場合 String b = "222444"; //文字列の長さが偶数の場合 //文字列aを左右に分割(中央の文字はスルー) String a_L = a.substring(0,a.length()/2); String a_R = a.substring(a.length()/2+1,a.length()); //文字列bを左右に分割(こっちは二分可能) String b_L = b.substring(0,b.length()/2); String b_R = b.substring(b.length()/2,b.length()); System.out.println(a_L+":"+a_R); //output = 111:555 System.out.println(b_L+":"+b_R); //output = 222:444 } }
【補足】奇数長の文字列strから中央の文字だけ抜き出す場合
・substring(str.length()/2,str.length()/2+1);
【3、先頭からn文字、末尾からn文字抜き出す場合】
import java.util.*; public class Main { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { String a = "oooxxx"; String b = "???!!!"; int n = 3; //aの先頭からn文字抜き出す String a_top = a.substring(0,n); //bの末尾からn文字抜き出す String b_last = b.substring(b.length()-n,b.length()); System.out.println(a_top); //output = ooo System.out.println(b_last); //output = !!! } }