문자열

Jeonghwan Yoon·2025년 3월 30일

문자열이란?

  • 문자(char)의 연속으로 이루어진 자료, 데이터.
  • 파이썬에서는 문자열(str)이 불변(immutable) 객체이므로, 수정 시 새로운 문자열을 생성.
  • C 언어에서는 char 배열을 사용하거나 char *를 동적 할당해 사용. (널 문자 \0 로 끝을 표시)
s = "hello"
print(s[1])  # 출력: 'e'

문자열의 특징

  1. 인덱스 접근
    • s[i]로 개별 문자에 접근 가능 (파이썬: 상수 시간, C: 배열 인덱스 접근)
  2. 불변성(파이썬)
    • 문자열을 직접 수정(s[2] = 'X') 불가 → 새로운 문자열을 만들어야 함.
  3. 크기(길이)
    • 파이썬: len(s)로 길이를 쉽게 구함 (O(1)처럼 보이지만 내부 구현에 따라 O(1) 또는 O(n) 가능성).
    • C: strlen(str) 함수로 길이 계산 (실제로 한 문자씩 순회하므로 O(n)).
  4. 문자열 연산 비용
    • 문자열 연결시, 새로 공간을 할당하고 복사 → 길이에 비례한 시간 소요.

요약

특징설명
문자 배열내부적으로는 문자 하나하나를 인덱스로 구분
0번 인덱스부터 시작s[0]은 첫 글자
불변(immutable)문자열을 직접 수정할 수 없음
슬라이싱 가능부분 문자열 추출 가능
많은 내장 함수 지원문자열을 다루기 위한 다양한 기능 제공

문자열에서 주로 하는 작업

  1. 탐색
    • 특정 문자가 문자열 안에 존재하는지 찾기.
    • 선형 탐색으로 O(N)
    • 파이썬 내장: s.find('a'), 'a' in s 등 (내부적으로도 선형 탐색)
  2. 슬라이싱 (파이썬)
    • s[start:end] 형태로 부분 문자열을 구함.
    • 실제로는 새 문자열을 생성 (복사가 발생) → O(N)
      s = "hello"
      print(s[1:4])  # 'ell'
      print(s[:2])   # 'he'
      print(s[2:])   # 'llo'
  3. 변환/조작
    • s.replace(old, new): 부분 문자열을 다른 문자열로 교체 (새로운 문자열 리턴)
    • s.split(delim): 구분자로 나누어 리스트 형태로 반환
    • s.strip(): 공백이나 특정 문자 제거
  4. 문자열 뒤집기
    • 파이썬: s[::-1] (슬라이싱 응용)
    • 직접 구현 시, O(N)의 시간에 두 인덱스를 바꿔가며 스왑.

인덱스 접근

s = "hello"
print(s[0])  # 'h'
print(s[-1]) # 'o' (뒤에서 첫 번째 문자)

직접 구현 예시 (파이썬, 내장함수 최소화)

문자열 뒤집기

def reverse_string(st):
    reversed_str = ""
    for i in range(len(st)-1, -1, -1):
        reversed_str += st[i]
    return reversed_str
s = "Hello"
print(reverse_string(s))
# 'olleH'

문자열 선형 탐색

def find_char(st, ch):
    """st에서 문자 ch를 찾으면 인덱스 반환, 없으면 -1"""
    for i in range(len(st)):
        if st[i] == ch:
            return i
    return -1
print(find_char("Hello", 'l'))  # 2 (처음 찾은 'l')
print(find_char("Hello", 'z'))  # -1 (존재하지 않음)

부분 문자열(substring) 확인

def is_substring(main_str, sub_str):
    """main_str에 sub_str이 포함되어 있는지 확인"""
    M = len(main_str)
    S = len(sub_str)
    for i in range(M - S + 1):
        match = True
        for j in range(S):
            if main_str[i+j] != sub_str[j]:
                match = False
                break
        if match:
            return True
    return False
print(is_substring("Hello World", "World"))  # True
print(is_substring("Hello World", "Bye"))    # False

문자열 관련 파이썬 내장 함수 정리

함수설명예시C언어 대체 방식
len(s)문자열 길이len("hello") → 5strlen() 함수 사용 또는 직접 카운트
s.upper()대문자로 변환"abc".upper() → "ABC"반복문 + toupper()
s.lower()소문자로 변환"ABC".lower() → "abc"반복문 + tolower()
s.strip()앞뒤 공백 제거" hi ".strip() → "hi"반복문으로 공백 체크
s.lstrip()왼쪽 공백 제거" hi".lstrip() → "hi"-
s.rstrip()오른쪽 공백 제거"hi ".rstrip() → "hi"-
s.split()문자열 나누기"a,b,c".split(',') → ['a','b','c']직접 파싱 (for + 조건문)
s.find(sub)부분 문자열 위치"abcde".find("cd") → 2직접 구현 (위 예시 참고)
s.replace(a, b)문자열 치환"aabb".replace("a","c") → "ccbb"직접 구현 필요
s.isdigit()숫자 여부 확인"123".isdigit() → True문자 하나하나 확인

split() 함수

text = "apple,banana,grape"
result = text.split(',')   # ✅ 내장함수
print(result)              # ['apple', 'banana', 'grape']
  • 기본 동작: split(separator)
  • separator로 문자열을 나눠서 리스트 형태로 반환
  • 생략하면 공백 기준으로 나눔 → text.split()
  • C언어에서는 문자열 순회하며 구분자를 기준으로 직접 나눠야 함

strip() 함수

s = "  hello  "
print(s.strip())   # 'hello'
print(s.lstrip())  # 'hello  '
print(s.rstrip())  # '  hello'
  • 문자열 앞뒤의 공백 문자(또는 지정 문자)를 제거
  • 내부적으로 문자 하나하나 비교해서 제거
  • C언어에서는 수동으로 인덱스 조정하면서 공백 건너뛰어야 함

문자열 불변(Immutable)의 의미

s = "hello"
s[0] = 'H'  # ❌ 오류! 문자열은 변경 불가
# 대신 이렇게 해야 함
s = 'H' + s[1:]  # ✅ 새로운 문자열 생성
print(s)  # 출력: 'Hello'
  • 파이썬의 문자열은 값을 바꾸는 게 아니라, 새로 만드는 방식으로 동작
  • 메모리 관점에서 비효율이 될 수 있음 (C에서는 직접 바꾸는 것이 가능)

정리

핵심 포인트설명
문자열은 불변이다수정이 아닌 새 문자열을 생성
파이썬은 많은 내장 함수를 제공split, strip, replace 등
내장함수 없이 구현도 가능해야 함C언어에서는 전부 직접 만들어야 하기 때문
슬라이싱은 강력한 기능s[1:4], s[::-1]

추가 tip

  • 문자열은 배열처럼 인덱스로 처리
  • 파이썬에서는 str, C언어에서는 char[]로 다룸
  • 내장함수에 익숙해지되, 함수 없이도 구현하는 습관을 들이기
  • C언어에서는 문자열 처리할 때 *널문자 \0로 종료를 표시함

C 언어에서의 문자열과 차이

  • *널 문자(\0)**로 문자열의 끝을 표시해야 함.
  • strlen(), strcpy(), strcat() 등 표준 라이브러리 함수를 사용하거나 직접 구현.
  • 수정 가능(배열이므로), 단 ‘버퍼 크기 초과’에 유의해야 함.

예: char str[10] = "Hello"; 라면, 내부적으로 'H' 'e' 'l' 'l' 'o' '\0' ... 형태로 저장.

profile
안녕하세요.

0개의 댓글