Skip to content

Latest commit

ย 

History

History
331 lines (249 loc) ยท 9.58 KB

StringSearch.md

File metadata and controls

331 lines (249 loc) ยท 9.58 KB

๋ฌธ์ž์—ด ํƒ์ƒ‰ (String Search)

written by sohyeon, hyemin ๐Ÿ’ก


๋ฌธ์ž์—ด ํƒ์ƒ‰

์–ด๋–ค ๋ฌธ์ž์—ด ์•ˆ์— ํƒ์ƒ‰ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฌธ์ž์—ด์ด ๋“ค์–ด ์žˆ๋Š”์ง€ ์กฐ์‚ฌํ•˜๊ณ  ๊ทธ ์œ„์น˜๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๊ฒƒ์ด๋‹ค.
ํƒ์ƒ‰ํ•  ๋ฌธ์ž์—ด์„ ํŒจํ„ด ์–ด๋–ค ๋ฌธ์ž์—ด์„ ์›๋ณธ ํ…์ŠคํŠธ๋ผ๊ณ  ํ‘œํ˜„ํ•˜๊ฒ ๋‹ค.

1. ๋ธŒ๋ฃจํŠธ-ํฌ์Šค

์„ ํ˜• ๊ฒ€์ƒ‰์„ ํ™•์žฅํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ๋ชจ๋‘ ์ง์ ‘ ํ•ด ๋ณด๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๋ฌธ์ž์—ด ํƒ์ƒ‰ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹จ์ˆœ๋ฒ•, ์†Œ๋ฐ•๋ฒ•์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค.

๋ฌธ์ž์—ด ํƒ์ƒ‰์— ๋ธŒ๋ฃจํŠธ-ํฌ์Šค๋ฅผ ์ ์šฉํ•  ๊ฒฝ์šฐ

  1. ํŒจํ„ด์„ ํ…์ŠคํŠธ์˜ ์ฒซ๋ฌธ์ž๋ถ€ํ„ฐ ๊ฒน์น˜๋Š” ํ™•์ธ

    • ๋ชจ๋“  ํŒจํ„ด์ด ์ผ์น˜ํ•  ๊ฒฝ์šฐ ํƒ์ƒ‰ ์„ฑ๊ณต
  2. ํŒจํ„ด๊ณผ ๋‹ค๋ฅธ ๋ฌธ์ž๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉด ๊ฒ€์ƒ‰์„ ์ค‘๋‹จ

  3. ํ…์ŠคํŠธ์˜ ๊ฒ€์‚ฌ ์œ„์น˜๋ฅผ 1์นธ ์˜ฎ๊ฒจ ํƒ์ƒ‰ ์ง„ํ–‰

    • ๋ชจ๋“  ํŒจํ„ด์ด ์ผ์น˜ํ•  ๊ฒฝ์šฐ ํƒ์ƒ‰ ์„ฑ๊ณต
    • ๋‹ค๋ฅธ ๋ฌธ์ž๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉด 3์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณต

์ˆ˜ํ–‰ ์‹œ๊ฐ„ ๋ฉด์—์„œ ๋น„ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ

๋ธŒ๋ฃจํŠธ-ํฌ์Šค๋ฒ•์œผ๋กœ ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ

import java.util.Scanner;

class BFmatch {
	// ๋ธŒ๋ฃจํŠธ-ํฌ์Šค๋ฒ•์œผ๋กœ ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ 
	static int bfMatch(String txt, String pat) {
		int pt = 0;		// txt ์ปค์„œ
		int pp = 0;		// pat ์ปค์„œ

		while (pt != txt.length() && pp != pat.length()) {
			if (txt.charAt(pt) == pat.charAt(pp)) {
				pt++;
				pp++;
			} else {
				pt = pt - pp + 1;
				pp = 0;
			}
		}
		if (pp == pat.length())         // ๊ฒ€์ƒ‰ ์„ฑ๊ณต!
			return pt - pp;
		return -1;                      // ๊ฒ€์ƒ‰ ์‹คํŒจ!
	}

	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

		System.out.print("ํ…์ŠคํŠธ๏ผš");
		String s1 = stdIn.next();         // ํ…์ŠคํŠธ์šฉ ๋ฌธ์ž์—ด 

		System.out.print("ํŒจํ„ด๏ผš");
		String s2 = stdIn.next();         // ํŒจํ„ด์šฉ ๋ฌธ์ž์—ด 

		int idx = bfMatch(s1, s2);         // ๋ฌธ์ž์—ด s1์—์„œ ๋ฌธ์ž์—ด s2๋ฅผ ๊ฒ€์ƒ‰

		if (idx == -1)
			System.out.println("ํ…์ŠคํŠธ์— ํŒจํ„ด์ด ์—†์Šต๋‹ˆ๋‹ค.");
		else {
			// ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž ๋ฐ”๋กœ ์•ž๊นŒ์ง€์˜ ๊ธธ์ด๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.
			int len = 0;
			for (int i = 0; i < idx; i++)
				len += s1.substring(i, i + 1).getBytes().length;
			len += s2.length();

			System.out.println((idx + 1) + "๋ฒˆ์งธ ๋ฌธ์ž๋ถ€ํ„ฐ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.");
			System.out.println("ํ…์ŠคํŠธ๏ผš" + s1);
			System.out.printf(String.format("ํŒจํ„ด๏ผš%%%ds\n", len), s2);
		}
	}
}
  • ํ…์ŠคํŠธ์—์„œ ํŒจํ„ด์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํ…์ŠคํŠธ์˜ ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ํ…์ŠคํŠธ์— ํŒจํ„ด์ด ์—ฌ๋Ÿฌ๊ฐœ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ€์žฅ ์•ž์ชฝ์— ์œ„์น˜ํ•œ ํ…์ŠคํŠธ์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ ,
    ๊ฒ€์ƒ‰์— ์‹คํŒจํ•˜๋ฉด -1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

2. KMP ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ธŒ๋ฃจํŠธ-ํฌ์Šค๋ณด๋‹ค ํšจ์œจ์ ์ด๊ฒŒ ๋ฌธ์ž์—ด์„ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
KMP๋Š” ๊ฒ€์‚ฌํ–ˆ๋˜ ์œ„์น˜ ๊ฒฐ๊ณผ๋ฅผ ํ™œ์šฉํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

KMP๋Š” ์˜ˆ์ œ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.

์˜ˆ์‹œ

ํ…์ŠคํŠธ ZABCABXACCADEF์—์„œ ํŒจํ„ด ABCABD๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ์˜ˆ์‹œ

ํŒจํ„ด์˜ ํ‘œ 
ABCABD
-00120

       0123456789
ํ…์ŠคํŠธ ZABCABXACC  
ํŒจํ„ด   ABCABD  
       x

์ฒซ๋ฒˆ์งธ ๋ฌธ์ž์™€ ํŒจํ„ด์ด ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค 1์นธ ๋’ค๋กœ ์ด๋™์‹œ์ผœ ํƒ์ƒ‰ํ•œ๋‹ค.

       0123456789
ํ…์ŠคํŠธ ZABCABXACC  
ํŒจํ„ด    ABCABD  
        ooooox  

ํŒจํ„ด์˜ D๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค. 
์œ„์˜ ํ‘œ๋ฅผ ๋ณด๋ฉด ํŒจํ„ด์— ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์ด ์กด์žฌํ•˜๋ฉฐ AB๊นŒ์ง€๋Š” ํŒจํ„ด๊ณผ ํ…์ŠคํŠธ๊ฐ€ ์ผ์น˜ํ–ˆ๋‹ค.
ํ•ด๋‹น ์ธ๋ฑ์Šค๋กœ ์ด๋™ํ•ด ํƒ์ƒ‰ํ•œ๋‹ค.

       0123456789
ํ…์ŠคํŠธ ZABCABXACC  
ํŒจํ„ด       ABCABD  
           oox  

๋”์ด์ƒ ์ด๋™ ๋ถˆ๊ฐ€ ํƒ์ƒ‰ ์‹คํŒจ

ํŒจํ„ด์„ ํ•œ์นธ์”ฉ ์ด๋™ํ•˜์ง€ ์•Š๊ณ  ํŒจํ„ด์˜ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์„ ์ฐพ์•„๋‚ด ๋‹ค์‹œ ์‹œ์ž‘ํ•  ์œ„์น˜๋ฅผ ๊ตฌํ•œ๋‹ค.
ํŒจํ„ด์„ ์ตœ์†Œํ•œ๋งŒ ์ด๋™์‹œ์ผœ ํšจ์œจ์„ ๋†’์ธ๋‹ค.
๋ช‡๋ฒˆ์งธ ๋ฌธ์ž๋ถ€ํ„ฐ ๋‹ค์‹œ ๊ฒ€์ƒ‰ํ• ์ง€ ๊ตฌํ•˜๊ธฐ ์œ„ํ•œ ํ‘œ๋ฅผ ๋งŒ๋“ค์–ด ๊ณ„์‚ฐํ•œ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ

import java.util.Scanner;
// KMP๋ฒ•์— ์˜ํ•œ ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰

class KMPmatch {
	// KMP๋ฒ•์— ์˜ํ•œ ๋ฌธ์ž์—ด ๊ฒ€์ƒ‰
	static int kmpMatch(String txt, String pat) {
		int pt = 1;                                    // txt ์ปค์„œ
		int pp = 0;                                    // pat ์ปค์„œ
		int[] skip = new int[pat.length() + 1];        // ๊ฑด๋„ˆ๋›ฐ๊ธฐ ํ‘œ

		// ๊ฑด๋„ˆ๋›ฐ๊ธฐ ํ‘œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
		skip[pt] = 0;
		while (pt != pat.length()) {
			if (pat.charAt(pt) == pat.charAt(pp))
				skip[++pt] = ++pp;
			else if (pp == 0)
				skip[++pt] = pp;
			else
				pp = skip[pp];
		}

		// ๊ฒ€์ƒ‰
		pt = pp = 0;
		while (pt != txt.length() && pp != pat.length()) {
			if (txt.charAt(pt) == pat.charAt(pp)) {
				pt++;
				pp++;
			} else if (pp == 0)
				pt++;
			else
				pp = skip[pp];
		}

		if (pp == pat.length())       // pt - pp๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
			return pt - pp;
		return -1;                    // ๊ฒ€์ƒ‰ ์‹คํŒจ
	}

	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

		System.out.print("ํ…์ŠคํŠธ๏ผš");
		String s1 = stdIn.next();                  // ํ…์ŠคํŠธ์šฉ ๋ฌธ์ž์—ด 

		System.out.print("ํŒจํ„ด๏ผš");
		String s2 = stdIn.next();                  // ํŒจํ„ด์šฉ ๋ฌธ์ž์—ด 

		int idx = kmpMatch(s1, s2);  // ๋ฌธ์ž์—ด s1์—์„œ ๋ฌธ์ž์—ด s2๋ฅผ ๋ธŒ๋ฃจํŠธ-ํฌ์Šค๋ฒ•์œผ๋กœ ๊ฒ€์ƒ‰

		if (idx == -1)
			System.out.println("ํ…์ŠคํŠธ์— ํŒจํ„ด์ด ์—†์Šต๋‹ˆ๋‹ค.");
		else {
			int len = 0;
			for (int i = 0; i < idx; i++)
				len += s1.substring(i, i + 1).getBytes().length;
			len += s2.length();

			System.out.println((idx + 1) + "๋ฒˆ์งธ ๋ฌธ์ž์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.");
			System.out.println("ํ…์ŠคํŠธ๏ผš" + s1);
			System.out.printf(String.format("ํŒจํ„ด๏ผš%%%ds\n", len), s2);
		}
	}
}

3. Boyer-Moore ์•Œ๊ณ ๋ฆฌ์ฆ˜

KMP๋ณด๋‹ค ํšจ์œจ์ด ์šฐ์ˆ˜ํ•ด ์‹ค์ œ๋กœ ๋ฌธ์ž์—ด ํƒ์ƒ‰์— ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

ํŒจํ„ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž๋ถ€ํ„ฐ ์•ž์ชฝ์œผ๋กœ ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ
์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ž๊ฐ€ ์žˆ์œผ๋ฉด ๋ฏธ๋ฆฌ ์ค€๋น„ํ•œ ํ‘œ์— ๋”ฐ๋ผ ํŒจํ„ด์„ ์˜ฎ๊ธธ ํฌ๊ธฐ๋ฅผ ์ •ํ•œ๋‹ค.

์˜ˆ์‹œ

ABCXDEZCABACABAC์—์„œ ํŒจํ„ดABAC๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ

           v
ํ…์ŠคํŠธ ABC X DEZCABACABAC
a      ABA C				ํŒจํ„ด๊ณผ ํ…์ŠคํŠธ์˜ ๋ฌธ์ž๊ฐ€ ์„œ๋กœ ๋‹ค๋ฆ„
b       AB A C				ํŒจํ„ด์„ 1์นธ ์˜ฎ๊ฒจ๋„ ๋ฌธ์ž๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค.
c        A B AC				ํŒจํ„ด์„ 2์นธ ์˜ฎ๊ฒจ๋„ ๋ฌธ์ž๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค.
d          A BAC			ํŒจํ„ด์„ 3์นธ ์˜ฎ๊ฒจ๋„ ๋ฌธ์ž๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค.

ํŒจํ„ด์•ˆ์— ๋“ค์–ด์žˆ์ง€ ์•Š์€ ํ…์ŠคํŠธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด ํ•ด๋‹น ์œ„์น˜๊นŒ์ง€ ๊ฑด๋„ˆ๋›ฐ๊ณ  ํƒ์ƒ‰์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.  

               v
ํ…์ŠคํŠธ ABCXDEZ C ABACABAC
           ABA C			์ผ์น˜

              v
ํ…์ŠคํŠธ ABCXDE Z CABACABAC
a         ABA C						  
b          AB A C			
c           A B AC			
d             A BAC			๋ถˆ์ผ์น˜

Z๊ฐ€ ํŒจํ„ด์— ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•œ๋ฒˆ์— 3์นธ ์˜ฎ๊ฒจ ๋‹ค์‹œ ํƒ์ƒ‰ํ•œ๋‹ค.

                  v
ํ…์ŠคํŠธ ABCXDEZCAB A CABAC
a             ABA C						  
b              AB A C		์ผ์น˜

A ๋ฌธ์ž๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๊ณ 
ํ•ด๋‹น ์œ„์น˜์—์„œ ํŒจํ„ด์˜ ๋งˆ์ง€๋ง‰ ์œ„์น˜ ๋ฌธ์ž๋ถ€ํ„ฐ ๋น„๊ตํ•œ๋‹ค.

                <---   
ํ…์ŠคํŠธ ABCXDEZC ABAC ABAC
                ABAC		์ผ์น˜

๋ชจ๋‘ ์ผ์น˜ํ•˜์—ฌ ๊ฒ€์ƒ‰์— ์„ฑ๊ณตํ•œ๋‹ค.

ํŒจํ„ด์˜ ๊ธธ์ด๋ฅผ n์ด๋ผ๊ณ  ํ•˜๋ฉด ํ˜„์žฌ ๊ฒ€์‚ฌํ•˜๊ณ  ์žˆ๋Š” ํ…์ŠคํŠธ์˜ ๋ฌธ์ž ์œ„์น˜๋กœ๋ถ€ํ„ฐ
๋‹ค์Œ์— ๊ฒ€์‚ฌํ•  ํŒจํ„ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž ์œ„์น˜๊ฐ€ n๋งŒํผ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋„๋ก ํŒจํ„ด์„ ์ด๋™ ์‹œํ‚จ๋‹ค.

๊ฐ๊ฐ์˜ ๋ฌธ์ž๋ฅผ ๋งŒ๋‚ฌ์„ ๋•Œ ํŒจํ„ด์„ ์˜ฎ๊ธธ ํฌ๊ธฐ๋ฅผ ์ €์žฅํ•  ํ‘œ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

ํ‘œ ๋งŒ๋“ค๊ธฐ

n = ํŒจํ„ด ๋ฌธ์ž์—ด์˜ ๊ธธ์ด

  • ํŒจํ„ด์— ๋“ค์–ด ์žˆ์ง€ ์•Š์€ ๋ฌธ์ž๋ฅผ ๋งŒ๋‚œ ๊ฒฝ์šฐ

    1. ํŒจํ„ด์„ ์˜ฎ๊ธธ ํฌ๊ธฐ๋Š” n์ด๋‹ค.
  • ํŒจํ„ด์— ๋“ค์–ด ์žˆ๋Š” ๋ฌธ์ž๋ฅผ ๋งŒ๋‚œ ๊ฒฝ์šฐ

    1. ๋งˆ์ง€๋ง‰์— ๋‚˜์˜ค๋Š” ์œ„์น˜์˜ ์ธ๋ฑ์Šค๊ฐ€ k์ด๋ฉด ํŒจํ„ด์„ ์˜ฎ๊ธธ ํฌ๊ธฐ๋Š” n-k-1์ด๋‹ค.
    2. ๊ฐ™์€ ๋ฌธ์ž๊ฐ€ ํŒจํ„ด ์•ˆ์— ์ค‘๋ณตํ•ด์„œ ๋“ค์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด ํŒจํ„ด์„ ์˜ฎ๊ธธ ํฌ๊ธฐ๋Š” n์ด๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ

import java.util.Scanner;

class BMmatch {
	// Boyer-Moore๋ฒ•์œผ๋กœ ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ 
	static int bmMatch(String txt, String pat) {
		int pt;                             // txt ์ปค์„œ
		int pp;                             // pat ์ปค์„œ
		int txtLen = txt.length();          // txt์˜ ๋ฌธ์ž ๊ฐœ์ˆ˜
		int patLen = pat.length();          // pat์˜ ๋ฌธ์ž ๊ฐœ์ˆ˜
		int[] skip = new int[Character.MAX_VALUE + 1];	// ๊ฑด๋„ˆ๋›ฐ๊ธฐ ํ‘œ

		// ๊ฑด๋„ˆ๋›ฐ๊ธฐ ํ‘œ ๋งŒ๋“ค๊ธฐ
		for (pt = 0; pt <= Character.MAX_VALUE; pt++)
			skip[pt] = patLen;
		for (pt = 0; pt < patLen - 1; pt++)
			skip[pat.charAt(pt)] = patLen - pt - 1;	// pt == patLen - 1
		// ๊ฒ€์ƒ‰
		while (pt < txtLen) {
			pp = patLen - 1;				// pat์˜ ๋ ๋ฌธ์ž์— ์ฃผ๋ชฉ

			while (txt.charAt(pt) == pat.charAt(pp)) {
				if (pp == 0)
					return pt;	// ๊ฒ€์ƒ‰ ์„ฑ๊ณต
				pp--;
				pt--;
			}
			pt += (skip[txt.charAt(pt)] > patLen - pp) ? skip[txt.charAt(pt)] : patLen - pp;
		}
		return -1;				// ๊ฒ€์ƒ‰ ์‹คํŒจ
	}

	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);

		System.out.print("ํ…์ŠคํŠธ๏ผš");
		String s1 = stdIn.next(); 					// ํ…์ŠคํŠธ์šฉ ๋ฌธ์ž์—ด 

		System.out.print("ํŒจํ„ด๏ผš");
		String s2 = stdIn.next();					// ํŒจํ„ด์šฉ ๋ฌธ์ž์—ด 

		int idx = bmMatch(s1, s2);	// ๋ฌธ์ž์—ด s1์—์„œ ๋ฌธ์ž์—ด s2๋ฅผ BM๋ฒ•์œผ๋กœ ๊ฒ€์ƒ‰

		if (idx == -1)
			System.out.println("ํ…์ŠคํŠธ์— ํŒจํ„ด์ด ์—†์Šต๋‹ˆ๋‹ค.");
		else {
			int len = 0;
			for (int i = 0; i < idx; i++)
				len += s1.substring(i, i + 1).getBytes().length;
			len += s2.length();

			System.out.println((idx + 1) + "๋ฒˆ์งธ ๋ฌธ์ž์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.");
			System.out.println("ํ…์ŠคํŠธ๏ผš" + s1);
			System.out.printf(String.format("ํŒจํ„ด๏ผš%%%ds\n", len), s2);
		}
	}
}

Reference & Additional Resources

Do it! ์ž๋ฃŒ๊ตฌ์กฐ์™€ ํ•จ๊ป˜ ๋ฐฐ์šฐ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž…๋ฌธ, ์ž๋ฐ” ํŽธ