3

私は次のことを達成しようとしています。これらのフィールド (ID、コンテンツ) を含むテーブルがあるとします。

1 | りんご

2 | パイナップル

3 | 応用

4 | 国家

現在、考えられる一般的な一致をすべて教えてくれる関数を探しています。たとえば、引数が「3」の場合、関数は複数のレコードに現れる 3 文字から可能なすべての文字列を返します。

この場合、「app」、「ppl」、「ple」、「ati」、「tio」、「ion」を取得します。

引数が「4」の場合、「appl」、「pple」、「atio」、「tion」を取得します

引数が「5」の場合、「apple」、「ation」を取得します。

引数が「6」の場合、nohting が返されます。

これまで、これを実現する機能は見つかりませんでした。

どうも!

追加情報: MySQL データベースを使用する PHP スクリプトでこれを使用しています。引数として文字数と、もちろん検索するテーブルを指定したいだけです。

4

3 に答える 3

3

まあ、これはちょっと醜いですが、うまくいきます。これは汎用 SQL であり、あらゆる環境で機能します。読み取り中のフィールドの最大長を超える部分文字列の選択を生成するだけです。関数内の数値 50 をフィールド長を超える数値に変更します。非常に長いクエリが返される場合がありますが、前述のとおり、問題なく動作します。Python での例を次に示します。

import sqlite3

c = sqlite3.connect('test.db')

c.execute('create table myTable (id integer, content varchar[50])')
for id, content in ((1,'apple'),(2,'pineapple'),(3,'application'),(4,'nation')):
    c.execute('insert into myTable values (?,?)', [id,content])

c.commit();

def GenerateSQL(substrSize):
    subqueries = ["select substr(content,%i,%i) AS substr, count(*) AS myCount from myTable where length(substr(content,%i,%i))=%i group by substr(content,%i,%i) " % (i,substrSize,i,substrSize,substrSize,i,substrSize)  for i in range(50)]
    sql = 'select substr FROM \n\t(' + '\n\tunion all '.join(subqueries) + ') \nGROUP BY substr HAVING sum(myCount) > 1'
    return sql

print GenerateSQL(3)

print c.execute(GenerateSQL(3)).fetchall()

生成されたクエリは次のようになります。

select substr FROM 
    (select substr(content,0,3) AS substr, count(*) AS myCount from myTable where length(substr(content,0,3))=3 group by substr(content,0,3) 
    union all select substr(content,1,3) AS substr, count(*) AS myCount from myTable where length(substr(content,1,3))=3 group by substr(content,1,3) 
    union all select substr(content,2,3) AS substr, count(*) AS myCount from myTable where length(substr(content,2,3))=3 group by substr(content,2,3) 
    union all select substr(content,3,3) AS substr, count(*) AS myCount from myTable where length(substr(content,3,3))=3 group by substr(content,3,3) 
    union all select substr(content,4,3) AS substr, count(*) AS myCount from myTable where length(substr(content,4,3))=3 group by substr(content,4,3) 
    ... ) 
GROUP BY substr HAVING sum(myCount) > 1

そして、それが生み出す結果は次のとおりです。

[(u'app',), (u'ati',), (u'ion',), (u'nat',), (u'pin',), (u'ple',), (u'ppl',), (u'tio',)]
于 2009-07-20T04:32:19.573 に答える
2

しばらくphpで遊んでおらず、適切なテスト環境がないため、申し訳ありませんが、c#3.5でこれを行う方法をすぐに考案しました

擬似コード: 指定された長さの文字列とその横に出現回数を含むテーブルを作成します。カウント > 1 の場合を選択します。

    static void Main(string[] args)
    {

        string[] data = { "apple", "pinapple", "application", "nation" };
        string[] result = my_func(3,data);

        foreach (string str in result)
        {
            Console.WriteLine(str);
        }
        Console.ReadKey();
    }

    private static string[] my_func(int l, string[] data)
    {
        Dictionary<string,int> dict = new Dictionary<string,int>();
        foreach (string str in data)
        {
            for (int i = 0; i < str.Length - l + 1; i++)
            {
                string part = str.Substring(i, l);
                if (dict.ContainsKey(part))
                {
                    dict[part]++;
                }else {
                    dict.Add(part,1);
                }
            }
        }
        var result = from k in dict.Keys
                where dict[k] > 1
                orderby dict[k] descending
                select k;

        return result.ToArray<string>();
    }
于 2009-07-20T07:54:18.060 に答える
0

明らかなオプションの1つは、REGEXを使用することです。私はこれについて以前の経験はありませんが、これはあなたの助けになるかもしれません:http: //dev.mysql.com/doc/refman/5.1/en/regexp.html

必要なものに一致する適切な式を見つける必要があります。

于 2009-07-19T14:26:14.477 に答える