728x90
반응형

저번 글에 이어 이번 글에서는 그래프를 읽어온 결과를 바탕으로 그래프 상에서 dfs를 해보겠다.


0. 그래프 구조

먼저, 저번 글에서 사용한 그래프 구조를 직접 그리면 다음과 같다.

1. dfs 코드

dfs는 Depth-First-Search의 약자로 현재 정점에서 다음 정점으로 갈 수 있는 경우, 탐색을 계속하며 다음 정점이 없는 경우에는 부모 정점으로 돌아가 다시 갈 수 있는 정점가 있는지 판단한다.

다음 정점이 있는 경우 계속해서 탐색을 하기 때문에 트리에서 탐색할 경우, 루트 노드에서 계속해서 높이를 내려가면서 탐색을 하므로 dfs라는 이름이 붙었다.

 

코드 전반은 다음과 같다.

int dfs(vector<vector<int>> &graph, vector<int>& visited, int n){
    cout << "Vertex " << n << "\n";
    visited[n - 1] = 1;

    for(int i = 0; i < graph[n - 1].size(); i++){
        int idx = graph[n - 1][i];
        if(!visited[idx - 1]){
            dfs(graph, visited, idx);
        }
    }
    return 0;
}

그래프 정보를 저장하는 이차원 배열 graph와 방문 여부를 저장하는 배열visited, 현재 정점 번호를 저장하는 idx 변수를 매개변수로 가진다.

 

재귀함수를 이용해 코드를 구현했으며(스택을 이용해도 가능하다) 정점을 방문할 시 현재 정점에 방문처리를 한다.

 

그리고 현재 정점에 연결된 다른 정점들을 방문했는지 체크하며, 만약 방문하지 않았다면 그 정점을 방문한다.

결과는 다음과 같다.

8번 정점에서 5번 정점으로 가는 이유는, 8번 정점에서 5번 정점으로 갈 수 있기 때문이다.

dfs는 높이가 위에서 아래로 내려가는 것만이 아니라, 다음에 갈 수 있는 정점이 있는지 여부를 가지고 탐색을 계속한다.

728x90
반응형
LIST
728x90
반응형

< 그래프 정보를 출력 모습 >

이 글에서는 fstream 라이브러리를 이용한(C++11 이상 버전 권장, 버퍼 객체 bool 타입으로 변환 가능해서) 파일 입출력 예제를 다뤄보겠다.

수업에서 배운 dfs, bfs, 다익스트라 알고리즘 등을 복습할 겸 C++로 코드를 짜보았다.


1. include

먼저 기본 입출력에 필요한 iostream, 그래프 정보를 저장하는 데 쓸 이차원 배열을 동적으로 생성하기 위한 vector, 파일 입출력을 위한 fstream 라이브러리를 include 해온다.

#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

*std 네임스페이스를 미리 선언했다. 이렇게 되면 원래는 std::fstream 형인 fstream을 그냥 fstream으로 사용할 수 있다.

 

2. 변수들과 파일 스트림 객체를 만들어 준다.

파일 스트림 객체는 fstream 말고도 쓰기만을 위한 ofstream, 읽기만을 위한 ifstream으로도 객체를 생성할 수 있다.

int main(){
    int n;
    int V;
    vector<vector<int>> graph;
    vector<int> visited;
    
    fstream fs;
}

여기서는 굳이 ofstream과 ifstream을 구분하진 않겠다.

 

3. open()메소드를 이용해 파일을 읽어와 그래프에 저장한다.

int main(){
    int n;
    int V;
    vector<vector<int>> graph;
    vector<int> visited;

    // inputs
    fstream fs;
    fs.open("./test.txt", ios::in);	// 여기서 텍스트 파일 경로 지정
    if(!fs){    // if fails			읽기 실패시 Error 출력
        cerr << "Error!\n";
    }
    fs >> n;						// 형식이 정해져 있을 경우, >> 연산자를 사용 가능하다.
    for(int i = 0; !fs.eof(); i++){
        fs >> V;
        graph.push_back({});
        for(int j = 0; j < V; j++){
            graph[i].push_back(0);
            fs >> graph[i][j];
        }
    }
    fs.close();						// 파일 스트림 닫아주기


    // output - 그래프 정보 출력
    cout << "Graph info - \n";
    for(int i = 0; i < n; i++){
        cout << "Vertex " << i+1 << " - ";
        for(int j = 0; j < graph[i].size(); j++){
            cout << graph[i][j] << " ";
        }
        cout << "\n";
    }
    return 0;
}

- 입력 파일 및 출력 결과

첫 번째 줄에는 그래프 정점의 개수 V가

두 번째 줄~ V+1번째 줄에는 연결된 정점의 개수와 정점의 번호가 입력된다.

 

4. 전체 코드

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;


int main(){
    int n;
    int V;
    vector<vector<int>> graph;
    vector<int> visited;

    // inputs
    fstream fs;
    fs.open("./test.txt", ios::in);
    if(!fs){    // if fails
        cerr << "Error!\n";
    }
    fs >> n;
    for(int i = 0; !fs.eof(); i++){
        fs >> V;
        graph.push_back({});
        for(int j = 0; j < V; j++){
            graph[i].push_back(0);
            fs >> graph[i][j];
        }
    }
    fs.close();


    // output
    cout << "Graph info - \n";
    for(int i = 0; i < n; i++){
        cout << "Vertex " << i+1 << " - ";
        for(int j = 0; j < graph[i].size(); j++){
            cout << graph[i][j] << " ";
        }
        cout << "\n";
    }
    return 0;
}
728x90
반응형
LIST
728x90
반응형

자바에서 스윙 라이브러리를 사용하려고 다음과 같이 import시 오류가 나는 상황이 있었을 것이다.

import javax.swing.*;

이때, java 11 이후로는 java.base 모듈만 기본으로 포함하므로, 그 이외의 다른 모듈들을 사용하기 위해서는 따로 불러오기가 필요하다.

따라서 module-info.java 파일에 다음과 같이 작성해준다.

module <모듈 이름>{
	requires java.desktop;
}

예시)

참고 블로그 : https://daily-life-of-bsh.tistory.com/129

728x90
반응형
LIST
728x90
반응형

1. 변수 한 개를 추가로 생성한다.

void swap(int *a, int *b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
    return;
}

2. xor 연산을 사용한다.

void swap(int *a, int *b){
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
    return;
}

3. 덧셈 연산을 사용한다.

void swap(int *a, int *b){
    *a = *a + *b;
    *b = *a - *b;
    *a = *a - *b;
    return;
}

// 또는 더 간단하게
void swap(int *a, int *b){
    *a += *b;
    *b = *a - *b;
    *a -= *b;
    return;
}

1. 방법은 간편하지만 추가로 변수를 생성해야 한다는 단점이 존재하고 (메모리 관점에서 손해)
2. 방법과 3. 방법은 변수를 생성할 필요가 없지만, 사람이 직관적으로 이해하기에는 다소 무리가 있다는 단점이 있다. (가독성 측면에서 손해)
하지만 2. 방법에서는 xor이라는 생소한 개념을 사용하는 반면, 3. 에서는 우리에게 익숙한 + 연산을 사용하므로 구현하기에 무리가 없다.

c++에서 독립적인 함수를 만든다는 가정하에 void형 반환 타입과 포인터 변수를 사용했다.

만약 독립적인 함수가 아닌 다른 함수 내부에서 구현한다고 하더라도, 다음과 같이 a와 b 자리에 값을 바꾸고자 하는 변수를 위치시키면 된다.

728x90
반응형
LIST
728x90
반응형

** 주의

PS를 할 때 C++에서 list 자료형은 인덱싱을 할 수 없다는 치명적인 결함 때문에 거의 쓰이지 않습니다.

이 글에서는 list 자료형을 사용할 수 있는 방법을 소개했지만, PS를 할 때는 다른 라이브러리를 사용하는 것을 추천드립니다.

1. 개요

알고리즘을 풀 때 만약 요소를 순서대로 조회하면서 인덱싱을 하려면

std::vector 라이브러리나 std::deque, std::map (포인터로 iterator 생성가능) 등의 자료형을 사용할 것이다.

 

하지만 만약 시퀀스 중간에서 삽입, 삭제가 일어나야 할 경우, 위에 나온 자료형 모두 사용하기가 애매해진다. (map은 확인 필요)

- 특히, std::vector는 push_back, pop_back 등의 메소드는 amortized O(1)로 O(n)이 나올 상황을 방지할 수 없고, 무엇보다 erase() 메소드는 O(n)의 시간복잡도를 가진다.

 

그래서 인덱싱 및 중간에서의 삽입, 삭제를 O(1)만에 하기 위해서는 list 자료형이 그 무엇보다 간절해진다.

이 글에서는 빠르게 std::list의 사용법, 시간복잡도를 알아보겠다.

 

2. 사용법

// 예제코드
// Test Source.
#include <list>
using namespace std;

int main() {
	list<int> lst;
	
	return 0;
}

다음과 같이 코드를 짜면 list 자료형을 가지는 lst가 생성된다.

이때 list에서 사용할 수 있는 메소드는 다음 블로그에 잘 정리되어 있으니 참고하기 바란다.

https://losskatsu.github.io/programming/c-stl-list/

 

[C언어] C++ STL 리스트(list) 사용법 정리

C++ STL 리스트(list) 사용법 정리

losskatsu.github.io

 

3. 인덱싱

하지만 std::list 라이브러리의 가장 큰 문제가 아직 남아있다.

.at()메소드나 인덱싱이 되지 않아 어떤 한 요소에 바로 접근할 수 없는 것이다.

 

하지만 다음 블로그의 내용을 참고하면 이를 해결할 수 있다.

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=cksdn788&logNo=220448923269 

 

[Grind Away] STL list 에서 index로 값 접근하기

list에는 at함수와 같이 index 값을 통해 특정 위치의 데이터에 접근하는 기능이 존재하지 않는다. 사실 별...

blog.naver.com

advance()메소드를 사용하는 것인데 예제 코드는 다음과 같다.

 

// Test Source.
#include <iostream>
#include <list>
using namespace std;

int main() {	
	list<int> lst;
	list<int>::iterator itr = lst.begin();
	
	for(int i = 0; i < 5; i++)
		lst.push_back(i);
	// test output
	for (itr = lst.begin(); itr != lst.end(); itr++)
		cout << *itr << " ";
	// itr initalize
	itr = lst.begin();
    // itr에 다음 요소의 주소를 할당 (뒤의 숫자만큼 인덱스 증가)
	advance(itr, 1);
	cout << *itr;		

	return 0;
}

- advande(std::list<자료형>::iterator itr, int increaseIdx)

- 뒤의 숫자만큼 다음 인덱스로 가며, 배열의 끝 +1 번지에 도착하는 건 괜찮지만, 그 주소에서 역참조를 해 값을 출력, 연산하려고 하면 오류가 나니 조심하자.

 

- 이를 이용하면 인덱싱도 가능해진다. (itr = begin()으로 초기화해줘야 함)

무엇보다 advance는 itr에 주소를 할당시켜 주므로 erase()메소드 등을 이용하기 오히려 편리하다.

- 주소를 증가시킨다는 것은 이런  뜻이다.

- i로 실수로 할당하면 포인터가 배열을 벗어난 주소를 가리키게 되니 주의하자.

 

+)

- 이런 식으로 미리 초기화를 해주면 인덱싱하는것 처럼 쓸 수 있으니 참고하자.

728x90
반응형
LIST
728x90
반응형

참고한 블로그

- UTF-8 인코딩 설정:

https://suzxc2468.tistory.com/174

 

이클립스(Eclipse) 한글 깨짐 - "UTF-8" 인코딩 설정

개념 인코딩이라는 개념과 친하지 않은 뉴비들을 위한 아주 간략한 설명을 하자면... 어딘가에서 소스를 가져와서 이클립스에 갖다 붙혀봤더니, 한글이 깨져서 나와요. or HTML, JSP에서 작성 된 한

suzxc2468.tistory.com

- 콘솔 출력에서 MS949 인코딩 설정

https://error-nono.tistory.com/entry/%EC%9D%B4%ED%81%B4%EB%A6%BD%EC%8A%A4-%EC%BD%98%EC%86%94-%ED%95%9C%EA%B8%80%EA%B9%A8%EC%A7%90-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95

 

이클립스 콘솔 한글깨짐 해결 방법

저는 평소에 맥북을 사용하고 있습니다. 그런데 테스트 환경이 맥 환경을 지원하지 않는다고 해서 윈도우에 새로 개발환경을 세팅했습니다. 그리고 톰캣을 시작했는데 콘솔창에 한글이 깨져서

error-nono.tistory.com


1. Preferences-> UTF-8 설정하기

 

 

2. Run -> MS949 설정하기

 

728x90
반응형
LIST

'Programming Language > Java' 카테고리의 다른 글

[JAVA] eclipse swing 모듈 설정  (0) 2022.12.04
[Java] Java vscode 개발 환경 설정하기  (0) 2022.09.02
728x90
반응형

참고한 블로그 : 

https://www.delftstack.com/ko/howto/cpp/how-to-convert-int-to-string-in-cpp/

 

C++에서 Int를 문자열로 변환하는 방법

이 기사에서는 C++에서 정수를 문자열로 변환하는 방법을 보여줍니다.

www.delftstack.com

https://godog.tistory.com/entry/C-string-to-int-int-to-string-%ED%98%95%EB%B3%80%ED%99%98-%ED%95%98%EA%B8%B0

 

C++ string to int, int to string 형변환 하기

C++ string to int, int to string 형변환 하기 , string 문자열에서 숫자만 선택해 형변환 int stoi (const string& str [, size_t* idx = 0, int base = 10]) : string to int - string을 int로 바꾸어주기 위해..

godog.tistory.com

https://velog.io/@dkssk2140/C-%EC%88%AB%EC%9E%90%ED%98%95%ED%83%9C%EC%9D%98-char%EB%A5%BC-int%EB%A1%9C-%ED%98%95%EB%B3%80%ED%99%98

 

[C++] 숫자형태의 char를 int로 형변환

https://stackoverflow.com/questions/31490145/what-does-si-0-mean\-'0' 해주기ex)

velog.io


1. int -> string으로 변환하는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	int i;
	cin >> n;
	string number = to_string(n);
	for (i = 0; i < number.length(); i++)
		cout << number[i];
	return 0;
}
  1. string 헤더 include
  2. to_string 메서드를 이용해 string 포인터에 전달 (to_string 함수는 string 객체를 반환)

* 단, 부동소수점 리터럴을 to_string 함수에 전달 시 값이 잘리는 문제 발생 가능

 

- 사용 예시 >

결과 >

앞의 0은 잘리고 나머지 1234만 출력되는 모습을 볼 수 있다.

 

 

2. string -> int로 변환 방법

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	int i;
	cin >> n;
	string number = to_string(n);
	n = stoi(number);
	cout << n;

	return 0;
}

마찬가지로, string 헤더를 include 해주고

stoi 함수를 사용해준다. (string to int를 줄인 것)

3. 그럼 char -> int는?

char형을 int로 변환해주면, 일단 c++에서는 문자열은 string형을 쓰기 때문에 char을 int로 바꾼다는 건 보통 한 글자 내에서 연산이 이루어진다는 것이다.

따라서 char형을 int형에 저장하면 그 문자의 아스키코드값 ('1' -> 49)이 나오게 되는데, 여기서 그냥 '1'을 빼고 1을 더해 주면 된다.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n;
	int i;
	cin >> n;
	string number = to_string(n);
	n = number[0] - '1' + 1;
	cout << n;
	return 0;
}

 

728x90
반응형
LIST
728x90
반응형

참고한 블로그 : https://offbyone.tistory.com/437

 

Microsoft Visual Studio Code에서 Java 개발 환경 설정하기

이전에 Visual Studio Code를 설치해보았습니다. Visual Studio Code를 설치만 했을때 할 수 있는 작업이 없더군요. 필요한 언어에 대한 확장팩을 설치해야 더 나아갈 수 있었습니다. 이번에는 Visual Studio Co

offbyone.tistory.com

목차

  1.  jdk 설치 후 jdk 폴더 환경변수 추가 해주기
  2. vscode에서 java extension pack 설치 해주기
  3. 개발 폴더 만들고 java 프로젝트 만들어주기
728x90
반응형
LIST

'Programming Language > Java' 카테고리의 다른 글

[JAVA] eclipse swing 모듈 설정  (0) 2022.12.04
[JAVA] eclipse IDE 인코딩 설정하기  (0) 2022.09.05
728x90
반응형

추가

- 딕셔너리는 키-값 쌍의 형태를 지닌 자료구조이다.

- 먼저 딕셔너리에서 가장 중요한 메서드 2개는 다음과 같다.

- setdefault : 키-값 쌍 추가(수정은 불가)
- update : 키-값 수정/추가(괄호 안에 들어가는 건 키가 문자열일때만 가능, 아닐 때는 전체 딕셔너리를 넣어야 함) 
# setdefault 메서드 -> 새로운 키-값 추가

x = {'a' : 10, 'b' : 20, 'c' : 30, 'd' : 40}
x.setdefault('e')		# 키만 추가
print(x)				# {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': None}

x.setdefault('f', 100)	# 키와 값 추가
print(x)				# {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': None, 'f': 100}


# update 메서드 -> 기존의 값 수정, 없으면 키-값 쌍 추가.
x = {'a' : 10, 'b' : 20, 'c' : 30, 'd' : 40}
x.update(a = 90)		# 키 a의 값을 90으로 변경
print(x)				# {'a': 90, 'b': 20, 'c': 30, 'd': 40}

x.update(e = 90)		# 없으면 키-값 추가
print(x)				# {'a': 90, 'b': 20, 'c': 30, 'd': 40, 'e': 90}

x.update(a = 900, f = 60)	# 여러 개를 한 번에 수정/추가할 수도 있음.
print(x)				# {'a': 900, 'b': 20, 'c': 30, 'd': 40, 'e': 90, 'f': 60}

 

- 여기서 주의할 점은, setdefault 메서드로는 수정이 불가능하며, update 메서드는 키의 형식이 문자열일 때만 괄호 안에 넣을 수 있다는 것이다. (그래서 괄호 안에 넣을 때 작은따옴표를 붙이지 않음.)

 

- 그래서 만약 키의 형식이 문자열이 아니라면, 다음과 같은 방법을 사용해야 한다.

# 1. 괄호 안에 딕셔너리를 넣기
y = {1 : 'one', 2 : 'two'}
y.update({1 : 'ONE', 3 : 'THREE'})	# 이처럼 딕셔너리를 update 메서드 안에 직접 넣는다.
print(y)					# {1: 'ONE', 2: 'two', 3: 'THREE'}

# 2. 리스트와 튜플 이용하기
# 리스트 -> [[key1, val1], [key2, val2]] 형식으로 [[키, 값], [키, 값]] 처럼 넣어줌.
# 튜플도 마찬가지이다.
y = {1 : 'one', 2 : 'two'}
y.update([[2 , 'TWO'], [4, 'FOUR']])
print(y)					# {1: 'one', 2: 'TWO', 4: 'FOUR'}

# 3. zip 객체와 같이 키-값 쌍으로 된 반복 가능한 객체
y = {1 : 'one', 2 : 'two'}
y.update(zip([1, 2], ['ONE', 'TWO']))
print(y)					# {1: 'ONE', 2: 'TWO'}

 


삭제

- 딕셔너리에서 키-값 쌍을 삭제하는 메서드는 다음 종류가 있다.

- pop 메서드 : 딕셔너리_이름.pop(키) 형태로 사용, 특정 키-값 쌍을 삭제한 뒤 그 값을 반환함.

- del 메서드 : del 딕셔너리_이름[키] 형태로 사용, 딕셔너리의 특정 키-값을 삭제함.

- popitem() 메서드 : 임의의 키-값 쌍을 삭제, 그 키-값 쌍을 반환함. pop메서드는 값만을 반환하지만 이 메서드는 키-값쌍을 튜플로 반환함.

- clear() 메서드 : 딕셔너리의 모든 키-값 쌍을 삭제함.

 

# pop 메서드
x = {'one' : 1, 'two' : 2, 'three' : 3}
x.pop('one')					# 1
print(x)						# {'two': 2, 'three': 3}

- ** 만약 내가 없애고자 한 키가 그 딕셔너리에 없을 경우, 오류가 난다. (리스트에서 범위 밖의 인덱스를 지정한 것과 비슷한 맥락으로 이해하면 될 것 같다)

- 이때 pop 메서드 안에 기본값을 지정해 주면 키가 없을 경우 기본값을 반환한다.

pop 기본값 지정

# del 메서드
x = {'one' : 1, 'two' : 2, 'three' : 3}
del x['one']
print(x)					# {'two': 2, 'three': 3}

- 또한 마찬가지로 del도 존재하지 않는 키를 입력하면 오류가 난다. 

del 키 오류

 


가져오기

- get() 메서드 : 딕셔너리에서 특정 키의 값을 가져온다.

- items() 메서드 : 딕셔너리의 키-값 쌍을 '모두' 가져온다.

- keys() 메서드 : 딕셔너리의 키를 '모두' 가져온다.

- values() 메서드 : 딕셔너리의 값을 '모두' 가져온다.

- items, keys, values 메서드는 for 반복문과 조합해서 사용한다고 한다.

# get 메서드
x = {'one' : 1, 'two' : 2, 'three' : 3}
x.get('one')					# 1

# 이렇게 할 수도 있다.
x['one']						# 1

- 여기서도 pop메서드처럼 기본값을 설정하면, 만약 키가 없을 경우 기본값을 반환한다.

# items 메서드
x = {'one' : 1, 'two' : 2, 'three' : 3, 'four' : 4}
x.items()					# dict_items([('one', 1), ('two', 2), ('three', 3), ('four', 4)])

# keys 메서드
x.keys()					# dict_keys(['one', 'two', 'three', 'four'])

# values 메서드
x.values()					# dict_values([1, 2, 3, 4])

- 혹시나 해서 각 메서드들의 반환값의 표현형을 type() 메서드를 이용해 봤는데 다음과 같다.

 


만들기

- 리스트/튜플로도 딕셔너리를 만들 수 있다.

- dict.fromkeys() 메서드를 이용해 키 리스트로 딕셔너리를 만들 수 있다.

- 이때, 값을 지정하지 않으면 값은 모두 None이 된다.

# 리스트로 딕셔너리 만들기
keys = ['one', 'two', 'three', 'four']
x = dict.fromkeys(keys)
print(x)					# {'one': None, 'two': None, 'three': None, 'four': None}


# 값을 지정했을 때
x = dict.fromkeys(keys, 100)
print(x)					# {'one': 100, 'two': 100, 'three': 100, 'four': 100}

 


반복문 이용하기

- for 반복문 이용하기

# 모든 키 출력하기
x = {'one' : 1, 'two' : 2, 'three' : 3, 'four' : 4}
for i in x:
	print(i, end = ' ')
							# one two three four , 키만 출력됨.

# 키와 값 모두 출력하기
for key, value in x.items():
	print(key, value)
    						# one 1
                            # two 2
                            # three 3
                            # four 4

# 같은 방법으로, 키만 출력하기
for key in x.keys():
	print(key, end = ' ')	# one two three four 


# 값만 출력하기
for value in x.values():
	print(value, end = ' ')	# 1 2 3 4

 


딕셔너리 표현식

- 이 부분은 아직 이해가 필요해 이후에 추가하도록 하겠다.

728x90
반응형
LIST
728x90
반응형

- 문자열 일부 바꾸기

- s.replace('arr1', 'arr2')로 사용.
word = 'python is great'
word.replace('python', 'c')
print(word) 				#c is great

- 만약 문자열이 일치하지 않는 경우 -> 

word.replace('bython', 'c')
print(word)			# python is great

=> 바꿀 문자를 찾지 못하고 그대로 출력된다.

응용 => 문자열 A가 있을시에 A를 문자열 B로 바꾸는 프로그램을 만들 때 A가 있는지부터 검사할 필요 없이 바로. replace('A', 'B') 하면 된다.

 


 

- 문자 바꾸기

- translate(str.maketrans('aeiou', '12345'))으로 사용.
- table = str.maketrans('aeiou', '12345')), apple.translate(table) 으로도 사용 가능.
word = 'python is great'
word.translate(str.maketrans('pt', '12'))
print(word)		# 1y2hon is grea2

 


 

- 문자열 분리하기

'arr1'.split() 사용

# 그냥 빈칸만 있을 때 구분
'apple pear grape pineapple orange'.split()
# ['apple', 'pear', ..., 'orange']

# 컴마도 있을 때 구분
'apple, pear, grape, pineappple, orange'.split(', ')
# ['apple, 'pear', ..., 'orange']

 

- 문자열 연결하기

'문자열 사이 들어갈문자'.join(['arr1', 'arr2', ...]) 형태로 사용.

# 그냥 문자열을 합칠 때
' '.join(['apple', 'pear', 'grape', 'pineapple', 'orange'])
# 'apple pear grape pineapple orange'

# 문자열 사이에 특정 문자를 넣을 때
'-'.join(['apple', ..., 'orange'])
# 'apple-pear-grape-pineapple-orange'

 


- 소문자 -> 대문자 (모든 소문자는 대문자로, 대문자는 그대로)

.upper() 사용

'python'.upper()
# PYTHON

- 대문자 -> 소문자  (위의 규칙과 동일)

.lower() 사용

'PYTHON'.lower()
# python

 


 

- 좌우 특정 문자 삭제하기

# 문자 왼쪽에 있는 특정 문자 삭제
'     python     '.lstrip()
# 'python     ', 왼쪽 공백만 삭제

# 문자 오른쪽 삭제
'     python     '.rstrip()
# '     python', 오른쪽 공백만 삭제

# 양쪽 문자 삭제
'     python     '.strip()
# 'python', 양쪽 공백 삭제

# 괄호 안에 특정 문자 넣어주면 해당 문자 삭제
# '문자열1'.strip(',.') 이면
# 문자열 양쪽에서 ','와 '.' 문자 삭제

 


 

- 문자열 정렬하기

ljust(길이) -> 좌측 정렬, 남는 공간 공백으로, 만약 길이가 현재 문자열 길이보다 짧으면 실행 x

rjust(길이) -> 우측 정렬

center(길이) -> 가운데 정렬, 남는 공백 길이가 홀수면 왼쪽에 공백 한 칸이 더 들어감

# 우측정렬
'python'.rjust(10)
# '    python'

# 좌측정렬
'python'.ljust(10)
# 'python    '

# 가운데정렬
'python'.center(10)
# '  python  '

 


 

- 문자열 왼쪽에 0 채우기

zfill(길이) 형태로 사용

# 자릿수 앞에 0을 채워야 할 때
'35'.zfill(4)
# '0035'

# 그냥 문자열도 가능(당연하지만)
'hello'.zfill(10)
# '0000hello'

 


 

- 문자열 위치 찾기

특정 문자열의 인덱스를 찾을 때(왼쪽에서부터 찾음)

-> find('찾을 문자열')

오른쪽에서부터 찾을 때

-> rfind('찾을 문자열')

* 없을 시 -1 반환

 

또는

-> index('특정 문자열')

-> rindex('특정 문자열')

* 없을 시 에러 발생

 

- 문자열 개수 세기

count('특정 문자열')

 


 

- 문자열 만들기

1. 문자열 서식 지정자

2. 문자열 포메팅(f-string)

 

1 - 문자열 서식 지정자

# 문자열 넣기
'I am %s' % 'james'		# 'I am james'

# 숫자 넣기
'This watch is %d dollars'		# 'This watch is 5 dollars'

# 소숫점 표현하기
'%f' % 3.5			# '3.500000', 소숫점 이하 6자리까지 표현
'%.2f' % 3.5		# '3.50', .nf 형태 -> n자리까지 표현

# 문자열 정렬하기
'%10s' % 'python'	# '    python'

# 왼쪽 정렬
'%-10s' % 'python' 	# 'python    '

# 정수 자릿수 맞추기
'%5d' % 15			# '   15'
'%5d' % 100 		# '  100'

# 소숫점으로 자릿수와 소숫점 이하 자릿수 표현하기
'%10.2f' % 2000.3	# '   2000.30'

# 한 번에 여러 개 서식 지정자 사용하기
'Today is %d %s' % (3, 'April')		# 'Today is 3 April'

 

2 - 문자열 포매팅

 

- 서식 지정자보다 더 간단한 방법이라는 문자열 포매팅이다.

- {} 안에 포매팅을 지정하고, format메서드로 값을 넣는다.

'hello, {0}'.format('world!')		# 'hello, world!' 출력
# 이처럼 문자열 안에 {}을 넣고, 인덱스를 지정한다. 
# format()부분에는 {}부분에 넣을 값을 지정한다.

# 값 여러 개 넣기
'Hello, {0} {2} {1}'.format('Python', 'Script', 3.6)		# 'Hello, Python 3.6 Script'

'{0} {0} {1} {1}'.format('Python', 'Script')		# 'Python Python Script Script'

# 인덱스 생략 -> 지정한 순서대로 값이 들어감
'Hello, {} {} {}'.format('Python', 'Script', 3.6)	# 'Hello, Python Script 3.6'

# 또는 이름 지정 가능.
'Hello, {language} {version}'.format(language = 'Python', version = 3.6)	# 'Hello, Python 3.6'

# Python 3.6부터는 앞에 f를 붙이고 중괄호 안에 바로 변수 입력 가능
language = 'Python'
version = 3.6
print(f'Hello, {language} {version}')		# Hello, Python 3.6


# 문자열 정렬하기
print('{0:<10}'.format('Python'))		# Python

# '{인덱스 : 방향 길이}'.format() 형식으로 작성
# 인덱스는 없을 시 생략 가능

# 숫자 개수 맞추기
# 1. 서식 지정자
print('%03d' % 15)		# '015' ,  문자열로 나옴

# 2. format메서드
print('{:03d}'.format(15))		# 015, 정수로 나옴
# 실수
print('{0:08.2f}'.format(150.37))	# 00150.37


# 결론 : format은 '{인덱스 : 채우기 정렬 길이 .자릿수}'.format 형식으로 사용.
print('{:0<10}'.format(15))		# 1500000000


# 팁, 금액에서 천 단위로 ','을 넣는 것을 format함수를 이용해 할 수 있다.
print(format(1493500, ','))		# 1,493,500
728x90
반응형
LIST

+ Recent posts