C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++を使用して2つの文字列を等しくするために必要な特定の操作の最小数。


問題の説明

2つの文字列str1とstr2がある場合、両方の文字列に文字「a」と「b」が含まれます。両方の文字列は同じ長さです。両方の文字列に1つの_(空のスペース)があります。タスクは、次の操作の最小数を実行することにより、最初の文字列を2番目の文字列に変換することです-

  • _が位置Iにある場合、_は位置i+1またはi-1の文字と交換できます

  • 位置i+1とi+2の文字が異なる場合、_は位置i+1またはi+2の文字と交換できます

  • 同様に、位置i-1とi-2の文字が異なる場合、_は位置i-1またはi-2の文字と交換できます

str1 =“ aba_a”およびstr2 =“ _baaa”の場合、str1をstr2に変換するには2回の移動が必要です-

1. str1 = “ab_aa” (Swapped str1[2] with str1[3])
2. str2 = “_baaa” (Swapped str1[0] with str1[2])

アルゴリズム

1. Apply a simple Breadth First Search over the string and an element of the queue used for BFS will contain the pair str, pos where pos is the position of _ in the string str.
2. Also maintain a map namely ‘vis’ which will store the string as key and the minimum moves to get to the string as value.
3. For every string str from the queue, generate a new string tmp based on the four conditions given and update the vis map as vis[tmp] = vis[str] + 1.
4. Repeat the above steps until the queue is empty or the required string is generated i.e. tmp == B
5. If the required string is generated, then return vis[str] + 1 which is the minimum number of operations required to change A to B.

#include <iostream>
#include <string>
#include <unordered_map>
#include <queue>
using namespace std;
int transformString(string str, string f){
   unordered_map<string, int> vis;
   int n;
   n = str.length();
   int pos = 0;
   for (int i = 0; i < str.length(); i++) {
      if (str[i] == '_') {
         pos = i;
         break;
      }
   }
   queue<pair<string, int> > q;
   q.push({ str, pos });
   vis[str] = 0;
   while (!q.empty()) {
      string ss = q.front().first;
      int pp = q.front().second;
      int dist = vis[ss];
      q.pop();
      if (pp > 0) {
         swap(ss[pp], ss[pp - 1]);
         if (!vis.count(ss)) {
            if (ss == f) {
               return dist + 1;
               break;
            }
            vis[ss] = dist + 1;
            q.push({ ss, pp - 1 });
         }
         swap(ss[pp], ss[pp - 1]);
      }
      if (pp < n - 1) {
         swap(ss[pp], ss[pp + 1]);
         if (!vis.count(ss)) {
         if (ss == f) {
            return dist + 1;
            break;
         }
         vis[ss] = dist + 1;
         q.push({ ss, pp + 1 });
      }
      swap(ss[pp], ss[pp + 1]);
   }
   if (pp > 1 && ss[pp - 1] != ss[pp - 2]) {
      swap(ss[pp], ss[pp - 2]);
      if (!vis.count(ss)) {
         if (ss == f) {
            return dist + 1;
            break;
         }
         vis[ss] = dist + 1;
         q.push({ ss, pp - 2 });
      }
      swap(ss[pp], ss[pp - 2]);
   }
   if (pp < n - 2 && ss[pp + 1] != ss[pp + 2]) {
      swap(ss[pp], ss[pp + 2]);
      if (!vis.count(ss)) {
         if (ss == f) {
            return dist + 1;
            break;
         }
         vis[ss] = dist + 1;
         q.push({ ss, pp + 2 });
      }
      swap(ss[pp], ss[pp + 2]);
      }
   }
   return 0;
}
int main(){
   string str1 = "aba_a";
   string str2 = "_baaa";
   cout << "Minimum required moves: " << transformString(str1, str2) << endl;
   return 0;
}

出力

上記のプログラムをコンパイルして実行する場合。次の出力を生成します-

Minimum required moves: 2

  1. C++で文字を削除せずに2つの文字列アナグラムを作成するために必要な操作の最小数

    同じ長さの2つの文字列があるとすると、文字を削除せずに、2つの文字列のアナグラムを作成するために必要な最小限の変更を見つける必要があります。アナグラムは、同じ文字セットを持つ2つの文字列です。 2つの文字列が「HELLO」であり、ここで「WORLD」が必要な変更の数が3であると仮定します。この場合、3つの文字が異なります。 考え方は単純です。最初の文字列の各文字の頻度を見つけてから、2番目の文字列を調べ、2番目の文字列の文字が周波数配列に存在する場合は、頻度の値を減らします。頻度の値が0未満の場合は、最終カウントを1増やします。 例 #include <iostream> usi

  2. Pythonで2つの文字列を等しくするために必要な前処理移動の最小数を見つけます

    同じ長さで小文字のみの2つの文字列PとQがあるとすると、以下の操作を適用した後、文字列Pを文字列Qと等しくするために必要な、文字列Pの前処理移動の最小数をカウントする必要があります- 任意のインデックスiを選択し、文字piとqiを入れ替えます。 任意のインデックスiを選択し、文字piとpn – i –1を入れ替えます。 任意のインデックスiを選択し、文字qiとqn – i –1を入れ替えます。 注 −範囲内のiの値(0≤i