본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[프로그래머스] 시저 암호 문제 및 해설 (C, C++, JAVA 자바)

오랜만에 돌아온 프로그래머스 문제 풀이예요 ㅎㅎ

 

[Level 1]

시저 암호

문제

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 AB는 1만큼 밀면 BC가 되고, 3만큼 밀면 DE가 됩니다. z는 1만큼 밀면 a가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해보세요. 

 

제한 조건

공백은 아무리 밀어도 공백입니다.

s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.

s의 길이는 8000이하입니다.

n은 1이상, 25이하인 자연수입니다.

입출력 예시

s

n

result

"AB"

1

"BC"

"z"

1

"a"

"a B z"

4

"e F d"

기본 제공 

[C++언어]

#include <string>
#include <vector>
using namespace std;
string solution(string s, int n) {
    string answer = "";
    return answer;
}

[Java언어]

class Solution {
  public String solution(String s, int n) {
      String answer = "";

      return answer;
  }
}

 

ANSWER!!

시저 암호는 가장 오래된 방법 중 하나면서도 심플한 암호법이예요.

▼관련 포스팅은 여기로!

 

[암호학] 카이사르 암호법, 시저 암호법, 가장 오래된 고전 암호법

안녕하세요!! 이번에는 암호학 관련된 글로 찾아왔어요 ㅎㅎ 오늘 살펴볼 암호법은 가장 오래된 암호법 중 하나로 꼽히면서~~~~ 가장 간단한~~ 암호학의 시초라 할 수 있는 시저 암호법입니다. 시저 암호 (Caesar..

jhnyang.tistory.com

[C++언어]

각 글자를 n만큼 뒤로 옮기기만 하면 되니까 딱히 머리를 굴릴(?) 필요가 없이 코드 역시 간단하게 짤 수 있어요.

주어진 string 클래스를 최대한 활용해보았어요 ㅎㅎ

string solution(string s, int n){
    string answer="";
    for(char c: s) { //문자열 한글자 한글자 뽑아서
       answer.push_back(c+n);  // n만큼 뒤로 옮김!
    }
    return answer;
}

하지만 이렇게 끝나면, 오류가 뜹니다.

예시에서 보이다시피 이 암호는 순환암호예요. z가 끝이 아니라 abcd.....xyzabcd...이렇게 순환이 되기 때문에 

이 부분도 고려해줘야 한다는거~~

아스키 코드 상으로 Z나 z 다음이 A나 a로 가는게 아니라 특수문자로 가기 때문에 이 부분을 바로잡아 줘야 합니다.

실제로 저 코드에 s를 "ZAB"로 주면, answer값은 "ABC"가 아닌, "[BC"로 나옴을 확인할 수 있어요 ㅎㅎ

 

순환하게 만들기 위해, 소문자일 경우 대문자일 경우를 나눠서 모듈 연산을 사용하는 코드를 추가적으로 넣어줍시다. 또 띄어쓰기는 그대로 띄어쓰기로 나온다는 걸 유의해주세요 ㅎㅎ

string solution(string s, int n){
   string answer="";
   char start=' ';
   for(char c: s) { //문자열 한글자 한글자 뽑아서
        if ('A' <= c && c <='Z')
            start='A';
        else if('a' <= c && c<='z')
            start='a';
        if ( c != ' ')
            c = (c+n-start)%26 + start;
        answer.push_back(c); 
    }
    return answer;
}

 

[C++ 언어]

똑같은 코드지만 이번엔 string 메서드 말고 다른 방식으로 풀어봅시다.

사실 풀이법은 똑같아요 ㅎㅎ 그냥 사용한 함수만 쪼끔쪼끔 바꿀 뿐이지

예는 향상된 for문 대신 클래식 for문을 이용하고

스타트 문자를 구하기 위한 조건문을 삼항연산자로 바꿔준 것 밖에 읍어용 ㅎㅎ

 

#include <string>
using namespace std;
string solution(string s, int n){
   int len = s.length();
   for( int i = 0 ; i < len; i++)
   {
       if(s[i] != ' '){
        char start = ('A' <= s[i] && s[i] <= 'Z')? 'A' : 'a';  
        s[i]=start+(s[i]+n -start)%26; //순환을 위한 연산
       }
   }
    return s;
}

 

[Java 자바 풀이]

이번엔 자바로~~~

class Solution {
  public static String solution(String s, int n) {
      String answer = "";
      int len = s.length();
      char alpha;  char start;
      for(int i =0; i<len; i++){
          alpha = s.charAt(i);
          if(alpha != ' '){
            start = Character.isLowerCase(alpha)? 'a': 'A';
            alpha = (char)(start + (alpha+n-start)%26);
          }
          answer += alpha;
      }
      return answer;
  }
}

보시면 아시겠지만, 언어적 차이일 뿐 풀이는 동일합니다.

 

참고하시라고 다른 분들의 풀이도 올려드려요!

[C++]

앞에 자바가 대문자 소문자 판별할때 메서드를 사용한 것처럼 C++에서도 대소문자 판별에 라이브러리 함수를 사용한 풀이

[Java]

람다식을 이용한 풀이

아스키코드를 정수로 풀어쓴 거

 

참고로 아래는 geeksforgeeks 사이트에 나온 시저암호 코드입니다

[C++]

// A C++ program to illustrate Caesar Cipher Technique 
#include <iostream> 
using namespace std; 

// This function receives text and shift and 
// returns the encrypted text 
string encrypt(string text, int s) 
{ 
	string result = ""; 

	// traverse text 
	for (int i=0;i<text.length();i++) 
	{ 
		// apply transformation to each character 
		// Encrypt Uppercase letters 
		if (isupper(text[i])) 
			result += char(int(text[i]+s-65)%26 +65); 

	// Encrypt Lowercase letters 
	else
		result += char(int(text[i]+s-97)%26 +97); 
	} 

	// Return the resulting string 
	return result; 
} 

// Driver program to test the above function 
int main() 
{ 
	string text="ATTACKATONCE"; 
	int s = 4; 
	cout << "Text : " << text; 
	cout << "\nShift: " << s; 
	cout << "\nCipher: " << encrypt(text, s); 
	return 0; 
} 

[JAVA]

//A Java Program to illustrate Caesar Cipher Technique 
class CaesarCipher 
{ 
    // Encrypts text using a shift od s 
    public static StringBuffer encrypt(String text, int s) 
    { 
        StringBuffer result= new StringBuffer(); 
  
        for (int i=0; i<text.length(); i++) 
        { 
            if (Character.isUpperCase(text.charAt(i))) 
            { 
                char ch = (char)(((int)text.charAt(i) + 
                                  s - 65) % 26 + 65); 
                result.append(ch); 
            } 
            else
            { 
                char ch = (char)(((int)text.charAt(i) + 
                                  s - 97) % 26 + 97); 
                result.append(ch); 
            } 
        } 
        return result; 
    } 
  
    // Driver code 
    public static void main(String[] args) 
    { 
        String text = "ATTACKATONCE"; 
        int s = 4; 
        System.out.println("Text  : " + text); 
        System.out.println("Shift : " + s); 
        System.out.println("Cipher: " + encrypt(text, s)); 
    } 
} 

오늘은 여기까지입니당.

공감, 댓글, 광고보답은 질좋은 포스팅을 작성하는데 힘이됩니다 :) 다음에 또 보아요