C# 最短字表算法

C# 最短字表算法,c#,algorithm,C#,Algorithm,问题如下:用户提供了一个由X个字母组成的StartWord和EndWord字符串,以及一个长度也为X的字符串列表(设为4,但可能更多) static void Main(字符串[]args) { 字符串StartWord=“Spot”; 字符串EndWord=“Spin”; List providedList=新列表 { “旋转”、“吐”、“吐”、“点”、“跨度” }; 列表结果=MyFunc(开始、结束、提供的列表); } 公共列表MyFunc(字符串开始、字符串结束、列表输入) { ???

问题如下:用户提供了一个由X个字母组成的StartWord和EndWord字符串,以及一个长度也为X的字符串列表(设为4,但可能更多)

static void Main(字符串[]args)
{
字符串StartWord=“Spot”;
字符串EndWord=“Spin”;
List providedList=新列表
{
“旋转”、“吐”、“吐”、“点”、“跨度”
};
列表结果=MyFunc(开始、结束、提供的列表);
}
公共列表MyFunc(字符串开始、字符串结束、列表输入)
{
???
}
根据提供的参数,我需要向用户显示一个结果,该结果由4个字母单词的最短列表组成,从StartWord开始,以EndWord结束,在列表中可以找到许多中间单词,其中每个单词与前一个单词的差异正好是一个字母

例如,上述代码应返回包含以下元素的字符串列表: Spot(作为第一个词), Spit(只有一个字母与前面的单词不同), 旋转(作为结束语)

一个不好的例子是:斑点、飞溅、跨度、旋转(与上面的2个相比需要3个变化)

我一直在研究一些匹配算法和递归,但我不知道如何进行


感谢您事先提供的任何帮助

创建一个图,其中顶点是单词,边连接任何两个相差一个字母的单词

StartWord
开始,进行广度优先搜索,查找到
尾字的最短路径


下面是用另一种语言(Python)编写的此解决方案的示例代码。这可能会给你一个更好的指针。:-)


这就是我最终使用的(请随意评论它的上下两面):

private列出所有单词步骤;
私有字符串[]所有单词;
公共列表WordLadder(字符串wordStart、字符串wordEnd、字符串[]allWordsInput)
{
var wordLadder=new List(){wordStart};
this.allWordSteps=new List(){wordLadder};
allWords=allWords输入;
做
{
wordLadder=this.IterateWordSteps(wordEnd);
}
while(wordLadder.Count()==0);
返回字梯;
}
私有列表IterateWordSteps(字符串wordEnd)
{
List allWordSteps=this.allWordSteps.ToList();
this.allWordSteps.Clear();
foreach(AllWordStepScope中的变量wordSteps)
{
var nextant=this.allWords.Where(
x=>this.IsOneLetterDifferent(x,wordSteps.Last())&&
!wordSteps.Contains(x));
if(相邻的.Contains(wordEnd))
{
添加(wordEnd);
返回wordSteps;
}
foreach(相邻的变量字)
{
List newWordStep=wordSteps.ToList();
newWordStep.Add(word);
this.allWordSteps.Add(newWordStep);
}
}
返回新列表();
}
私有布尔值不同(字符串第一,字符串第二)
{
整数差=0;
if(first.Length==second.Length)
{
for(int i=0;i
听起来不错,但我的问题是要把它编写成代码,有没有可能得到一个片段?@IstvanNadj我提供了一个不同语言的解决方案,您可以尝试翻译。不要将解决方案嵌入问题中,而是写一个答案,并将其标记为acceptedIstvan Nadj,我已经回滚了你的无效编辑-发布自我回答是完全正确的,但是用答案编辑问题本质上使问题毫无意义是完全错误的。您可以将编辑内容从历史记录复制到新答案。Alexei Levenkov创建了一个anwser
static void Main(string[] args)
{
    string StartWord = "Spot";
    string EndWord = "Spin";
    List<string> providedList = new List<string>
                                {
                                "Spin", "Spit", "Spat", "Spot", "Span"
                                };
    List<string> result = MyFunc(StartWord, EndWord, providedList);
}

public List<string> MyFunc(string startWord, string endWord, List<string> input)
{
    ???
}
def shortestWordPath (startWord, endWord, words):
    graph = {}
    for word in words:
        graph[word] = {"connected": []}
    for word in words:
        for otherWord in words:
            if 1 == wordDistance(word, otherWord):
                graph[word]['connected'].append(otherWord)
    todo = [(startWord,0)]
    while len(todo):
        (thisWord, fromWord) = todo.pop(0)
        if thisWord == endWord:
            answer = [thisWord, fromWord]
            while graph[ answer[-1] ]["from"] != 0:
                answer.append(graph[ answer[-1] ]["from"])
            answer.reverse()
            return answer
        elif "from" in graph[thisWord]:
            pass # We have already processed this.
        else:
            graph[thisWord]["from"] = fromWord
            for nextWord in graph[thisWord]["connected"]:
                todo.append([nextWord, thisWord])
    return None


def wordDistance (word1, word2):
    return len(differentPositions(word1, word2))

def differentPositions(word1, word2):
    answer = []
    for i in range(0, min(len(word1), len(word2))):
        if word1[i] != word2[i]:
            answer.append(i)
    for i in range(min(len(word1), len(word2)),
                   max(len(word1), len(word2))):
        answer.append(i)
    return answer

print shortestWordPath("Spot", "Spin",
    ["Spin", "Spit", "Spat", "Spot", "Span"])
private List<List<string>> allWordSteps;
private string[] allWords;

public List<string> WordLadder(string wordStart, string wordEnd, string[] allWordsInput)
{
    var wordLadder = new List<string>() { wordStart };
    this.allWordSteps = new List<List<string>>() { wordLadder };
    allWords = allWordsInput;

    do
    {
        wordLadder = this.IterateWordSteps(wordEnd);
    }
    while (wordLadder.Count() == 0);

    return wordLadder;
}

private List<string> IterateWordSteps(string wordEnd)
{
    List<List<string>> allWordStepsCopy = this.allWordSteps.ToList();
    this.allWordSteps.Clear();
    foreach (var wordSteps in allWordStepsCopy)
    {
        var adjacent = this.allWords.Where(
            x => this.IsOneLetterDifferent(x, wordSteps.Last()) &&
                 !wordSteps.Contains(x));

        if (adjacent.Contains(wordEnd))
        {
            wordSteps.Add(wordEnd);
            return wordSteps;
        }

        foreach (var word in adjacent)
        {
            List<string> newWordStep = wordSteps.ToList();
            newWordStep.Add(word);
            this.allWordSteps.Add(newWordStep);
        }
    }

    return new List<string>();
}

private bool IsOneLetterDifferent(string first, string second)
{
    int differences = 0;
    if (first.Length == second.Length)
    {
        for (int i = 0; i < first.Length; i++)
        {
            if (first[i] != second[i])
            {
                differences++;
            }
        }
    }

    return differences == 1;
}