文字列内の文字セットを確認する

文字列が与えられた場合、文字が同じ順序である必要があるが連続していないように文字列内に文字の集合が存在するかどうか(そしてその位置を見つける)

例えば「INEEDTOGETAHAIRCUT」という文字列、{'O'、 'E'、 'G'、 'T'}を見つけるセット

ありがとう

(ps - 私はすでにブルートフォースの試行を試みましたが、ひどいですし、うまくいきません!)

4
charachtersは文字列のどこにも出現できませんが、連続していなければなりませんが、順序は問題ではありません。なぜか分かりません。説明する方法がわからない
追加された 著者 Biscuit128,
OOOOは許可されておらず、セットOEGTを満たす4つの連続する文字列
追加された 著者 Biscuit128,
'OOOO'の値が許可されているか、O E GとTの任意の組み合わせを検索したいですか?
追加された 著者 Fischermaen,
質問は明確ではありません。 "お互いに追いかける限り、彼らはどんな順序でも構わない。"それは自己矛盾しているようです。
追加された 著者 David Heffernan,
{code} {'O'、 'E'、 'G'、 'T'} を使い果たすテスト文字列の4つの連続した文字を見つける必要があります。
追加された 著者 David Heffernan,
@アクロンええ。新しい質問は上記のRickiのコメントとはまったく異なります。
追加された 著者 David Heffernan,
私はかなり疑問を編集した人は、それの論理を変更しました。私はそれが不明だとは思わない...
追加された 著者 Akron,

5 答え

私はあなたが "文字がお互いに続く"ということを100%確信していないなら、可能なアプローチがあります:文字シーケンスのすべての可能な順列を生成する 順列を検索する

using System;
using System.Collections.Generic;
class Program {

    static IEnumerable GetPermutations(string value) {
        if (value.Length == 1) {
            yield return value;
        } else {
            for (int i = 0; i < value.Length; ++i) {
                string a = value[i].ToString();
                foreach (string b in GetPermutations(value.Remove(i, 1))) {
                    yield return a + b;
                }
            }
        }
    }

    static void Main(string[] args) {

        string test = "INEEDTOGETAHAIRCUT";
        string chars = "OEGT";
        foreach (string to_find in GetPermutations(chars)) {
            int i = test.IndexOf(to_find);
            if (i != -1) {
                Console.WriteLine("Found {0} at index {1}", to_find, i);
            }
        }
    }
}
1
追加された
まあ、私の唯一の問題は、複雑さの順です。しかしそれはおそらく尋問者のために重要ではない。
追加された 著者 Akron,

System.Linqを使用して、これを行うことができます:

"INEEDTOGETAHAIRCUT".ToCharArray().Any(c => c=='O' || c=='E' || c=='G' || c=='T');

または、文字配列を引数として受け入れるための新しい拡張メソッドを記述します。  どのような順序でも文字の「シーケンス」を得るには、これを行うことができます:

public static class MyExtensions
{

    public static bool ContainsAnySequenceOf(this String str, List charArray)
    {
        foreach (char c in charArray)
        {
            if (str.ToCharArray().Any(x => x == c))
            {
                charArray.Remove(c);
                return str.Substring(str.IndexOf(c), Math.Min(str.Length - str.IndexOf(c), charArray.Count)).ContainsAnySequenceOf(charArray);
            }
        }
        return false;
    }
}

それからこれを次のように呼んでください:

"INEEDTOGETAHAIRCUT".ContainsAnySequenceOf(new List {'O','E','G','T'});
1
追加された
OK。私は今あなたの質問を理解し、それを達成するために私の答えを編集しました。
追加された 著者 Andrea Colleoni,
ああ、それは完璧ですが、残念ながら私は真実ではなく虚偽ではありません。私は本当にこれを言及すべきだった:/
追加された 著者 Biscuit128,

あなたが必要とするものをチェックするために何かをもっと単純なものにするだけで2行にするのはどうか

string strCompare = "INEEDTOGETAHAIRCUT";
string strStringContains = ""AHRI"; 
var matchingString = strCompare.IndexOfAny(strStringContains.ToCharArray()) != -1;
then wrap the matchingString in an if(matchingString){ }//should return true or false
1
追加された

これは、問題を解決するための非常に面白い古い学校のアプローチです。コードの一部がより効率的になると確信していますが、検索セットのすべての並べ替えを列挙することは避けています(受け入れた回答のように)。それは高価になる可能性があります。

static bool matchesPermutation(string test, string search)
{
    string remaining = search;
    for (int i = 0; i < test.Length; i++)
    {
        int pos = remaining.IndexOf(test[i]);
        if (pos == -1)
            return false;
        else
            remaining = remaining.Remove(pos, 1);
    }
    return true;
}

static int findPermutation(string test, string search)
{
    for (int i = 0; i < test.Length-search.Length+1; i++)
        if (matchesPermutation(test.Substring(i, search.Length), search))
            return i;
    return -1;
}

static void Main(string[] args)
{
    string test = "INEEDTOGETAHAIRCUT";
    string search = "AHRI";
    int foundPos = findPermutation(test, search);
    Console.WriteLine(foundPos);
    if (foundPos != -1)
        Console.WriteLine(test.Substring(foundPos, search.Length));
}
0
追加された

あなたの質問を正しく理解していれば:

String.IndexOfAny()を使用して、シーケンス。

次に、文字列内の次の文字を繰り返し処理して、それぞれが有効な文字セットに含まれていることを確認します。リストから見つけた各文字(見つかった最初の文字を含む)については、その後に続く合法的な文字のリストから削除して、重複を禁止します。

違法文字にヒットした場合、テキストは一致しないので、このアルゴリズムの先頭に戻り、文字列の残りの部分を処理します。

あなたが行の中のすべての合法的な文字を見つけたら、あなたはあなたの結果を持っています。

0
追加された
最初の出現とは反対の、私のセットからの任意の文字の最初の出現のインデックスを返します。
追加された 著者 Biscuit128,
しかし、それは「文字がお互いに続くように」必要性を満たしていません。
追加された 著者 Fischermaen,
申し訳ありませんが、質問は少し不明でした。もう少しお手伝いして私の答えを更新しました。
追加された 著者 Jason Williams,
これらは私のPerlの習慣です。
追加された 著者 iehrlich,