Linq高级应用

  Linq的应用为我们带来了很大的方便,提高了coding效率,最近看到了一个用linq写的数独游戏算法,让我看到了Linq写的是如此优雅,耳目一新的感觉,以前没有写过这样的代码,同时也感觉到原来Linq如此强大,以前大部分使用的地方主要是在集合中使用.

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

namespace SingleNumber
{
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] source =
            {
                5, 4, 0, 2, 9, 0, 0, 1, 0,
                0, 2, 0, 0, 0, 6, 3, 0, 0,
                3, 0, 0, 1, 0, 0, 0, 5, 4,
                0, 6, 0, 0, 0, 8, 9, 0, 0,
                2, 5, 0, 6, 7, 0, 0, 3, 1,
                0, 0, 1, 0, 2, 0, 0, 6, 0,
                8, 3, 0, 0, 0, 4, 0, 0, 6,
                0, 0, 5, 9, 0, 0, 0, 8, 0,
                0, 7, 0, 0, 3, 1, 0, 4, 2
            }; // http://www.sudoku.name/index-cn.php #10332 数独来自这个网站
                int[] result = source.ToArray();   // result数组保存解算中间数据和结果
                Func<bool> IsFinished = () => result.Where(x => x == 0).Count() == 0;  // 判断是否解算完成
                Func<int> NextNumber = () => result.Select((x, i) => new
                {
                    x,
                    i
                }).First(x => x.x == 0).i; // 取下一个空格(这个算法不是唯一的,你也可以从后往前填写,或者别的方法)
                Func<IEnumerable<int>> TryValues = () =>
                {
                    int pos = NextNumber(); // 获取空格
                    int col = pos % 9; // 行号
                    int row = pos / 9; // 列号
                    int group = (row / 3) * 3 + col / 3; // 宫号
                    var colnums = Enumerable.Range(1, 9).Except(Enumerable.Range(0, 81).Where(x => x % 9 == col).Select(x => result[x]).Where(x => x != 0)); // 让1-9和本列已有数据对比,求差集,差集是对于列,允许填入的数字,下面类似
                    var rownums = Enumerable.Range(1, 9).Except(Enumerable.Range(0, 81).Where(x => x / 9 == row).Select(x => result[x]).Where(x => x != 0));
                    var groupnumbers = Enumerable.Range(1, 9).Except(Enumerable.Range(0, 81).Where(x => ((x / 9) / 3) * 3 + (x % 9) / 3 == group).Select(x => result[x]).Where(x => x != 0));
                    return colnums.Intersect(rownums).Intersect(groupnumbers); //数据是行、列、宫的交集
                }; // 找出填写这个空格的所有可能尝试的数据

Action DisplayResult = () => Console.WriteLine(string.Join("\r\n", result.Select((x, i) => new
                {
                    x,
                    i
                }).GroupBy(x => x.i / 9).Select(x => string.Join(" ", x.Select(y => y.x))))); // 显示结果
                Action Solve = () =>
                {
                }; // 递归Lambda必须先定义一个空的。
                Solve = () =>
                {
                    if (IsFinished())
                    {
                        DisplayResult(); //如果全部填满,就输出结果(严格地,应该考虑无解的情况,这里忽略)
                    }
                    else
                    {
                        int pos = NextNumber(); // 获取空格位置
                        foreach (int item in TryValues()) // 依次尝试所有可能的数字
                        {
                            result[pos] = item; // 将盘面设置为尝试数字
                            Solve(); //下一层解算
                        }
                        result[pos] = 0; // 尝试完还不行,恢复盘面,回溯上一层
                    }
                }; // 算法主体
                Solve(); // 开始解算
                Console.Read();
            }
        }
    }
}
代码注释的很详细,就不再解释了.欢迎爱好者一起讨论。

时间: 2024-10-07 19:54:45

Linq高级应用的相关文章

Linq高级查询与分页查询

Linq高级查询 以~开头: r=>r.Name.StartsWith("李"); 以~结尾: r=>r.Name.EndsWith("光"); 包含(模糊查询): r=>r.Name.Contains("四"); 数据总个数: Con.Goods.Count();||Con.Users.ToList().count; 最大值: Con.Goods.ToList().Max(r=>r.Price); 最小值: Con.Go

LinQ 高级查询

Linq高级查:字符串:模糊查(包含):con.car.Where(r => r.name.Contains(name)).ToList();以什么开头:con.car.Where(r => r.name.StartsWith(name)).ToList();以什么结尾:con.car.Where(r => r.name.EndsWith(name)).ToList(); 数值:个数:.Count()最大值:con.car.Max(r => r.price);最小值:con.car

Webform(Linq高级查、分页、组合查询)

Linq高级查:字符串:模糊查(包含):con.car.Where(r => r.name.Contains(name)).ToList();以什么开头:con.car.Where(r => r.name.StartsWith(name)).ToList();以什么结尾:con.car.Where(r => r.name.EndsWith(name)).ToList(); 数值:个数:.Count()最大值:con.car.Max(r => r.price);最小值:con.car

Linq——高级查询方法入门

一,Lambda表达式 lambda表达式刚开始用的时候还很不习惯,因为以前用惯了那种先foreach,再逐个判断的麻烦形式,刚开始用lambda都会在脑子里转一下,变成自己让自己舒服的格式,但是写过几行代码后,就会喜欢上这种形式,首先,它比较简洁,其次,和LINQ组合起来用感觉非常贴近SQL: 二,LINQ高级查询内容简介 LINQ的写法有两种,一种是语句形式,一种是方法形式,但是语句形式支持的功能貌似不足方法强大,所以,有些时候写语句形式的LINQ表达式还要加入方法.在编译的时候,也是将语句

linq高级查询

Linq高级查 开头: Repeater1.DataSource = con.Users.Where(r => r.NickName.StartsWith("值")); 结尾: Repeater1.DataSource = con.Users. Where( r => r.NickName.EndsWith("值")); 模糊查(包含):Repeater1.DataSource = con.Users.Where(r => r.NickName.C

LinQ—高级查询方法

对于高级查询方法,主要分为五大类,详情下图: [Distinct]:  避免重复值出现,也就是如果有两个数字2,那么使用集合类可以单一出现 首先我们来写一个数组,方便举例: // 数组数据persons int[ ] Arr = { 25, 36, 25, 2, 3, 9, 55, 581, 21, 15, 44, 78, 96 }; 聚合类 Console.WriteLine("arr的最大值:" + Arr.Max()); Console.WriteLine("arr的最

2017年12月14日 LinQ高级查&amp;&amp;Asp.net WebForm Asp.net MVC

LinQ的高级查询用法 开头:StartsWith()结尾:EndsWith()模糊:Contains() 个数:Count最大值:Max(r => r.price)最小值:Min(r => r.price)平均值:Average(r => r.price)求和:Sum(r => r.price) 升序:OrderBy(r => r.price);降序:OrderByDescending(r => r.price) 分页:Skip(从第几项开始).Take(取几个) A

2017-6-2 Linq 高级查询 (分页和组合查)、集合取交集

1.linq分页和组合查询:(用项目实战来解释) <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <he

linq高级查与分页

前台代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="LinQ数据显示.aspx.cs" Inherits="LinQ数据显示" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="ser