CS/알고리즘

C++ 코드를 JAVA로 바꿔보자

lms0806 2023. 10. 10. 21:07
728x90
반응형

오늘은 https://www.acmicpc.net/problem/2557 문제를 통과하는 코드인 cpp 코드를 java코드로 바꿔주는 소스를 작성해 봤습니다.

 

2557번: Hello World

Hello World!를 출력하시오.

www.acmicpc.net

 

코드 컨벤션을 준수한 코드를 기준으로 작성했습니다.

 

테스트 cpp 코드

#include<iostream>

using namespace std;

int main(){
	cout << "Hello World!";
}

 

자바로 바꾼 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args)throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		StringBuilder sb = new StringBuilder();
		sb.append("Hello World!");
		System.out.print(sb);
	}
}

 

JAVA는 Scanner 또는 BufferedReader로 보통 입력을 받습니다.

그 중 제가 자주 쓰는 BufferedReader로 해결을 하였습니다.

 

출력같은 경우도 System.out.println(); 을 사용하게 되면 효율적이지 못하여 StringBuilder를 사용하는 방식으로 진행했습니다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
	static boolean iostream = false;
	static boolean printFirst = false;
	static boolean end = false;
	static Stack<Character> stack = new Stack<>();
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringBuilder sb = new StringBuilder();
		while(true) {
			String s = br.readLine();
			
			// 공백일 경우 pass
			if(s.equals("")) {
				continue;
			}
			
			sb.append(change(s));
			
			if(end) {
				break;
			}
		}
		System.out.print(sb);
	}
	
	public static StringBuilder change(String str) {
		StringBuilder sb = new StringBuilder();
		
		String[] s = str.trim().split(" ");
		
		if(str.equals("#include<iostream>")) {
			sb.append("import java.io.BufferedReader;").append("\n");
			sb.append("import java.io.IOException;").append("\n");
			sb.append("import java.io.InputStreamReader;").append("\n\n");
			iostream = true;
		} // 입출력을 사용할 것이다.
		else if(str.length() > 1 && s[1].contains("main")) {
			sb.append("public class Main {").append("\n");
			sb.append("	public static void main(String[] args)").append(iostream ? "throws IOException" : "").append(" {").append("\n");
			
			if(iostream) {
				sb.append("		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));").append("\n\n");
			}
			stack.add('{');
		} // main문을 작성하였을 떄
		else if(s[0].endsWith("cout")) {
			if(!printFirst) {
				printFirst = true;

				sb.append("		StringBuilder sb = new StringBuilder();").append("\n");
			}
			String[] coutS = str.split("<<");
			
			for(int i = 1; i < coutS.length; i++) {
				sb.append("		sb.append(");
				char[] c = coutS[i].trim().toCharArray();
				int len = c[c.length - 1] == ';' ? c.length - 1 : c.length;
				for(int j = 0; j < len; j++) {
					if(j < c.length - 6 && c[j] == '\\' && c[j + 1] == 'u'){
						j += 5;
						continue;
					} // 유니코드를 사용한 경우 pass
					sb.append(c[j]);
				}
				
				sb.append(");").append("\n");
			}
		} // 출력문인 경우
		else if(str.equals("}")) {
			if(stack.size() == 1 && stack.peek() == '{') {
				sb.append("		System.out.print(sb);").append("\n");
				sb.append("	}").append("\n");
			}
			sb.append("}").append("\n");
			stack.pop();
			end = true;
		} // 마무리인 경우
		return sb;
	}
}

작성한 코드는 이렇습니다.


Stack의 경우 추루  for(;;){} 등 괄호를 사용하는 구문이 추가될 경우를 고려하여 stack을 작성하였습니다.

 

만드는데 1시간 정도 걸린거 같네여

다 만들고 나니 저격케이스를 제공해주셔서 그거 수정하느라 몇분...

 

추후에는 JAVA코드를 CPP로 바꾸는 방식을 작성해보고자 합니다.

해당 방식을 할떄 고려할 사항은

Scanner를 기준으로 할 것인가, BufferedReader를 기준으로 할 것인가

System.out.println();을 기준으로 할 것인가, StringBuilder를 기준으로 할 것인가, StringBuffer를 기준으로 할 것인가, BufferedWriter를 기준으로 할 것인가...

등 고려해야할 사항이 많다보니 조금 더 고민해 봐야할거 같습니다.

 

퇴근하면서 '한번 해볼까?' 라는 생각으로 시작했는데, 추후 확장성을 생각한다면 그렇게 쉬운거 같진 않네요..

728x90
반응형