当前位置: 首页 > 编程语言 > C#

C#中的数独算法分享

时间:2023-04-10 23:24:00 C#

C#中的数独算法我需要一个衬里(或接近衬里)来验证给定的9个元素的数组不包含重复数字1,2,3,...,9.不计算重复的零(它们代表空单元格)。到目前为止我得到的最好的是:vara=newint[9]{1,2,3,4,5,6,7,8,9};varitIsOk=a.Join(a,i=>i,j=>j,(x,y)=>x).GroupBy(y=>y).Where(g=>g.Key>0&&g.计数()>1).计数()==0;如果你不想解决我的问题:),你至少能告诉我上面的算法是否有效吗?而且,是的,已经阅读了。幸运的是,不久前我自己构建了一个数独解算器:)整个过程大约有200行C#,它可以在4秒或更短的时间内解决我能找到的最棘手的难题。由于使用.Count,性能可能不是很好,但它应该可以工作:!a.Any(i=>i!=0&&a.Where(j=>j!=0&&i==j).Count>1)此外,j!=0部分并不是真正需要的,但它应该有助于运行得更快。[编辑:]kvb的回答给了我另一个想法:!a.Where(i=>i!=0).GroupBy(i=>i).Any(gp=>gp.Count()>1)inFilter0sbefore分组。虽然基于IEnumerable的工作方式,但这可能无关紧要。无论哪种方式,为了获得最佳性能,请将.Count>1替换为新的IEnumerable扩展方法,如下所示:boolMoreThanOne(thisIEnumerableenumerable,Predictatepred){boolflag=false;foreach(Titeminenumerable){if(pred(item)){if(flag)returntrue;标志=真;}}返回假;}这可能并不重要,因为数组被限制为9个项目,但如果你经常调用它,它可能会加起来。这比LINQ解决方案快大约50-250倍(取决于找到重复项的时间):publicstaticboolIsValid(int[]values){intflag=0;foreach(intvalueinvalues){if(value!=0){intbit=1!a.GroupBy(i=>i).Any(gp=>gp.Key!=0&&gp.Count()>1)为什么需要一行复杂的Linq代码而不是在扩展方法中包含一个有效的测试实现并调用它?vara=newint[9]{1,2,3,4,5,6,7,8,9};varitIsOk=a.HasNoNonZeroRepeats();NoNonZeroRepeats的一种实现可能是使用short的最低9位来指示数组中存在一个值,从而在不使用动态内存的情况下进行O(length(a))测试。Linq很可爱,但除非您只是出于审美原因使用它(您没有明确说您只是将Linq用作编写数独求解器的练习),否则它似乎只是增加了复杂性。这是一个老问题,但我最近指出了一个使用Oracle的自定义SQL树结构的单行解决方案。我认为将其转换为Linq会很好。您可以在我的博客上阅读更多有关如何在Linq中用1行解决数独的信息这是代码:while((leafNodesOfMoves.Length>0)&&(leafNodesOfMoves[0].IndexOf('')!=-1)){leafNodesOfMoves=(frompartialSolutioninleafNodesOfMovesletindex=partialSolution.IndexOf('')letcolumn=index%9letgroupOf3=index-(index%27)+column-(index%3)fromsearchLetterin"123456789"letInvalidPositions=fromspaceToCheckinEnumerable.Range(0,9)letIsInRow=partialSolution[index-column+spaceToCheck]==searchLetterletIsInColumn=partialSolution[column+(spaceToCheck*9)]==searchLetterletIsInGroupBoxOf3x3=partialSolution[groupOf3+(spaceToCheck%3)+(int)Math.Floor(spaceToCheck/3f)*9]==searchLetter其中IsInRow||IsInColumn||IsInGroupBoxOf3x3选择spaceToCheck其中InvalidPositions.Count()==0选择partialSolution.Substring(0,index)+searchLetter+partialSolution.Substring(index+1)).ToArray();}返回(leafNodesOfMoves.Length==0)?“无解”:leafNodesOfMoves[0];怎么样:varitIsOk=a.Where(x=>x>0).Di??stinct().Count()==a.Where(x=>x>0).Count();推理:首先创建一个枚举,其余数字不带0,如果其不同列表与实际列表长度相同,则不存在重复项。或者:如果唯一编号列表小于实际列表,则必须有重复编号。这是单线版本。a.Where(x=>x>0)列表可以被排除。varnonZeroList=a.Where(x=>x>0).ToList();varitIsOk=nonZeroList.Distinct().Count()==nonZeroList.Count();我通常对涉及捕获变量的解决方案犹豫不决,但我有一种冲动要写这个:boolhasRepeating=false;int前一个=0;intfirstDuplicateValue=a.Where(i=>i!=0).OrderBy(i=>i).FirstOrDefault(i=>{hasRepeating=(i==previous);previous=i;returnhasRepeating;});如果(hasRepeating){Console.WriteLine(firstDuplicateValue);为简洁起见,如果不是性能,varitIsOk=a.Sum()==a。清楚的()。和();以下是简单快捷的。以上就是C#学习教程:C#数独算法分享的全部内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注---ifa.Select(i=>Math.Pow(2,i-1)).ToArray().Sum()==511...本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: