第1週-6括弧変換
質問する
新しい開発者としてKakaoに入社したConは、他の開発者が作成したソースコードを分析し、問題を発見して修正するように、先輩の開発者から作業任務を受けた.ソースコードをコンパイルしてログを表示すると、ほとんどのソースコードのカッコがペアではない形式で記述されているため、エラーが発生します.
変更が必要なソースファイルが多すぎるため、コンソールは次のプログラムの開発を検討しています.
用語定義
文字列が「(」と「)」のみで構成され、「(」の数と「)」の数が同じである場合は、バランスカッコ文字列と呼ばれます.
「(」と「)」のカッコが一致している場合は、正しいカッコ文字列と呼ばれます.
たとえば、文字列「()」()は、バランスのとれたカッコ文字列ですが、有効なカッコ文字列ではありません.
逆に、文字列(()()など)は、バランスのとれたカッコ文字列であり、正しいカッコ文字列でもあります.
「(」と「)のみからなる文字列wがバランスの取れた括弧文字列である場合、以下の手順で正しい括弧文字列に変換できます.
入力
3-1. 実行後、文字列をuに接続して返します.
4-1. 「(」を最初の文字として空の文字列に追加します.
4-2. 文字列vに対して再帰操作を行い、ステップ1から文字列を接続する.
4-3. ')'貼り付け直します.
4-4. uの最初の文字と最後の文字を削除し、残りの文字列のカッコ方向を逆さまにして後ろに貼り付けます.
4-5. 生成された文字列を返します.
パラメータの説明
pは「(」と「」)のみからなる文字列であり、長さが2または1000より大きい偶数である.
文字列pの「(」と「)」は常に同じである.
pが有効なカッコ文字列である場合は、それを返すことができます.
コード#コード# // 괄호 변환
// https://tech.kakao.com/2019/10/02/kakao-blind-recruitment-2020-round1/
#include <string>
#include <vector>
#include <iostream>
using namespace std;
bool checkBalanace(string &s, char target1, char target2) {
int count_1 = 0;
int count_2 = 0;
for (char c : s) {
if (c == target1) ++count_1;
else if (c == target2) ++count_2; // else 로 할 수 있지만 가독성을 위해. -> 올바른 판단인가 ?
}
return count_1 == count_2;
}
bool checkRight(string s, char target, char pair) {
if (s.empty())
return true;
int last_idx = s.rfind(target);
if (last_idx == (s.size() - 1))
return false;
if (s[last_idx + 1] == pair) {
s.erase(last_idx, 2);
return checkRight(s, target, pair);
}
}
string reverseDir(string s, char dir1, char dir2) {
for (char& c : s) {
c = (c != dir1) ? dir1 : dir2;
}
return s;
}
string solution(string p) {
if (p.empty()) return "";
char check_char1 = '(';
char check_char2 = ')';
string answer = "";
for (int i = 2; i <= p.size(); i += 2) {
string u = p.substr(0, i);
string v = (i == p.size()) ? "" : p.substr(i);
if (checkBalanace(u, check_char1, check_char2)) {
if (checkRight(u, check_char1, check_char2)){
answer = u + solution(v);
} else {
u = u.erase(0, 1);
u = u.erase(u.size() - 1, 1);
answer = check_char1 + solution(v) + check_char2 + reverseDir(u, check_char1, check_char2);
}
break;
}
}
return answer;
}
int main()
{
cout << solution("(()())()") << endl; // "(()())()"
cout << solution(")(") << endl; // "()"
cout << solution("()))((()") << endl; // "()(())()"
//cout << solution("()))((()") << endl;
}
// 괄호 변환
// https://tech.kakao.com/2019/10/02/kakao-blind-recruitment-2020-round1/
#include <string>
#include <vector>
#include <iostream>
using namespace std;
bool checkBalanace(string &s, char target1, char target2) {
int count_1 = 0;
int count_2 = 0;
for (char c : s) {
if (c == target1) ++count_1;
else if (c == target2) ++count_2; // else 로 할 수 있지만 가독성을 위해. -> 올바른 판단인가 ?
}
return count_1 == count_2;
}
bool checkRight(string s, char target, char pair) {
if (s.empty())
return true;
int last_idx = s.rfind(target);
if (last_idx == (s.size() - 1))
return false;
if (s[last_idx + 1] == pair) {
s.erase(last_idx, 2);
return checkRight(s, target, pair);
}
}
string reverseDir(string s, char dir1, char dir2) {
for (char& c : s) {
c = (c != dir1) ? dir1 : dir2;
}
return s;
}
string solution(string p) {
if (p.empty()) return "";
char check_char1 = '(';
char check_char2 = ')';
string answer = "";
for (int i = 2; i <= p.size(); i += 2) {
string u = p.substr(0, i);
string v = (i == p.size()) ? "" : p.substr(i);
if (checkBalanace(u, check_char1, check_char2)) {
if (checkRight(u, check_char1, check_char2)){
answer = u + solution(v);
} else {
u = u.erase(0, 1);
u = u.erase(u.size() - 1, 1);
answer = check_char1 + solution(v) + check_char2 + reverseDir(u, check_char1, check_char2);
}
break;
}
}
return answer;
}
int main()
{
cout << solution("(()())()") << endl; // "(()())()"
cout << solution(")(") << endl; // "()"
cout << solution("()))((()") << endl; // "()(())()"
//cout << solution("()))((()") << endl;
}
Reference
この問題について(第1週-6括弧変換), 我々は、より多くの情報をここで見つけました https://velog.io/@lottocomeon/1주차-6번-괄호-변환テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol