// 스프링 시큐리티 의존성
implementation('org.springframework.boot:spring-boot-starter-oauth2-client')
    
@SpringBootApplication(exclude = SecurityAutoConfiguration.class) <= 이부분 추가

'spring boot > setting' 카테고리의 다른 글

.gitignore파일 제대로 동작하지 않는다면?  (0) 2023.11.13

.gitignore가 제대로 동작하지 않아서 ignore처리된 파일이 changed 파일에 계속 뜨는 경우

 


1.1 원인

.gitignore에 파일을 추가하기 전에 stage에 올라간 파일들이 캐시처리되어 기록이 남아있기 때문


1.2 해결

 

git rm -r --cached .
git add .
git commit -m "fixed untracked files"
git push origin 자신의 branch

 

👍 해결완료

'spring boot > setting' 카테고리의 다른 글

Spring Security 기본 로그인 화면 제거  (0) 2023.11.14

난이도: G4

문제풀이 : stack 이용

 

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

int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;

    stack<pair<int, int>> stk;
    vector<int> res(n, -1);

    int x;
    for (int i = 0; i < n; i++)
    {
        cin >> x;

        while (!stk.empty() && stk.top().second < x)
        {
            res[stk.top().first] = x;
            stk.pop();
        }

        stk.push({i, x});
    }

    for (auto v : res)
        cout << v << " ";

    return 0;
}

'알고리즘' 카테고리의 다른 글

[백준 15683번] 감시 C++  (0) 2023.12.18
[백준 12100번] 2048 C++  (2) 2023.11.18
백준[2230번] 수 고르기 C++  (0) 2023.11.06
백준[1351번] 무한수열 C++  (0) 2023.11.06
백준[15663번] N과 M(9)  (2) 2023.10.31

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

int n;
long long m;
vector<long long> v;

long long res = INT_MAX;
void selectedNum(int start, int end)
{
    while (start <= end && end < n)
    {
        if (v[end] - v[start] == m)
        {
            res = m;
            return;
        }
        else if (v[end] - v[start] > m)
        {
            res = min(res, v[end] - v[start]);
            start++;
        }
        else
        {
            end++;
        }
    }
}

int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;

    long long x;
    for (int i = 0; i < n; i++)
    {
        cin >> x;
        v.push_back(x);
    }

    sort(v.begin(), v.end());

    selectedNum(0, 0);

    cout << res;

    return 0;
}

 

 

'알고리즘' 카테고리의 다른 글

[백준 12100번] 2048 C++  (2) 2023.11.18
백준[17298번] 오큰수 C++  (0) 2023.11.07
백준[1351번] 무한수열 C++  (0) 2023.11.06
백준[15663번] N과 M(9)  (2) 2023.10.31
백준[2133번] 타일 채우기  (0) 2023.10.30

 

https://www.acmicpc.net/problem/1351

 

1351번: 무한 수열

첫째 줄에 3개의 정수 N, P, Q가 주어진다.

www.acmicpc.net

 

해당 문제는 dp와 hash를 적용하여 문제를 해결하였다,

 

처음에, dp만을 활용하여 재귀함수 호출을 통해서 문제를 제출했으나, 시간 초과가 발생하였다. 아무래도 n <= 10^ 12, p, q <= 10^9이다보니, memorization을 활용하지 않아서 그런 것 같다.

* 해당 문제는 Top-down 방식으로 dp를 해결하다보니 memorization이 필요하다.

따라서 map STL 라이브러리를 사용하여 해결하는데, 해당 문제에서 dp의 순서는 크게 상관없기때문에 상대적으로 더 간단한 unordered_map을 활용한다. 또한 배열로 선언하기에는 n이 너무 크므로, map을 활용하여 필요한 값들만 따로 저장해두므로 훨씬 편리하다.

또한, 

A[0] = 1

A[i] = A[i/p] + A[j/q] 이므로 다음과 같이 코드를 작성하였다.

#include <iostream>
#include <unordered_map>
using namespace std;

long long n, p, q;
long long res = 0;
unordered_map<long long, long long> m;

long long solution(long long x)
{
    if (x == 0)
        return 1;

    if (m[x] != 0)
    {
        return m[x];
    }
    else
    {
        return m[x] = solution(x / p) + solution(x / q);
    }
}

int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> p >> q;

    m[0] = 1;
    cout << solution(n);

    return 0;
}

'알고리즘' 카테고리의 다른 글

백준[17298번] 오큰수 C++  (0) 2023.11.07
백준[2230번] 수 고르기 C++  (0) 2023.11.06
백준[15663번] N과 M(9)  (2) 2023.10.31
백준[2133번] 타일 채우기  (0) 2023.10.30
백준[3197번] 백조와 호수  (0) 2023.09.19

* 하나의 sentence로 이루어진 문장에서 단어별로 분리하기

 

#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    string a = "It is time to study", res;

    int pos, max = INT_MIN;
    while ((pos = a.find(' ')) != string::npos)
    {
        string tmp = a.substr(0, pos);
        int len = tmp.size();
        if (len > max)
        {
            max = len;
            res = tmp;
        }

        cout << tmp << '\n';
        a = a.substr(pos + 1);
    }

    if (a.size() > max)
    {
        max = a.size();
        res = a;
    }

    cout << res << '\n';

    return 0;
}

 

<algorithm> 헤더파일을 통해서 string 안에 소문자, 대문자, 숫자를 구별할 수 있다.

substr(pos, cnt) : pos부터 cnt개수만큼 꺼내온다.

vector와 같이 push_back(), pop_back()로 값을 넣어줄 수 있다.

clear(): string을 비운다.

 

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string a = "Time is 2023Year 10Month";
    cout << a.size() << '\n';

    for (int i = 0; i < a.size(); i++)
    {
        cout << a[i] << " ";
    }
    cout << '\n';

    for (int i = 0; i < a.size(); i++)
    {
        if (isupper(a[i]))
        {
            cout << a[i] << " ";
        }
    }
    cout << '\n';

    for (int i = 0; i < a.size(); i++)
    {
        if (islower(a[i]))
        {
            cout << a[i] << " ";
        }
    }
    cout << '\n';

    for (int i = 0; i < a.size(); i++)
    {
        if (isdigit(a[i]))
        {
            cout << a[i] << " ";
        }
    }
    cout << '\n';

    cout << a.find('Y') << '\n';

    a.push_back('a');
    cout << a << '\n';

    a.pop_back();
    cout << a << '\n';

    a += " 31day";
    cout << a << '\n';

    cout << a.substr(8) << '\n';
    cout << a.substr(8, 4) << '\n';
    a.clear();

    cout << a << '\n';

    return 0;
}

bool visited[10] : 자신과 중복되는 값을 제거하기 위해 사용

int xx : 중복순열을 제거하기 위해 이전에 입력한 값을 저장하고, 현재 받으려는 값과 비교하여 값이 같으면 중복 수열이므로 넘어가준다.

 

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

int n, m;
vector<int> v;
int res[10];
bool visited[10];

void dfs(int cnt)
{
    if (cnt == m)
    {
        for (int i = 0; i < m; i++)
        {
            cout << res[i] << " ";
        }
        cout << '\n';
        return;
    }
    else
    {
        int xx = 0;
        for (int i = 0; i < v.size(); i++)
        {
            if (visited[i] || v[i] == xx)
            {
                continue;
            }

            visited[i] = true;
            res[cnt] = v[i];
            xx = v[i];
            dfs(cnt + 1);
            visited[i] = false;
        }
    }
}
int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;

    int x;
    for (int i = 0; i < n; i++)
    {
        cin >> x;

        v.push_back(x);
    }

    sort(v.begin(), v.end());

    dfs(0);

    return 0;
}

 

'알고리즘' 카테고리의 다른 글

백준[2230번] 수 고르기 C++  (0) 2023.11.06
백준[1351번] 무한수열 C++  (0) 2023.11.06
백준[2133번] 타일 채우기  (0) 2023.10.30
백준[3197번] 백조와 호수  (0) 2023.09.19
백준[1655번] 가운데를 말해요  (0) 2023.09.19

참고자료: https://yabmoons.tistory.com/536

 

[ 백준 2133 ] 타일 채우기 (C++)

백준의 타일채우기(2133) 문제이다.[ 문제 바로가기 ] [ 문제풀이 ]3 x N 크기의 벽을 2 x 1 , 1 x 2 타일들로만 채울 때, 그 경우의 수를 구해야 하는 문제이다.작은 수들부터 차근차근 만들어보면서 하

yabmoons.tistory.com

사용되는 알고리즘 : dp

* 특별한 경우를 잘 확인해야한다. => 이전 타일을 이용해서 쌓아가는 걸 제외하고 특별한 모양

* n이 홀수일 경우는 애초에 고려하지 않는다. => 3 * odd의 경우 넓이는 홀수값이 되는데 2*1 또는 1*2로 채우는 경우는 값이 무조건 짝수가 나와야 한다.

#include <iostream>
using namespace std;

int dp[31];

int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;

    dp[0] = 1;
    dp[2] = 3;

    if (n % 2 == 1)
    {
        cout << 0;
        return 0;
    }

    for (int i = 4; i <= n; i += 2)
    {
        dp[i] = dp[i - 2] * dp[2];

        for (int j = i - 4; j >= 0; j -= 2)
        {
            dp[i] += 2 * dp[j];
        }
    }

    cout << dp[n];

    return 0;
}

참고자료에 올린 블로그에서 설명을 자세하게 해주어서 이해하는데 많은 도움이 되었다.

'알고리즘' 카테고리의 다른 글

백준[1351번] 무한수열 C++  (0) 2023.11.06
백준[15663번] N과 M(9)  (2) 2023.10.31
백준[3197번] 백조와 호수  (0) 2023.09.19
백준[1655번] 가운데를 말해요  (0) 2023.09.19
백준 14889번 스타트와 링크  (0) 2023.09.07

1. 유틸리티 

타임리프에서 자바8 날짜인 LocalDate, LocalDateTime, Instant를 사용하려면 추가 라이브러리 필요 -> 스프링 부트 타임리프를 사용하면 자동으로 추가(걱정 X)

 

사용예시

// basic/date.html
<span th:text="${#temporals.format(localDate, 'yyyy-MM-dd HH:mm:ss')}"></span>

// BasicController 추가
@GetMapping("/date")
public String date(Model model) {
	model.addAttribute("localDateTime", LocalDateTime.now());
    return "basic/date";
}

2. URL 링크

// BasicController 추가
@GetMapping("/link")
  public String link(Model model) {
      model.addAttribute("param1", "data1");
      model.addAttribute("param2", "data2");
      return "basic/link";
}

// basic/link.html
<ul>
      <li><a th:href="@{/hello}">basic url</a></li> // 1
      <li><a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query param</a></li> // 2
      <li><a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}">path variable</a></li> // 3
      <li><a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">path variable + query parameter</a></li> // 4
</ul>

1. 단순한 URL: /hello

2. 쿼리 파라미터: /hello?param1=data1&param2=data2

3. 경로 변수: /hello/data1/data2

4. 경로 변수 + 쿼리 파라미터: /hello/data1?param2=data2

 

3. 리터럴(Literals)

// 타임리프에서 문자 리터럴은 항상 '로 감싸야 한다.
<span th:text="'hello'">
// 하지만 너무 귀찮고~ => 공백 없이 쭉 이어진다면 하나의 의미있는 토큰으로 인지 -> 생략 가능
<span th:text="hello"> (o)
<span th:text="hello world"> (x)
<span th:text="'hello world'"> (o)
<span th:text="'hello' + ' world!'"> (o)
<span th:text="'hello ' + ${data}"> (o)
<span th:text="|hello ${data}|"> (o) // -> 리터럴 대체 문법 : 마치 템플릿을 사용하는 것처럼 편하쥬

// 추가 예정 // 

4. 연산

5. 속성 값 설정

6. 반복

7. 조건부 평가

8. 주석

9. 블록

10. 자바스크립트 인라인

11. 템플릿 조각

12. 템플릿 레이아웃

'spring boot' 카테고리의 다른 글

스프링 포맷터(Formatter)  (0) 2023.11.23
스프링 타입 컨버터 - Converter  (1) 2023.11.23
타임리프(Thymeleaf) 정리  (2) 2023.10.19

타임리프 특징

1. 서버 사이드 HTML 렌더링(SSR): 타임리프는 백엔드 서버에서 HTML을 동적으로 렌더링하는 용도로 사용된다.

2. 네츄럴 템플릿: 순수 HTML을 그대로 유지하면서 뷰 템플릿도 사용할 수 있는 타임리프의 특징을 네츄럴 템플릿

3. 스프링 통합 지원: 타임리프는 스프링과 자연스럽게 통합되고, 스프링의 다양한 기능을 편리하게 사용할 수 있게 지원한다.

 

타임리프 사용 선언

<html xmlns:th="http://thymeleaf.org">

 

타임리프의 텍스트 출력 - text, utext

HTML 태그의 속성에 기능을 정의해서 동작한다. HTML의 콘텐츠(content)에 데이터를 출력 => th:text

<span th:text-"${data}">

HTML 태그의 속성이 아니라 HTML 콘텐츠 영역안에서 직접 데이터를 출력하고 싶으면 다음과 같이 [[...]]를 사용하면 된다.

컨텐츠 안에서 직접 출력하기 = [[${data}]]

 

HTML엔티티 - 웹 브라우저는 <를 HTML 태그의 시작으로 인식한다. 따라서 <를 태그의 시작이 아니라 문자로 표현할 수 있는 방법이 필요한데 이것을 HTML 엔티티라고 한다.

 

이스케이프(escape) - HTML에서 사용하는 특수 문자를 HTML엔티티로 변경하는 것.

th:text, [[...]]는 기본적으로 이스케이프를 제공

====> 이스케이프를 사용하지 않으려면

th:text -> th:utext

[[...]] -> [(...)]

 

th:inline="none": 타임리프는 [[...]]를 해석하기 때문에, 화면에 [[...]]글자를 보여줄 수 없다. 이 테그 안에서는 타임리프가 해석하지 말라는 옵션

ex)

<li><span th:inline="none">[[...]] = </span> [[${data}]]</li> -> 이스케이프된채로(=문자 그대로 출력된다.)

<li><span th:inline="none">[[...]] = </span> [(${data})]</li> -> 이스케이프되지 않아서 태그를 그대로 받아들여짐

 

변수 - 스프링에서는 SpringEL이라는 스프링이 제공하는 표현식을 사용

 

@GetMapping("/variable")
  public String variable(Model model) {
      User userA = new User("userA", 10);
      User userB = new User("userB", 20);
      
      List<User> list = new ArrayList<>();
      list.add(userA);
      list.add(userB);
      
      Map<String, User> map = new HashMap<>();
      map.put("userA", userA);
      map.put("userB", userB);
      
      model.addAttribute("user", userA);
      model.addAttribute("users", list);
      model.addAttribute("userMap", map);
      
      return "basic/variable";
  }

 

 

<!DOCTYPE html>
  <html xmlns:th="http://www.thymeleaf.org">
  <head>
      <meta charset="UTF-8">
      <title>Title</title>
  </head>
<body>
<h1>SpringEL 표현식</h1> <ul>Object
      <li>${user.username} =
      <li>${user['username']} = <span th:text="${user['username']}"></span></li>
      <li>${user.getUsername()} = <span th:text="${user.getUsername()}"></span></
  li>
  </ul>
  <ul>List
      <li>${users[0].username}    = <span th:text="${users[0].username}"></
  span></li>
      <li>${users[0]['username']} = <span th:text="${users[0]['username']}"></
  span></li>
      <li>${users[0].getUsername()} = <span th:text="$
  {users[0].getUsername()}"></span></li>
  </ul>
  <ul>Map
      <li>${userMap['userA'].username} =  <span th:text="$
  {userMap['userA'].username}"></span></li>
      <li>${userMap['userA']['username']} = <span th:text="${userMap['userA']
  ['username']}"></span></li>
  <li>${userMap['userA'].getUsername()} = <span th:text="$
  {userMap['userA'].getUsername()}"></span></li>
  </ul>
  </body>
</html>

 

지역변수 선언

th:with 사용

ex)

<div th:with="first=${users[0]}">

  <p><span th:text="${first.username}"></span>

</div>

 

기본 객체들은 스프링 부트 3.0이상부터 model에 넣어서 관리한다.

@GetMapping("basic-objects")
public String basicObjects(Model model, HttpServletRequest request,
	HttpServletResponse response, HttpSession session) {
    session.setAttribute("sessionData", "Hello Session");
    model.addAttribute("request", request);
    model.addAttribute("response", response);
    model.addAttribute("servletContext", request.getServletContext());
    return "basic/basic-objects";
}

@Component("helloBean")
static class HelloBean {
	public String hello(String data) {
    	return "Hello " + data;
    }
}

 

 

<!DOCTYPE html>
  <html xmlns:th="http://www.thymeleaf.org">
  <head>
      <meta charset="UTF-8">
      <title>Title</title>
  </head>
<body>
<h1>식 기본 객체 (Expression Basic Objects)</h1> <ul>
      <li>request = <span th:text="${request}"></span></li>
      <li>response = <span th:text="${response}"></span></li>
      <li>session = <span th:text="${session}"></span></li>
      <li>servletContext = <span th:text="${servletContext}"></span></li>
      <li>locale = <span th:text="${#locale}"></span></li>
</ul>
<h1>편의 객체</h1> <ul>
      <li>Request Parameter = <span th:text="${param.paramData}"></span></li>
      <li>session = <span th:text="${session.sessionData}"></span></li>
      <li>spring bean = <span th:text="${@helloBean.hello('Spring!')}"></span></
li> </ul>
  </body>
  </html>

'spring boot' 카테고리의 다른 글

스프링 포맷터(Formatter)  (0) 2023.11.23
스프링 타입 컨버터 - Converter  (1) 2023.11.23
타임리프 정리-2  (0) 2023.10.27

+ Recent posts