0

現在、私が取り組んでいる小さなプロジェクトをいじっています。これはカウントダウンタイプのゲーム(テレビ番組)です。現在、このプログラムでは、ユーザーが母音または子音を9文字の制限まで選択し、これらの9文字を使用して考えられる最長の単語を入力するように求めています。

辞書として機能する大きなテキストファイルがあり、ユーザーが入力した文字列を使用して検索し、結果を照合して、入力した単語が有効な単語であるかどうかを確認します。私の問題は、9文字で構成される最長の単語を辞書で検索したいのですが、それを実装する方法が見つからないようです。

これまで、すべての単語を配列に入れ、各要素を検索して文字が含まれているかどうかを確認しようとしましたが、9文字から作成できる最長の単語が8文字の単語であるかどうかはわかりません。何か案は?現在私はこれを持っています(これはフォームの送信ボタンの下にあります。コードを提供しなかったり、Windowsフォームアプリケーションであると言って申し訳ありません):

StreamReader textFile = new StreamReader("C:/Eclipse/Personal Projects/Local_Projects/Projects/CountDown/WindowsFormsApplication1/wordlist.txt");
int counter1 = 0;
String letterlist = (txtLetter1.Text + txtLetter2.Text + txtLetter3.Text + txtLetter4.Text + txtLetter5.Text + txtLetter6.Text + txtLetter7.Text + txtLetter8.Text + txtLetter9.Text); // stores the letters into a string
char[] letters = letterlist.ToCharArray(); // reads the letters into a char array
string[] line = File.ReadAllLines("C:/Eclipse/Personal Projects/Local_Projects/Projects/CountDown/WindowsFormsApplication1/wordlist.txt"); // reads every line in the word file into a string array (there is a new word on everyline, and theres 144k words, i assume this will be a big performance hit but i've never done anything like this before so im not sure ?)

line.Any(x => line.Contains(x)); // just playing with linq, i've no idea what im doing though as i've never used before
for (int i = 0; i < line.Length; i++)// a loop that loops for every word in the  string array
//  if (line.Contains(letters)) //checks if a word contains the letters in the char array(this is where it gets hazy if i went this way, i'd planned on only using words witha  letter length > 4, adding any words found to another text file and either finding the longest word then in this text file or keeping a running longest word i.e.  while looping i find a word with 7 letters, this is now the longest word, i then go to the next word and it has 8 of our letters, i now set the longest word to this)

counter1++;
if (counter1 > 4)

txtLongest.Text + = line + Environment.NewLine;

マイクのコード:

using System;

System.Collections.Genericを使用します。System.Linqを使用します。

クラスプログラム

static void Main(string[] args) {
    var letters = args[0];

    var wordList = new List<string> { "abcbca", "bca", "def" }; // dictionary

    var results = from string word in wordList // makes every word in dictionary into a seperate string
                  where IsValidAnswer(word, letters) // calls isvalid method
                  orderby word.Length descending // sorts the word with most letters to top
                  select word; // selects that word

    foreach (var result in results) {
        Console.WriteLine(result);    //  outputs the word
    }
}

private static bool IsValidAnswer(string word, string letters) {
    foreach (var letter in word) {
        if (letters.IndexOf(letter) == -1) { // checks if theres letters in the word
            return false;
        }

        letters = letters.Remove(letters.IndexOf(letter), 1);
    }

    return true;
}

}

4

6 に答える 6

1

これが私が数分で一緒にノックした答えです。あなたが望むことをするはずです。他の人が言っているように、この問題は複雑であるため、アルゴリズムは遅くなります。LINQクエリは、辞書内の各文字列を評価し、提供された文字を使用してその単語を生成できるかどうかを確認します。

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args) {
        var letters = args[0];

        var wordList = new List<string> { "abcbca", "bca", "def" };

        var results = from string word in wordList
                      where IsValidAnswer(word, letters)
                      orderby word.Length descending
                      select word;

        foreach (var result in results) {
            Console.WriteLine(result);    
        }
    }

    private static bool IsValidAnswer(string word, string letters) {
        foreach (var letter in word) {
            if (letters.IndexOf(letter) == -1) {
                return false;
            }

            letters = letters.Remove(letters.IndexOf(letter), 1);
        }

        return true;
    }
}
于 2013-02-21T17:14:38.620 に答える
0

私はこれについてもう少し考えました。これを効率的に行う方法は、辞書を前処理し、各単語の文字をアルファベット順に並べ、リスト内の単語もアルファベット順に並べることです(元の単語を保存するには、おそらく何らかのマルチマップ構造を使用する必要があります)。およびソートされた単語)。

それが済んだら、文字のプールから生成できる単語をはるかに効率的に見つけることができます。他の誰かが私を打ち負かさない場合は、後で戻ってこれを行うためのアルゴリズムを具体化します。

于 2013-02-22T00:08:43.317 に答える
0

それで、あなたはどこで立ち往生していますか?スローブルートフォース方式から始めて、すべての文字を含むすべての単語を見つけます。次に、単語を長さ順に並べて、最長にします。探している文字数よりも短い単語を返したくない場合(重複する文字がある場合にのみ問題になると思います???)、テストを追加してそのケースを排除します。

于 2013-02-21T16:55:40.353 に答える
0

ステップ1:各単語を文字でソートしてトライ構造を構築します。

例:EACHはACEHにソートされ、トライにA-> C-> E-> H->(EACH、ACHE、..)として格納されます(ACHEはEACHのアナグラムです)。

ステップ2:入力文字を並べ替えて、トライ内のその文字セットに対応する最長の単語を見つけます。

于 2013-02-22T02:14:56.690 に答える
-1

このようなものを実装してみましたか?あなたが試したコードを見るのは素晴らしいことです。

string[] strArray = {"ABCDEFG", "HIJKLMNOP"};
string findThisString = "JKL";
int strNumber;
int strIndex = 0;
for (strNumber = 0; strNumber < strArray.Length; strNumber++)
{
    strIndex = strArray[strNumber].IndexOf(findThisString);
    if (strIndex >= 0)
        break;
}
System.Console.WriteLine("String number: {0}\nString index: {1}",
    strNumber, strIndex);
于 2013-02-21T16:55:25.717 に答える
-1

これは仕事をしなければなりません:

private static void Main()
{
    char[] picked_char = {'r', 'a', 'j'};
    string[] dictionary = new[] {"rajan", "rajm", "rajnujaman", "rahim", "ranjan"};
    var words = dictionary.Where(word => picked_char.All(word.Contains)).OrderByDescending(word => word.Length);


    foreach (string needed_words in words)
    {
        Console.WriteLine(needed_words);
    }
}

出力:


rajnujaman
ranjan
rajan
rajm

于 2013-02-21T17:10:12.383 に答える