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

C++である文字列が別の文字列を「破る」ことができるか判定する方法

問題の概要

同じ長さを持つ2つの文字列 s1 と s2 が与えられたとします。このとき、s1 のある並べ替え(順列)が s2 のある並べ替えを「破る」ことができるか、あるいはその逆が成り立つかどうかを判定する必要があります。

ここで「文字列 a が文字列 b を破る」とは、0 から n-1 までのすべてのインデックス i において x[i] >= y[i](アルファベット順での比較)が常に成立することを意味します。

たとえば、入力が s1 = "abc"、s2 = "xya" の場合、出力は true になります。これは、s2 の並べ替えである "ayx" が、s1 = "abc" の並べ替えである "abc" を破ることができるためです。

解決の手順

この問題は、次の手順で解くことができます。

  • check(s1, s2) という関数を定義します。
  • i を 0 から s1 のサイズ未満まで1ずつ増やしながらループします。
    • s2[i] < s1[i] であれば false を返します。
  • ループを最後まで抜けたら true を返します。
  • メイン処理では以下を実行します。
    • s1 を昇順にソートする
    • s2 を昇順にソートする
    • f3 := check(s2, s1) を計算する
    • f4 := check(s1, s2) を計算する
    • f3 または f4 のどちらかが true であれば true を、そうでなければ false を返す

アルゴリズムのポイント

両方の文字列をあらかじめ昇順にソートしておけば、「ある並べ替えが他方を破れるかどうか」は、ソート済みの2つの文字列を先頭から要素ごとに比較し、片方が常に他方以上になっているかを確認するだけで判定できます。計算量はソートに伴い O(n log n) となり、非常に効率的です。

実装例

理解を深めるために、以下のC++による実装を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    bool check(string& s1, string& s2){
        for (int i = 0; i < s1.size(); i++) {
            if (s2[i] < s1[i])
                return false;
        }
        return true;
    }
    bool checkIfCanBreak(string s1, string s2) {
        sort(s1.begin(), s1.end());
        sort(s2.begin(), s2.end());
        bool f3 = check(s2, s1);
        bool f4 = check(s1, s2);
        return f3 || f4;
    }
};
main(){
    Solution ob;
    cout << (ob.checkIfCanBreak("abc", "xya"));
}

入力

"abc", "xya"

出力

1

  1. Swiftで文字列が別の文字列を含んでいるか確認する方法

    Swiftである文字列に別の文字列が含まれているかどうかを確認するには、2つの異なる文字列が必要です。1つは検索対象となる文字列、もう1つはその中に特定の文字列が含まれているかを調べる元となる文字列です。 ここでは、確認したい文字列を「point」、全体の文字列を「TutorialsPoint」、そして別の文字列として「one two three」を使用して説明します。Playgroundでこれらの文字列を使って実際に確認してみましょう。 この確認は、以下に示す2つの方法で行うことができます。まずは3つの異なる文字列を作成します。 var completeStr1 = Tutorials po

  2. C++で二分木が別の二分木の部分木(サブツリー)であるかを判定する方法

    はじめに二つの二分木が与えられたとき、小さい方の木がもう一方の二分木の部分木(サブツリー)として含まれているかどうかを判定する方法を解説します。例として、以下のような二つの木を考えてみましょう。この場合、2番目の木は1番目の木の部分木となっています。判定アルゴリズムの考え方この性質を確認するためには、大きい方の木を後順走査(post-order traversal)でたどり、各ノードを根とする部分木が2番目の木と完全に一致するかどうかを順番に調べます。一致する部分木が一つでも見つかれば、2番目の木は1番目の木の部分木であると判定できます。判定の流れは以下の通りです。1. 部分木側がNULLであ