编程挑战--最小操作数(C#.Net版算法)

来源:互联网 发布:ipad能编辑淘宝店铺 编辑:程序博客网 时间:2024/06/07 16:17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
题目详情

给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。


   举个例子如下:

Given:

   A = "hit"

   B = "cog"

   Dict = ["hot","dot","dog","lot","log"]

Return

 [

   ["hit","hot","dot","dog","cog"],

   ["hit","hot","lot","log","cog"]

 ]


    即把字符串A = "hit"转变成字符串B = "cog",有以下两种可能:

  1. "hit" -> "hot" ->  "dot" ->  "dog" -> "cog";
  2. "hit" ->  "hot" ->  "lot" ->  "log"  ->"cog"。
*/
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string a = "hit";
            string temp = "cog";
            string[] dic = { "hot", "dot", "dog", "lot", "log" };
            if (a.Length != temp.Length)
            {
                Console.Write("没有匹配的转换");
                Console.Read();
                return;
            }
            if (a == temp)
            {
                Console.Write("两个字符串相等");
                Console.Read();
                return;
            }
            List<List<string>> lists = new List<List<string>>();
            List<string> printList = new List<string>();
            if (!Match(a, temp, dic, printList, lists))
            {
                Console.Write("没有匹配的转换");
            }
            foreach (List<string> list in lists)
            {
                int i = 1;
                foreach (string s in list)
                {
                    if (i == list.Count)
                        Console.Write(s);
                    else
                    {
                        Console.Write(s + ",");
                    }
                    i++;
                }
                Console.WriteLine();
            }
            Console.Read();
        }
        /// <summary>
        /// 匹配引擎
        /// </summary>
        /// <param name="a"></param>
        /// <param name="temp"></param>
        /// <param name="dic"></param>
        /// <param name="printList"></param>
        /// <param name="lists"></param>
        /// <returns></returns>
        private static bool Match(string a, string temp, string[] dic, List<string> printList, List<List<string>> lists)
        {
            printList.Insert(0, temp);
            bool isMatch = false;
            int matchIndex = -1;
            int aMatch = MatchingString(temp, a);
            if (aMatch == 1)
            {
                printList.Insert(0, a);
                if (lists.Count == 0) lists.Add(printList);
                else if (printList.Count == lists[0].Count)
                {
                    lists.Add(printList);
                }
                else if (printList.Count < lists[0].Count)
                {
                    lists.Clear();
                    lists.Add(printList);
                }
                isMatch = true;
            }
            for (int i = 0; i < dic.Length; i++)
            {
                int match = MatchingString(temp, dic[i]);
                if (match == 1)
                {
                    matchIndex = i;
                    if (Match(a, dic[i], RemoveItem(i, dic), CopyString(printList), lists))
                        isMatch = true;
                }
            }
            return isMatch;
        }
        /// <summary>
        /// 复制一个List
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static List<string> CopyString(List<string> list)
        {
            List<string> newList = new List<string>();
            foreach (string s in list)
            {
                newList.Add(s);


            }
            return newList;
        }
        /// <summary>
        /// 匹配两个字符串,返回两个单词的差异数
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        private static int MatchingString(string a, string b)
        {
            int count = 0;
            if (a.Length != b.Length) return 0;//字符串不相等,直接返回0
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] != b[i])
                {
                    count++;
                }
            }
            return count;
        }
        /// <summary>
        /// 从字符串中移除指定索引的元素,返回一个新字符串
        /// </summary>
        /// <param name="index"></param>
        /// <param name="dic"></param>
        /// <returns></returns>
        private static string[] RemoveItem(int index, string[] dic)
        {
            string[] newArray = new string[dic.Length - 1];
            int count = 0;
            for (int i = 0; i < dic.Length; i++)
            {
                if (i == index) continue;
                newArray[count] = dic[i];
                count++;
            }
            return newArray;
        }
    }


}