자바에서 문장의 제일 마지막 두 단어에 [ ] 를 씌우는 방법은?
java 에서 입력값이 문장이고, 출력값도 문장일때 해당 문장의 제일 마지막 두단어에 [ ] 를 씌우려고 하는데, 어떻게 하면 될까요? split 함수를 이용하면 되나요? 만약 입력값이 한단어이면 그 단어에 [ ] 를 씌우면 되요
ex)
나는 오늘도 회사에 가야 한다. ==> 나는 오늘도 회사에 [가야] [한다.]
안녕? ==> [안녕?]
- import java.util.Scanner; import java.util.Stack; public class Main { @SuppressWarnings("resource") public static void main(String[] args) { // 문장을 입력 받기 위해 사용 Scanner scan = new Scanner(System.in); String str; System.out.println("문장을 입력 해 주세요."); // 문자열 저장 str = scan.nextLine(); // 문자열이 없으면 종료 int len = str.length(); if(len > 0) { // 스택에 []를 미리 넣어둠 Stack<String> stack = new Stack<String>(); stack.push("["); stack.push("]"); stack.push("["); stack.push("]"); // 문자열을 저장할 변수와 불리언 변수 선언 StringBuffer sb = new StringBuffer(); boolean isBlank = false; boolean isNeedBraketPop = false; // 마지막 문자가 빈칸일 경우를 대비 선언 if(!" ".equals(str.subSequence(str.length() - 1, str.length()))) { sb.append(stack.pop()); isNeedBraketPop = true; } // 문자열 길이 만큼 for문을 실행 for (int i = len - 1; i >= 0; i--) { // 뒤에서 부터 문자를 하나씩 가져옴 String s = str.substring(i, i + 1); // 빈칸일 경우 if(" ".equals(s)) { // 빈칸이 있었음을 저장함. isBlank = true; // 괄호를 한번 pop하여 저장하였을 경우 if(isNeedBraketPop == true) { sb.append(stack.pop()); sb.append(s); isNeedBraketPop = false; } else { // 괄호를 저장할 필요가 없는 경우 sb.append(s); } // 빈칸이 아닐 경우 } else { // 스택이 비어 있지 않으면서 빈칸이 있었을 경우 if(!stack.isEmpty() && isBlank == true) { // 괄호를 저장하고 문자를 저장함. sb.append(stack.pop()); sb.append(s); // 상태값을 저장 isBlank = false; isNeedBraketPop = true; } else { //문자만 저장 sb.append(s); } } } // 2단어 이하일 경우 괄호를 닫아 주어야 한다. if(stack.size() % 2 == 1) { sb.append(stack.pop()); } // 출력 System.out.println(sb.reverse().toString()); } } }
// 예시1
// 공백이 두칸 이상 있을 경우
// 예시2
일단 해당 문제를 해결하려면 단어의 조건을 만들 필요가 있습니다.
아마 공백으로 나누어진 것을 기준으로 문장에서 단어를 쪼갤 수 있을 것 같습니다.
하지만 댓글의 split 을 사용하게 되면 공백문자에 대해 구분자로 인식하기 때문에 공백문자가 두 개 이상일 경우 하나로 줄어들 수 있는 부작용이 생길 수 있습니다. (추가 댓글에서 인지하신 것 같네요.)가장 간단하게 할 수 있는 방법은 자바의 정규식을 이용하는 방법이 있습니다.
단어를 나타내는 정규식은 아래와 같이 사용할 수 있습니다.
"\\S+"따라서 아래와 같이 사용할 수 있습니다.
import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class WrapBracket { private static final Pattern ONE_WORD_PATTERN = Pattern.compile("\\S+"); public static void main(String[] args) { String original = "나는 오늘도 회사에 가야 한다. "; System.out.println(wrap(original)); } public static String wrap(String input) { if (input == null) { return null; } List<Group> twoWordGroup = getLastTwoWordGroup(input); if (twoWordGroup.isEmpty()) { return input; } else { switch (twoWordGroup.size()) { case 2: StringBuilder sb2 = new StringBuilder(input.length()); sb2.append(input, 0, twoWordGroup.get(0).start); sb2.append('['); sb2.append(input, twoWordGroup.get(0).start, twoWordGroup.get(0).end); sb2.append(']'); for (int i = twoWordGroup.get(0).end; i < twoWordGroup.get(1).start; i++) { sb2.append(input.charAt(i)); } sb2.append('['); sb2.append(input, twoWordGroup.get(1).start, twoWordGroup.get(1).end); sb2.append(']'); for (int i = twoWordGroup.get(1).end; i < input.length(); i++) { sb2.append(input.charAt(i)); } return sb2.toString(); case 1: default: StringBuilder sb1 = new StringBuilder(input.length()); sb1.append(input, 0, twoWordGroup.get(0).start); sb1.append('['); sb1.append(input, twoWordGroup.get(0).start, twoWordGroup.get(0).end); sb1.append(']'); for (int i = twoWordGroup.get(0).end; i < input.length(); i++) { sb1.append(input.charAt(i)); } return sb1.toString(); } } } private static List<Group> getLastTwoWordGroup(String input) { final Matcher matcher = ONE_WORD_PATTERN.matcher(input); List<Group> groups = new ArrayList<>(); while (matcher.find()) { Group group = new Group(matcher.start(), matcher.end()); groups.add(group); } while (groups.size() > 2) { // only within 2 words groups.remove(0); } return groups; } static class Group { int start; int end; public Group(int start, int end) { this.start = start; this.end = end; } } }일단 원하는 기능을 동작하는 코드를 제시하기 위해 중복 코드가 보입니다.
코드를 리팩토링 하면 더 간결하게 만들 수 있겠습니다.안녕하세요
답변자로 활동중인 굴뚝새입니다.
Java에서 입력값 제일 뒤에 단어에 대괄호를 씌우는 방법에 대해 질문하셨는데요
질문에 말씀하신대로 split 을 잘 활용하시면 가능합니다
공백 ' ' 즉 띄어쓰기로 split를 해서
뒤에 두 단어에만 괄호를 해주시면 됩니다.
휴대폰으로 작성중이라 코드까지 작성하긴 무리가 있어 글로만 설명드렸어요
도움이되셨길 바랍니다.
안녕하세요. A-HA 프로그래밍 전문가입니다.
질문하신 단어의 기준이 스페이스 공백이라면 공백으로 split을 하고, split한 배열의 사이즈를 확인한 뒤, 가장 마지막 2개의 문자열에 []를 추가하시면 될 것 같습니다.
코드는 직접 작성 해보시는걸 추천합니다. 어렵지는 않을 것 같네요..
수도 코드로는
// 문자열 파싱 split 사용
// 배열 사이즈 확인
// 배열 max -2 만큼 루프 돌면서 [] 추가
// 배열 루프 돌면서 출력
이렇게 하시면 될 것 같습니다.
split 함수를 써서 단어별로 배열에 저장하고 저장된 배열의 크기가 2이상일경우에 마지막 두개만 [] 를 넣어서 저장합니다
공백이 두칸이상이라도 split 에 걸릴텐데 만약 (공백)가야 이러한경우에 반복문을 통해 한문자씩 확인 후 공백문자가 아니면 []를 추가하는 방식으로 하면 됩니다. 그다음에 다시 배열의 단어들을 합치면 됩니다.
안녕하세요
샘플소스입니다. 참고하세요~
import java.util.Scanner; public class ScannerTest { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String line = null; StringBuffer sb = null; while (true) { System.out.print("문장 입력 : "); line = scanner.nextLine(); if ("그만".equals(line)) { System.out.println("종료합니다."); break; } String[] words = line.split("\s"); int wordSize = words.length; sb = new StringBuffer(); for (int i = 0; i < wordSize; i++) { if (i > 0) { sb.append(" "); } if (i >= wordSize - 2) { sb.append("["); } sb.append(words[i]); if (i >= wordSize - 2) { sb.append("]"); } } System.out.println(sb.toString()); } } }소스입니다.
class CodeRunner{ public static void main(String[] args){ String contents = "나는 오늘도 회사에 가야 한다."; // 문장을 공백을 기준으로 배열로 변환 String[] strArr = contents.split(" "); // 출력 String 선언 String result = null; for (int i = 0; i < strArr.length; i++) { String str = null; // 단어 배열을 돌면서 마지막 2단어일경우 단어에 대괄호 추가 if (strArr.length - 3 < i) { str = "[" + strArr[i] + "]"; } else { str = strArr[i]; } // 변경된 단어 배열 재조합 result = result == null ? str : result + " " + str; } //출력 System.out.println(result); } }출력 결과입니다.
네네 안녕하십니까~
문장의 마지막 2단어만을 [ ] 로 씌우고 싶다는 말씀이신데요
우선 띄어쓰기의 유무를 체크하면 될것 같습니다.
StringUtils.countMatches("문장", " ")
위처럼 기본 라이브러리를 사용해서 문장 안에 띄어쓰기를 찾습니다.
if문을 사용해
띄어쓰기가 1개 이하면 전부 [ ]를 씌우고
띄어쓰기가 2개 이상이면 마지막 2단어만 [ ]를 씌우면 될것 같습니다.
[ ] 를 씌우는 과정은
문자열.split() 함수를 사용해 단어별로 배열에 담아줍니다.
그리고 배열.length()-1와 배열.length() -2 로 특정 인덱스의 값에 [ ]를 붙여주면 됩니다.
그리고 마지막엔 문장을 이어붙여주면 됩니다~
for문을 통해 배열의 첫 인덱스부터 마지막 인덱스까지 띄어쓰기를 붙여주시고
마지막 인덱스의 단어를 붙이고서는 띄어쓰기를 멈춰주시면 됩니다~ (이 과정이 좀 싫다면 마지막에 rtrim() 함수 사용하시구요)
코드로 작성해드림이 깔끔하고 보기좋았을텐데 그렇지 못한 점 죄송합니다.
그래도 조금이나마 도움이 되었으면 해요 !!
안녕하세요.
"나는 오늘도 회사에 가야 한다." 같은 문장의 경우라면 단어들이 단어와 단어사이에 모두 " "공백을 두고 있기때문에
말하신대로 " "공백으로 split을 통해 배열로 변환한 뒤 배열의 총길의 -1과 -2순번의 앞에 "[" 뒤에 "]"를 붙이는 것으로 로직을 구성하면 될 것 같습니다.
"안녕?"과 같이 단어가 1개인 경우가 있을 수 있으니 배열의 총길이가 1인 경우는 따로 처리해 주면 될 것 같습니다.
ex)
나는 오늘도 회사에 가야 한다. ==> 나는 오늘도 회사에 [가야] [한다.]
안녕? ==> [안녕?]
===> 완전한 소스보다는 풀기위한 알고리즘을 알려드리겠습니다
1. 우선 입력된 문장값을 공란 을 기준으로 함수를 이용하여 나눕니다
2. 나누게 되면 배열이 생성되는데 , 그 배열의 갯수를 알아냅니다
3. 제일 큰수 와 두번째로 큰수에 들어있는 문자열에 [] 괄호를 넣어줍니다
4. (2)에서 생성된 배열들을 전부 출력하면? 위에 질문하신 내용대로 문장이 출력이 됩니다
위 알고리즘을 토대로 직접 풀어보시고, 안되면 직접 시도한 소스로 재 질문하시면
소스의 무엇이 잘못되었는지 체크해드리겠습니다
import java.util.Scanner;
public class ExampleScanner {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = null;
while((line = scanner.nextLine()) != null) {
line = line.trim();
String spStr[] = line.split(" ");
String newStr = "";
for(int i = 0; i < spStr.length; i++) {
if(i>0) {
newStr += " ";
}
if(i > spStr.length - 3) {
newStr += "["+spStr[i]+"]";
}else {
newStr += spStr[i];
}
}
System.out.println(line+"==>"+newStr);
}
}
}