Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++의 단어(또는 문자열) 배열에서 회문 쌍 만들기

<시간/>

"Madam" 또는 "racecar"는 회문이라고 하는 앞으로 읽는 것과 뒤로 읽는 것이 같은 두 단어입니다.

문자열 모음이나 목록이 주어지면 목록의 두 문자열을 결합하여 회문을 형성할 수 있는지 알아보기 위해 C++ 코드를 작성해야 합니다. 주어진 목록에 그러한 문자열 쌍이 있으면 "예"를 인쇄해야 하고, 그렇지 않으면 "아니오"를 인쇄해야 합니다.

이 자습서에서 입력은 문자열 배열이 되고 출력은 그에 따라 문자열 값이 됩니다. 예를 들어

입력

list[] = {"flat", "tea", "chair", "ptalf", "tea"}

출력

Yes

회문 문자열 "flatptalf"를 형성하는 "flat" 및 "ptalf" 쌍이 있습니다.

입력

list[] = {"raman", "ram", "na", "ar", "man"}

출력

Yes

회문 문자열 "naman"을 형성하는 "na"와 "man" 쌍이 있습니다.

해결책을 찾기 위한 접근 방식

무차별 대입 접근

배열의 각 문자열에 대해 다른 모든 문자열과 회문을 형성하는지 여부를 확인합니다. 그러한 쌍이 발견되면 true를 반환합니다. 이러한 쌍을 검색하기 위해 모든 배열 요소를 순회하고 적절한 쌍을 찾지 못하면 false를 반환합니다.

시간 복잡도 :O(N^2)

공간 복잡도 :O(1)

예시

#include<bits/stdc++.h>
using namespace std;
bool isPalindrome (string str) {
   int len = str.length ();
   for (int i = 0; i < len / 2; i++)
   if (str[i] != str[len - i - 1])
      return false;
   return true;
}
bool checkPalindromePair (vector < string > vect) {
   for (int i = 0; i < vect.size () - 1; i++) {
      for (int j = i + 1; j < vect.size (); j++) {
         string check_str = "";
         check_str = check_str + vect[i] + vect[j];
         if (isPalindrome (check_str))
            return true;
      }
   }
   return false;
}
int main () {
   vector < string > vect = { "flat", "tea", "chair", "ptalf", "tea"};
   checkPalindromePair (vect) ? cout << "Yes" : cout << "No";
   return 0;
}

출력

Yes

효율적이거나 최적화된 접근 방식

이 문제를 해결하기 위해 tri 데이터 구조를 사용할 수 있습니다.

먼저 빈 트라이를 만들고 배열의 각 문자열에 대해 현재 단어의 역순을 삽입하고 어느 인덱스까지 회문인지 저장해야 합니다. 그런 다음 배열을 다시 탐색해야 하며 각 문자열에 대해 다음을 수행해야 합니다.

  • True에서 사용할 수 있으면 true를 반환합니다.

  • 부분적으로 사용 가능한 경우 --나머지 단어가 회문인지 확인하십시오. 그렇다면 쌍이 회문을 형성한다는 의미인 true를 반환합니다.

시간 복잡도:O(Nk^2)

공간 복잡도:O(N)

여기서 N은 목록의 단어 수이고 k는 회문에 대해 확인된 최대 길이입니다.

예시 2

#include<bits/stdc++.h>
using namespace std;
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
#define ALPHABET_SIZE (26)
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
struct TrieNode {
   struct TrieNode *children[ALPHABET_SIZE];
   vector < int >pos;
   int id;
   bool isLeaf;
};
struct TrieNode *
getNode (void) {
   struct TrieNode *pNode = new TrieNode;
   pNode->isLeaf = false;
   for (int i = 0; i < ALPHABET_SIZE; i++)
      pNode->children[i] = NULL;
   return pNode;
}
bool isPalindrome (string str, int i, int len) {
   while (i < len) {
      if (str[i] != str[len])
         return false;
      i++, len--;
   }
   return true;
}
void insert (struct TrieNode *root, string key, int id) {
   struct TrieNode *pCrawl = root;
   for (int level = key.length () - 1; level >= 0; level--) {
      int index = CHAR_TO_INDEX (key[level]);
      if (!pCrawl->children[index])
         pCrawl->children[index] = getNode ();
      if (isPalindrome (key, 0, level))
         (pCrawl->pos).push_back (id);
      pCrawl = pCrawl->children[index];
   }
   pCrawl->id = id; pCrawl->pos.push_back (id);
   pCrawl->isLeaf = true;
}
void
search (struct TrieNode *root, string key, int id,
vector < vector < int > >&result) {
   struct TrieNode *pCrawl = root;
   for (int level = 0; level < key.length (); level++) {
      int index = CHAR_TO_INDEX (key[level]);
      if (pCrawl->id >= 0 && pCrawl->id != id && isPalindrome (key, level, key.size () - 1))             result.push_back ( { id, pCrawl->id} );
      if (!pCrawl->children[index]) return; pCrawl = pCrawl->children[index];
   }
   for (int i:pCrawl->pos) {
      if (i == id) continue;
         result.push_back ( { id, i} );
   }
}
bool checkPalindromePair (vector < string > vect) {
   struct TrieNode *root = getNode ();
   for (int i = 0; i < vect.size (); i++)
   insert (root, vect[i], i);
   vector < vector < int >>result;
   for (int i = 0; i < vect.size (); i++) {
      search (root, vect[i], i, result);
      if (result.size () > 0) return true;
   }
   return false;
}
// Driver code int main () {
   vector < string > vect = { "flat", "tea", "chair", "ptalf", "tea"};
   checkPalindromePair (vect) ? cout << "Yes" : cout << "No";
   return 0;
}

출력

Yes

결론

이 자습서에서는 두 가지 접근 방식(Bruteforce 및 Optimized)을 사용하여 배열에서 회문 쌍을 찾는 방법을 배웠습니다. 우리는 또한 자바, 파이썬 및 기타 언어로 이 코드를 작성할 수 있습니다. 첫 번째 접근 방식은 주어진 모든 요소를 ​​순회하여 솔루션을 찾는 기본적인 방법입니다. 대조적으로, 두 번째 접근 방식은 tri 데이터 구조를 사용하므로 답은 거의 선형 시간 복잡도입니다. 이 튜토리얼이 도움이 되기를 바랍니다.