アルゴリズムを数秒で理解する | 文字列一致アルゴリズムの分析例: 隠れた、最も低い 3 要素の文字列

 文字列照合アルゴリズムは実際のプロジェクトでも頻繁に遭遇するもので、大手企業の筆記試験や面接でもよく出題されます。このアルゴリズムは通常、元の文字列 (文字列) と部分文字列 (パターン) を入力として受け取り、元の文字列内で部分文字列が最初に出現する位置を返す必要があります。たとえば、元の文字列が「ABCDEFG」でサブ文字列が「DEF」の場合、アルゴリズムは 3 を返します。一般的なアルゴリズムには、BF (ブルート フォース、総当たり検索)、RK (ロビン-カープ、ハッシュ検索)、KMP (教科書で最も一般的なアルゴリズム)、BM (ボイヤー ムーア)、サンデーなどが含まれます。

01、症例分析: ラーカー

問題の説明:

R国とS国は戦火に巻き込まれ、両国は互いに潜伏者(スパイ)を送り込んで互いの内国に忍び込み、日和見の行動を窺う。 S 国に潜伏していた R 国のスパイであるリトル C は、多くの困難を経て、最終的に S 国の軍典の暗号化ルールを理解しました。

(1) S 国軍内に送信されるオリジナル情報は暗号化されてインターネット上に送信され、オリジナル情報の内容と暗号化された内容は大文字の「A」~「Z」で構成されます(スペースやその他の文字は含まれません)。 )。

(2) S国では、文字ごとに対応する「秘密の言葉」を定めている。暗号化のプロセスでは、元のメッセージ内のすべての文字を、対応する「秘密の単語」に置き換えます。

(3) 各文字は固有の「秘密の単語」にのみ対応し、異なる文字は異なる「秘密の単語」に対応します。 「秘密の言葉」は元の手紙と同じでも構いません。

例えば、「A」の秘密語を「A」、「B」の秘密語を「C」と指定すると(その他の文字や秘密語は省略)、元の情報「ABA」が暗号化されます。 「ACA」として。

さて、Little C は、S 国のネットワーク上で送信される暗号化されたメッセージと、内線を介してそれに対応するオリジナルのメッセージを習得しました。リトル C は、この情報を使用して S 国の軍事法典を解読したいと考えています。 Little C の解読プロセスは次のとおりです。元の情報をスキャンし、元の情報の文字 X (任意の大文字を表す) に対応する暗号化された情報の中から大文字の Y を見つけ、Y がパスワード内の X のパスワードであると考えます。キャラクター。次のいずれかの状態で停止するまで、この手順を続けます。

(1) すべての情報をスキャンし、元の情報に含まれる「A」から「Z」までの 26 文字すべてと、それに対応する「秘密の言葉」を取得します。

(2) すべての情報をスキャンしましたが、元の情報には表示されない特定の(またはいくつかの)文字があることが判明しました。

(3) スキャン中に、得られた情報に明らかな矛盾または誤りがあることが判明しました (S 国のパスワードの暗号化規則に違反しています)。たとえば、「XYZ」という情報を「ABA」と翻訳すると、「異なる文字には異なるパスワードが対応する」というルールに違反します。

リトル C が忙しすぎて頭がクラクラしているとき、R 国の本部が別の電報を送り、S 国から傍受されたばかりの別の暗号化メッセージを翻訳するよう彼に依頼しました。さあ、リトル C を助けてください。内部関係者が入手した情報を使用してコードを解読し、解読されたコードを使用して電報内の暗号化された情報を翻訳してください。

入力形式:

合計 3 行あり、各行は 1 ~ 100 までの長さの文字列です。

最初の行は、Little C が持つ暗号化されたメッセージです。

2 行目は、1 行目の暗号化された情報に対応する元の情報です。

行 3 は、R 国の本社がリトル C に翻訳を要求する暗号化されたメッセージです。

入力データでは、すべての文字列が大文字の「A」〜「Z」のみで構成され、最初の行の長さが 2 行目の長さと等しいことが保証されます。

出力フォーマット:

合計1行。

コードの解読を停止したときに (2) と (3) の 2 つの状況が発生した場合は、Failed (最初の文字が大文字、残りが小文字) が出力され、それ以外の場合は、暗号化された情報を暗号を使用して翻訳して取得した元の情報が出力されます。電文が出力されます。

入力例 #1:

出力サンプル:

 入力例:

出力サンプル:

 入力例:

出力サンプル:

 

入力と出力のサンプル 1 の説明:

元のメッセージの文字「A」と「B」は同じパスワードに対応しており、「失敗」が出力されます。

入力と出力のサンプル 2 の説明:

元のメッセージには文字「Z」は表示されず、「失敗」が出力されます。

アイデア:

(1) A~Z がすべて存在する必要があります。存在しない場合は Failed が出力されます。

(2) 暗号文内の各文字を複数の文字で使用することはできません。そうでない場合は、Failed が出力されます。

参考手順:

#include<iostream>
#include<cstring>
using namespace std;
char map[26];
int main()
{
string secret,original,translation;
int len1,len3;
int i,j;
cin>>secret>>original>>translation; ;//输人密文、原文、要翻译的文字
len1=secret.length() ;  //计算密文长度
len3=translation.length(); //计算要翻译的文字长度
if(len1<26)  //若密文长度小于 26 个字母的长度,则不合要求,输出 Eailed,终止程序
}
{
cout<<"Failed"<<endl;
return 0;
}
for(i=0;i<lenl;i++)
{
for(j=0;j<i;j++)
if(original[i]==original[jl&&secret[il!=secret[j]) //若原文中有相同字母,但密文中对应字母不相同,则不合要求,输出 Eailed,终止
//程序
{
cout<<"Failed"<<endl;
return 0;
}
map[secret[il-'A']=original[i];   //存储密文对应的原文 
}
for(i=0;i<len3;i++)  //输出翻译后的文字
cout<<map[translation[i]-'A'];
cout<<end1;
return 0;    
}

02,分析例: 最下位の 3 要素文字列

問題の説明:

3 値文字列を指定します (文字列は文字 '0'、'1'、および '2' のみで構成されます)。

任意の 2 つの隣接する (連続する) 文字「0」と「1」 (つまり、「01」を「10」に置き換える、またはその逆)、または任意の 2 つの同一の文字を交換できます。隣接する (連続する) 文字「1」と「2」(つまり、「12」を「21」に、またはその逆に置き換えます)。たとえば、文字列「010210」の場合、次の手順を実行できます。

「010210」→→「100210」;

「010210」→→「001210」;

「010210」→→「010120」;

「010210」→→「010201」。

たとえば、文字列「010210」の場合、次の操作を実行できます。 「02」を「20」に、またはその逆に変換できないことに注意してください。指定された文字列では、上記以外の操作は実行できません。

あなたのタスクは、これらのスワップを何度でも (場合によっては 0 回) 使用して、(辞書編集上) 可能な最小の文字列を取得することです。

位置 i (1≤i≤|a|、|s| は文字列 "ss" の長さ) がある場合、文字列 "aa" は文字列 "bb" より辞書順に小さくなります (文字列 " ; aa" と "bb" は同じ長さであるため)、各 j

入力:

入力の最初の行には、'0'、'1'、および '2' のみで構成され、長さ 1 ~ 105 の文字列 "s" が含まれています ( 105)。

出力:

文字列 - 前述のスワップを使用して取得できる (辞書編集上の) 文字列の最小数 (おそらくゼロ) を出力します。

入力例:

100210

出力サンプル:

001120

入力例:

11222121

出力サンプル:

11112222

入力例:

20

出力サンプル:

20

質問の意味: 0、1、2 だけの数字列が与えられたとき、0 と 1、および 1 と 2 は互いに入れ替えることができ、入れ替え後の最小の値を求めます。

アイデア: 1 がどこにあるかに関係なく、常に 2 の前に置き換えることができますが、0 は 2 の前に置き換えることはできないため、最初に最初の 2 の前にある 0 の数を数えて出力し、次に文字列全体の 1 の数を数えます。 , 出力; 最後に、最初の 2 以降のすべての数値から 1 を削除して出力します。

参考手順:

#include<iostream>
#include<cstdio>
#include<cstring>
# include< cmath>
#include<algorithm>
#include<string>
# include<cstdlib>
# include<queue>
# include< set>
# include<map>
#include<stack>
#include<ctime>
#include<vector>
#define INF Ox3f3f3f3f
# define PI acos(-1.0)
#define N 1001
#define MOD 10007
#define E 1e-6
# define LL long long
using namespace std;
int main()
{
string str;
cin>>str;
LL len=str.length() ;
LI num 1=0;
bool flag=true;
for(LL i=0;i<len;i++)
if(str[il=='1')num 1++;
if(str[i]=='1' str[i]=='2')
flag=false;
LL pos;
LI num 0=0;
for(LL i=0;i<len;i++)
f(str[i]=='0')
num 0++;
if(str[i]=='2')
pos=i;
break;
if(flag)
cout<<str<<endl;
return 0;
}
while(num 0--)
cout<<'0';
while(num 1--)
cout<<'1';
for(LL i=pos;i<len;i++)
{
if(str[il=='1')
continue;
else
cout<<str[i];
}
cout<<endl;
return 0;
}

おすすめ

転載: blog.csdn.net/qq_41640218/article/details/133738157