'프로그래밍' 태그의 글 목록 :: 잡다한 프로그래밍
반응형

1. 문법의 차이

#1) #을 이용한 경우

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user WHERE id = #{id}
</select>

다음과 같은 SELECT문을 작성하였을경우 아래와 같이 ?에 파라미터가 바인딩 되어 수행된다 이렇게 파싱된 쿼리문은 재활용(캐싱)되므로 효율적이다.

SELECT name FROM user WHERE id = ?

 또한 변수에 작은 따옴표(')가 붙어 쿼리가 수행되므로 '#{id}'라고 쿼리문을 작성할 필요가 없다. 대신 다음과 같이 사용할 수 없다. 아래와 같이 사용할 경우 user_'tableName'이 되어버리므로 에러가 발생한다.

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user_#{tableName} WHERE id = #{id}
</select>

 

#2) $를 이용한 경우

반면 $를 이용하게 되면 파라미터값이 바뀔 때마다 새로운 쿼리문의 파싱을 진행해야해서 성능상 단점이 존재한다.

또한 쿼리문에 #{}과 다르게 작은 따옴표(')가 붙지 않아서 테이블 이름이나 컬럼이름을 동적으로 결정할때 사용할 수 있다.

<select id="select" resultType="String" parameterType="Map">
    SELECT name FROM user_${tableName} WHERE id = #{id}
</select>

2. SQL Injection 차이

보안적으로 #과 $에는 차이가 존재한다. #은 $보다 보안에 안전하다 다음과 같은 예시를 보자

<select id="select" parameterType="Map" resultType="...">
    SELECT * FROM user WHERE id = '${id}' AND password = '${password}'
</select>

만약 이때 사용자가 id 값에 root' --를 입력했다고 가정하면 다음과 같은 결과를 초래한다.

SELECT * FROM user WHERE id = 'root' -- 'AND password = ''

사용자는 비밀번호를 입력하지 않았지만 뒷부분이 주석처리되어 로그인에 성공하게되어버린다 따라서 $는 #보다 SQL Injection에 취약하다

반응형
반응형

 

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

 

1068번: 트리

첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다. 셋째 줄에는 지울 노드의 번호가 주어진다.

www.acmicpc.net

1. 해결방법

열 단위로 램프가 켜지기 때문에 같은 패턴을 띄어야만 행의 램프가 켜질 수 있다 따라서 1행이 0 1 이라면 나머지 2 3행에서 0 1 패턴이 있는지 찾고 이를 반복적으로 수행하면 된다. 또한 0의 개수가 K보다작은지, K%2 = 0%2인지 비교해주면 된다


2. 코드

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

int N, M, K;
string ary[51];
int max_value = 0;

int main()
{
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		cin >> ary[i];
	}
	cin >> K;
	
		for (int j = 0; j < N; j++) {
			int zero_cnt = 0;
			for (int k = 0; k < M; k++) {
				if (ary[j][k] == '0') {
					zero_cnt++;
				}
			}
			int cnt = 0;
			if (zero_cnt <= K && zero_cnt % 2 == K % 2) {
				for (int m = 0; m < N; m++) {
					if (ary[j] == ary[m]) {
						cnt++;
					}
				}
			}
			max_value = max(max_value, cnt);
		}
		cout << max_value;
}
반응형

'코딩테스트 > 백준' 카테고리의 다른 글

[백준] #1197 램프  (0) 2020.05.08
[백준] #1012 유기농 배추  (0) 2020.04.06
[백준] #1068 트리  (0) 2020.03.29
반응형

https://swexpertacademy.com/main/main.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

1. 해결방법

많이 볼 수 있는 DFS 문제로 좌, 우, 아래 순으로 한 번만 체크하는 방식으로 해결하면 금방 풀 수 있을 거라 생각했다.


2. 에러

먼저 100X100 배열을 가로로 입력받아야 하는데 다음과 같은 코드로 세로를 먼저 받게 입력받았다. 이사실을 오랫동안 알아차리지 못해 문제에 오류가 생겼다. 주의하자 array[i][j]가 아닌 [j][i] 여야 한다

        for(int i = 0; i < 100; i++){
            for(int j = 0; j < 100; j++){
                cin >> array[i][j];
            }
        }

3. 코드

#include<iostream>

using namespace std;
int array[100][100] = {0};
int chk_array[100][100] = {0};
int result = 0;
int max_value = 9999;
int nx[3] = {-1, 1, 0};
int ny[3] = {0, 0, 1};

void dfs(int x, int y, int start, int count){
    if (y == 99){
        if(count <= max_value){
            max_value = count;
          	result = start;
        }
    }
    else{
        for(int i = 0; i < 3; i ++){
     		int dx = x + nx[i];
        	int dy = y + ny[i];

        	if(dx < 0 || dx >= 100 || dy < 0 || dy >= 100 || chk_array[dx][dy] == 1 || array[dx][dy] == 0 || (y == 0 && i == 0) || (y == 0 && i ==1)) continue;
			else{
                chk_array[dx][dy] = 1;
             	dfs(dx, dy, start, count+1);
                chk_array[dx][dy] = 0;
                break;
            }
    	}
        
    }    
}

int main(int argc, char** argv)
{
   int test_case;
   int T;   
   for(test_case = 1; test_case <= 10; ++test_case)
   {
      cin>>T;
        for(int i = 0; i < 100; i++){
            for(int j = 0; j < 100; j++){
                cin >> array[j][i];
            }
        }
        result = 0; max_value = 9999;
        for(int k = 0; k < 100; k++){
            chk_array[k][0] = 1;
            dfs(k, 0, k, 1);
            chk_array[k][0] = 0;
        }
        cout << "#" << test_case << " " << result << endl;

   }
   return 0;//정상종료시 반드시 0을 리턴해야합니다.
}
반응형
반응형

 

https://swexpertacademy.com/main/main.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

1. 해결방법

벡터를 사용하여 방향 그래프를 저장하였고, 이를 DFS완전 탐색으로 해결하였다


2. 에러 사항

vector를 초기화해주지 않아서 탐색 시간이 길어져 시간 초과가 생겼는데 clear() 함수가 제대로 작동하지 않아서 dfs함수에 vector를 넘겨주고 vector를 전역 변수가 아닌 메인 함수 내부에 선언하는 방식으로 해결하였다


3. 코드

#include<iostream>
#include<vector>
using namespace std;
int test_case;
int T;
int num;
int x, y;
int result = 0;

void vector_dfs(int now, vector<int>* vector){
    if(now == 99){
		result = 1;
        return;
    }else{
        for(int i = 0; i < vector[now].size(); i++){
                        vector_dfs(vector[now][i], vector);    
        }
    }
}

int main(int argc, char** argv)
{
	for(test_case = 1; test_case <= 10; ++test_case)
	{
		cin >> T;
        cin >> num;
		vector<int> vec[100];
        
        for(int i = 0; i < num; i++){
            cin >> x;
            cin >> y;
            vec[x].push_back(y);
        }
        result = 0;
        vector_dfs(0, vec);
            cout << "#" << test_case <<" " << result << endl;
    }
	return 0;//정상종료시 반드시 0을 리턴해야합니다.
}
반응형
반응형

https://swexpertacademy.com/main/main.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

1. 해결방법

1-1 오류발생

먼저 한 사람씩 비교하여 방문지로 체크했다가 다음 사람은 전에 방문했던적이 있는지 없는지 비교하여 cnt를 ++ 해주는 방법을 사용하였으나 첫방문자가 1~400까지 방문했을경우 나머지는 모두 ++ 되어버리는 오류가 존재하였다

 

1-2 오류코드

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

int N;
int now_room;
int next_room;
int cnt = 0;
int room[401] = {0};
int now_check;
int next_check;

int main(int argc, char** argv)
{
    int test_case;
    int T;
    cin>>T;
    for(test_case = 1; test_case <= T; ++test_case)
    {
        memset(room, 0 , sizeof(room));
        cnt = 1;
        cin>>N;
        for(int i = 0; i < N; i++){
            cin >> now_room;
            cin >> next_room;
            if(now_room > next_room){
                swap(now_room, next_room);
            }
            
            for(int k = now_room; k<=next_room; k++){
                if(room[k]){
                     cnt++;
                    break;
                }
            }
            
                for(int j = now_room; j <= next_room; j++){
                    room[j] = 1;
                }
            
        }
        cout << "#" << test_case << " " << cnt << endl;
    }
    return 0;//정상종료시 반드시 0을 리턴해야합니다.
}

2. 해결

1번 방법과 비슷한대신 방문지를 ++해주고 마지막에 방문지중 가장 큰 값을 return한다 이방법으로 1번의 오류를 해결하였다

 

코드

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

int N;
int now_room;
int next_room;
int room[401] = {0};
int now_check;
int next_check;
int cnt = 0;
int main(int argc, char** argv)
{
	int test_case;
	int T;
	cin>>T;
	for(test_case = 1; test_case <= T; ++test_case)
	{
		memset(room, 0 , sizeof(room));
        cin>>N;
        for(int i = 0; i < N; i++){
            cin >> now_room;
            cin >> next_room;
            if(now_room > next_room){
				swap(now_room, next_room);
            }

            if((now_room % 2) == 0) now_room--;
            if((next_room % 2) == 1) next_room++;
            
            for(int j = now_room; j <= next_room; j++){
             room[j]++;   
            }
        }
        cnt = *max_element(room, room+401);
        cout << "#" << test_case << " " << cnt << endl;
	}
	return 0;//정상종료시 반드시 0을 리턴해야합니다.
}
반응형
반응형

https://programmers.co.kr/learn/challenges?tab=all_challenges

 

프로그래밍 강의 | 프로그래머스

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

1. 해결방법

stack을 활용하여 올바른 괄호 문자열인지 확인하고, 나머지는 문제에서 제시한 방법대로 재귀함수를 진행한다


2. 코드

#include <string>
#include <string.h>
#include <vector>
#include <stack>
#include <iostream>
using namespace std;
    string answer = "";

bool check(string p){
    stack<char> st;
    for(int i = 0; i < p.length(); i++){
        if(!st.empty() && p[i] == ')'){
            if(st.top() == '(') {
                st.pop();
            }else {st.push(p[i]);} 
        }else {st.push(p[i]);}
    }

    if(st.empty()) return 1;
    else return 0;
}

string check_function(string p){
    if(p == "") return "";
    string u = "";
    string v = "";
    int left = 0;
    int right = 0;
    
    if(check(p)) {return p;}
    else{
        for(int i = 0; i < p.length(); i++){
            if(p[i] == '(') left++;
            else right++;
            if(left == right) {
                u = p.substr(0,left+right);
                v = p.substr(left+right, p.length());
                
                if(check(u)){ 
                    return u + check_function(v);
                }else{
                    string temp;
                    temp += "(";
                    temp += check_function(v);
                    temp += ")";
                    string temp2 = u.substr(1, u.length()-2);
                    for(int j = 0; j < temp2.length(); j++){
                        if(temp2[j] == '(') temp += ")";
                        else temp += "(";
                    }
                    return temp;
                }
                
            }
            
        }
    }
}

string solution(string p) {
    if(p == "") return "";
    answer = check_function(p);
    return answer;
}
반응형
반응형

 

https://programmers.co.kr/learn/challenges?tab=all_challenges

 

프로그래밍 강의 | 프로그래머스

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

1. 해결방법

문제에서 제시한 개수만큼 글자를 자르고 이전과 다음으로 저장하여 비교하는 방식을 사용하였다.


2. 코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;
int answer = 9999;
void check(int num, string s){
    int mok;
    if(s.length() % num == 0) mok = s.length() / num;
    else mok = s.length() / num + 1;
    string result = "";
    int check = 1;
    string pre; string next;
    for(int i = 0; i < mok-1; i++){
        pre = s.substr(i*num, num);
        next = s.substr((i+1) * num , num);
        
        if(pre == next) check++;
        else{
            if(check != 1) result += to_string(check) + pre;
            else result += pre;
            check = 1;
        }
    }
    if(check == 1) result += next;
    else result += to_string(check) + pre;
    if(result.length() < answer) answer = result.length();
    
}

int solution(string s) {
                answer = 9999;

    for(int i = 1; i <= s.length()-1; i++){
        check(i, s);
    }
    if(s.length() == 1) answer = 1;
        return answer;
}
반응형
반응형

https://swexpertacademy.com/main/main.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

1. 해결방법

먼저 전에 가능한 시험 점수라는 문제를 풀면서 가능한 모든 점수를 구하는 문제를 푼 기억이 있어서 같은 방법으로 해결하면 좋겠다 라는 생각을 하였다. 가능한 시험 점수라는 방법으로 문제를 해결했으나, 깔끔한 코드가 아닌 것 같아서 다른 방법이 존재할까 찾아보았고 dfs로 가능하다는걸 알았다. 어렵지 않았는데 왜 dfs로 해결해볼까?라는 생각을 하지 못했다.


2. 코드

#include<iostream>
#include<string.h>
using namespace std;
	int test_case;
	int N;
	int top_height;
	int array[300000];
	int temp = 0;
	int sum = 0;
	int result = 0;
int main(int argc, char** argv)
{
    cin>>test_case;
	for(int i = 1; i <= test_case; i++)
	{
		cin >> N;
        cin >> top_height;
            memset(array, 0, sizeof(array));
        array[0] = 1;
       	for(int j = 0; j < N; j++){
            cin >> temp;
            sum += temp;
            for(int k = sum; k>=0; k--){
             if(array[k] != 0){
                 array[k + temp]++;
             }
            }
        
        }
        
         for(int m = 0; m< 300000; m++){
         if(array[m] !=0 && m >= top_height){
         	result = m - top_height;
                              break;
         }
        }

        
        cout << "#"<<i<<" "<< result << endl;
    }
	return 0;//정상종료시 반드시 0을 리턴해야합니다.
}
반응형

+ Recent posts