데이터 · 12
문자열 만들어 가기
조각을 붙여 문자열 만들기, 사이에 넣어 잇기, 한 줄에 이어 찍기.
출력할 문자열을 한 번에 쓸 수 없을 때는 조각을 하나씩 붙여서 만들어요.
아래 예제는 낱말들을 읽어서 첫 글자만 모은 문자열, 낱말을 쉼표로 이은 문자열, 낱말 길이를 빈칸으로 이은 한 줄을 차례로 찍어요.
words = input().split()initials = ""for w in words: initials += w[0] # 한 조각씩 붙여 가요print(initials)print(", ".join(words)) # 사이에만 ", "lens = [len(w) for w in words]print(*lens) # 빈칸으로 이어 찍기const words = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);let initials = "";for (const w of words) { initials += w[0]; // 한 조각씩 붙여 가요}console.log(initials);console.log(words.join(", ")); // 사이에만 ", "const lens = words.map((w) => w.length);console.log(lens.join(" ")); // 빈칸으로 이어 찍기import { readFileSync } from "node:fs";const words: string[] = readFileSync(0, "utf8").trim().split(/\s+/);let initials: string = "";for (const w of words) { initials += w[0]; // 한 조각씩 붙여 가요}console.log(initials);console.log(words.join(", ")); // 사이에만 ", "const lens: number[] = words.map((w) => w.length);console.log(lens.join(" ")); // 빈칸으로 이어 찍기import java.util.Scanner; public class Main { public static void main(String[] args) { String[] words = new Scanner(System.in).nextLine().trim().split(" +"); StringBuilder initials = new StringBuilder(); for (String w : words) { initials.append(w.charAt(0)); // 한 조각씩 붙여 가요 } System.out.println(initials); System.out.println(String.join(", ", words)); // 사이에만 ", " int[] lens = new int[words.length]; for (int i = 0; i < words.length; i++) lens[i] = words[i].length(); for (int i = 0; i < lens.length; i++) { if (i > 0) System.out.print(" "); // 첫 값 앞에는 안 찍어요 System.out.print(lens[i]); } System.out.println(); }}using System;using System.Text; class Program{ static void Main() { string[] words = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); var initials = new StringBuilder(); foreach (string w in words) { initials.Append(w[0]); // 한 조각씩 붙여 가요 } Console.WriteLine(initials); Console.WriteLine(string.Join(", ", words)); // 사이에만 ", " int[] lens = new int[words.Length]; for (int i = 0; i < words.Length; i++) lens[i] = words[i].Length; Console.WriteLine(string.Join(" ", lens)); // 빈칸으로 이어 찍기 }}#include <iostream>#include <string>#include <vector> int main() { std::vector<std::string> words; std::string w; while (std::cin >> w) words.push_back(w); std::string initials; for (const std::string& x : words) { initials += x[0]; // 한 조각씩 붙여 가요 } std::cout << initials << '\n'; for (size_t i = 0; i < words.size(); i++) { if (i > 0) std::cout << ", "; // 사이에만 ", " std::cout << words[i]; } std::cout << '\n'; std::vector<int> lens; for (const std::string& x : words) lens.push_back(x.size()); for (size_t i = 0; i < lens.size(); i++) { if (i > 0) std::cout << ' '; // 첫 값 앞에는 안 찍어요 std::cout << lens[i]; } std::cout << '\n';}#include <stdio.h>#include <string.h> int main(void) { char words[100][51], initials[101]; int n = 0, lens[100]; while (n < 100 && scanf("%50s", words[n]) == 1) n++; for (int i = 0; i < n; i++) { initials[i] = words[i][0]; // 한 조각씩 붙여 가요 } initials[n] = '\0'; // 문자열의 끝 표시 printf("%s\n", initials); for (int i = 0; i < n; i++) { if (i > 0) printf(", "); // 사이에만 ", " printf("%s", words[i]); } printf("\n"); for (int i = 0; i < n; i++) lens[i] = strlen(words[i]); for (int i = 0; i < n; i++) { if (i > 0) printf(" "); // 첫 값 앞에는 안 찍어요 printf("%d", lens[i]); } printf("\n"); return 0;}words = 콘솔.줄읽기().나누기();initials = "";각각 (w 에서 words){ initials += w[0]; // 한 조각씩 붙여 가요}콘솔.쓰기(initials);콘솔.쓰기(words.잇기(", ")); // 사이에만 ", "lens = [];각각 (w 에서 words){ lens.넣기(w.길이);}콘솔.쓰기(lens); // 목록은 빈칸으로 이어 찍어요red green blue
rgb red, green, blue 3 5 4
핵심
- 만들어 가기: 빈 문자열에서 시작해, 반복하면서 조각을 뒤에 붙여요(
initials += w[0]).
합계를total += x로 모으던 것과 같은 꼴이에요. - Java와 C#의
+=는 붙일 때마다 지금까지의 문자열을 통째로 새로 만들어요.
그래서 조각을 모아 두었다가 끝에 한 번만 문자열로 바꾸는 StringBuilder가 따로 있어요. - 수를 붙일 때 저절로 문자열로 바꿔 주는 언어가 있고, 직접 바꿔서 붙여야 하는 언어가 있어요.
- 잇기(join)는 목록의 값들 사이에만 구분 문자열을 넣어 하나로 만들어요.
red,green,blue를", "로 이으면red, green, blue예요.
맨 뒤에는 붙지 않아요. - 잇기가 없는 언어에서는 반복문으로 써요.
첫 값이 아닐 때만 구분 문자열을 먼저 찍고 값을 찍으면, 맨 뒤에 구분 문자열이 남지 않아요. - 수 여러 개를 한 줄에 찍는 것도 같은 일이에요.
한 번에 이어 찍는 짧은 방법이 있는 언어도 있고, 줄을 바꾸지 않는 출력으로 하나씩 찍는 언어도 있어요.
언어별로 쓰는 법
| Python | 붙이기 s += 조각 — 수는 str(n)으로 바꿔서 붙여요.조각이 많으면 목록에 append하고 끝에 "".join(parts).잇기 ", ".join(words)는 문자열 목록만 받아요.한 줄 출력은 print(*nums), 구분을 바꾸려면 print(*nums, sep=", ") |
|---|---|
| JavaScript | 붙이기 s += 조각 — 수도 저절로 문자열이 돼요.잇기 words.join(", ")는 수 배열도 되고, 괄호를 비운 join()은 쉼표로 이어요.한 줄 출력은 console.log(nums.join(" ")) |
| TypeScript | JavaScript와 같아요 |
| Java | StringBuilder sb = new StringBuilder(); 다음 sb.append(조각) — 글자·수·문자열을 모두 받아요.끝에 sb.toString()으로 바꾸거나 그대로 println(sb).잇기 String.join(", ", words)는 문자열만 받아요.수는 System.out.print로 하나씩 찍거나 StringBuilder에 모아요 |
| C# | var sb = new StringBuilder();(using System.Text;) 다음 sb.Append(조각), 끝에 sb.ToString().잇기 string.Join(", ", words)는 수 배열도 받아서, 한 줄 출력이 Console.WriteLine(string.Join(" ", nums))예요 |
| C++ | std::string은 고칠 수 있어서 s += 조각이 제자리에서 붙어요.수는 std::to_string(n)으로 바꿔 붙여요.잇기가 없어서 if (i > 0) std::cout << ", ";처럼 반복문으로 써요.std::ostringstream에 <<로 모았다가 .str()로 꺼내도 돼요 |
| C | 문자열은 char 배열이라, 자리를 넉넉히 잡고 칸마다 글자를 넣은 뒤 끝에 '\0'을 넣어요.문자열을 붙일 때는 strcat(buf, "cd"), 수는 sprintf(buf + len, "%d", n).잇기가 없어서 반복문과 printf로 써요 |
| Craykon | 붙이기 s += 조각 — 수도 저절로 문자열이 돼요.잇기 words.잇기(", ")는 수 목록도 돼요.콘솔.쓰기(목록)은 빈칸으로 이어 찍고, 하나씩 찍을 때는 줄을 바꾸지 않는 콘솔.이어쓰기(값) |
자주 하는 실수
구분 문자를 값 뒤에 붙였어요
words = ["red", "green", "blue"]
line = ""
for w in words:
line += w + ","
print(line)→ red,green,blue, — 맨 뒤에 쉼표가 하나 더 붙어요
잇기를 쓰거나, 첫 값이 아닐 때만 값 앞에 붙여요: if line: line += "," 다음에 line += w.
수 목록을 그대로 이었어요Python · Java
print(", ".join([1, 2, 3]))→ Python은 TypeError: sequence item 0: expected str instance, int found. Java도 int[] nums에 String.join(", ", nums)를 쓰면 컴파일 오류예요
Python은 ", ".join(map(str, nums))나 print(*nums, sep=", "), Java는 StringBuilder에 모아요.
JavaScript·C#·크레이콘의 잇기는 수도 받아요.
따옴표 문자열 둘을 +로 붙였어요C · C++
char *s = "ab" + "cd";→ 컴파일 오류 invalid operands to binary + — C의 문자열은 주소라서 더할 수 없어요. C++에서 std::string s = "ab" + "cd";도 같은 까닭으로 컴파일 오류예요
C는 char buf[10] = "ab"; strcat(buf, "cd");, C++는 한쪽을 std::string으로 만들어요: std::string("ab") + "cd".
언어마다 다른 점
조각이 많을 때는 붙이는 방법에 따라 시간이 크게 달라져요.
이 사이트 채점기와 같은 환경에서 한 글자씩 20만 번 붙여 보니 Java는
Python도 예제처럼 함수 밖에서
JavaScript(Node.js)는
잰 시간은 컴퓨터마다 달라요.
그리고 C++에서 수를 붙일 때는 꼭
조각이 많을 때는 붙이는 방법에 따라 시간이 크게 달라져요.
이 사이트 채점기와 같은 환경에서 한 글자씩 20만 번 붙여 보니 Java는
+=로 1초쯤, StringBuilder로 1~2ms였고, C#은 +=로 2~3초, StringBuilder로 1~2ms였어요.Python도 예제처럼 함수 밖에서
+=로 붙이면 0.5초쯤, 목록에 모았다가 join하면 10ms가 안 걸렸어요.JavaScript(Node.js)는
+=로도 10ms 안팎이었어요.잰 시간은 컴퓨터마다 달라요.
그리고 C++에서 수를 붙일 때는 꼭
std::to_string을 거쳐요.s += 65는 "65"가 아니라 코드 65인 글자 A를 붙여요.