• 算法之枚举思想


    一: 思想

         有时我们解决某个问题时找不到一点规律。此时我们非常迷茫,非常痛苦,非常蛋疼,突然我们灵光一现。发现候选答案的问题规模在百万之内。

    此时我们就想到了从候选答案中逐一比較,一直找到正确解为止。

     

    二: 条件

         前面也说了,枚举是我们在无奈之后的最后一击,那么使用枚举时我们应该尽量遵守以下的两个条件。

         ①   地球人都不能给我找出此问题的潜在规律。

         ②   候选答案的集合是一个计算机必须可以承受的。

     

    三:举例

        以下是一个填写数字的模板,当中每一个字都代表数字中的”0~9“,那么要求我们输入的数字可以满足此模板。

    思路:首先拿到这个题,蛋还是比較疼的,由于找不到好的解题思路,细致想想这属于查找类型的问题,经常使用的查找也就5种,能适合

            该问题的查找也就”顺序查找“和”二分查找“,然后细致看看问题规模最多也就105=100000。事实上依据“二分"的思想在这个问题

            中并不合适,最后仅仅能用“顺序查找“了。

    复制代码
     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace Meiju
    7 {
    8 class Program
    9 {
    10 static void Main(string[] args)
    11 {
    12 int count = 0;
    13
    14 //“算”字的取值范围
    15 for (int i1 = 1; i1 < 10; i1++)
    16 {
    17 //“法”字的取值范围
    18 for (int i2 = 0; i2 < 10; i2++)
    19 {
    20 //“洗”字的取值范围
    21 for (int i3 = 0; i3 < 10; i3++)
    22 {
    23 //"脑"字的取值范围
    24 for (int i4 = 0; i4 < 10; i4++)
    25 {
    26 //"题"字的取值范围
    27 for (int i5 = 1; i5 < 10; i5++)
    28 {
    29 count++;
    30
    31 //一个猜想值
    32 var guess = (i1 * 10000 + i2 * 1000 + i3 * 100 + i4 * 10 + i5) * i1;
    33
    34 //终于结果值
    35 var result = i5 * 100000 + i5 * 10000 + i5 * 1000 + i5 * 100 + i5 * 10 + i5;
    36
    37 if (guess == result)
    38 {
    39 Console.WriteLine(" 不简单啊,费了我 {0}次,才tmd的找出来 ", count);
    40
    41 Console.WriteLine(" {0} {1} {2} {3} {4}", i1, i2, i3, i4, i5);
    42 Console.WriteLine(" X {0}", i1);
    43 Console.WriteLine("—————————————————————————————");
    44 Console.WriteLine(" {0} {1} {2} {3} {4} {5}", i5, i5, i5, i5, i5, i5);
    45
    46 Console.Read();
    47 }
    48
    49 Console.WriteLine("第{0}搜索", count);
    50
    51 }
    52 }
    53 }
    54 }
    55 }
    56
    57 Console.Read();
    58 }
    59 }
    60 }
    复制代码

     

    最后我们还是攻克了问题,发现当中的时间复杂度达到了O(n5),这个复杂度理论上是让人不能接收的,还好我们的n在10以内,

    n的每一次的自增对cpu来说都是莫大的伤害。


    有一种简单的算法就是从积枚举,由于积的形态比較特殊,xxxxx。所以仅仅有9种11111、22222、33333、44444、55555、66666、77777、88888、99999.这样算法的复杂度瞬间就降到了n2。

    现将你的想法用code实现一下。

    复制代码
     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace ConsoleApplication1
    7 {
    8 class Program
    9 {
    10 static void Main(string[] args)
    11 {
    12 //
    13 int[] resultArr = { 111111, 222222, 333333, 444444, 555555, 666666, 777777, 888888, 999999 };
    14
    15 //除数
    16 int[] numArr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    17
    18 int count = 0;
    19
    20 for (int i = 0; i < resultArr.Count(); i++)
    21 {
    22 for (int j = 0; j < numArr.Count(); j++)
    23 {
    24 count++;
    25
    26 var result = resultArr[i].ToString();
    27
    28 var num = numArr[j].ToString();
    29
    30 var origin = (resultArr[i] / numArr[j]).ToString();
    31
    32 if (origin.LastOrDefault() == result.FirstOrDefault()
    33 && origin.FirstOrDefault() == num.FirstOrDefault()
    34 && result.Length - 1 == origin.Length)
    35 {
    36 Console.WriteLine(" 费了{0} 次。tmd找出来了", count);
    37 Console.WriteLine(" 感谢一楼同学的回答。

    如今的时间复杂度已经减少到O(n2),相比之前方案已经是秒杀级别 ");
    38
    39 Console.WriteLine(" {0} {1} {2} {3} {4}", origin.ElementAt(0), origin.ElementAt(1), origin.ElementAt(2), origin.ElementAt(3), origin.ElementAt(4));
    40 Console.WriteLine(" X {0}", num);
    41 Console.WriteLine("—————————————————————————————");
    42 Console.WriteLine(" {0} {1} {2} {3} {4} {5}", result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0), result.ElementAt(0));
    43
    44 Console.Read();
    45 }
    46 Console.WriteLine("第{0}搜索", count);
    47 }
    48 }
    49 Console.WriteLine("无解");
    50 Console.Read();
    51 }
    52 }
    53 }

    复制代码

     


  • 相关阅读:
    (07)使用WireMock快速伪造REST服务
    (06)使用Swagger自动生成html文档,描述API接口
    (05)使用DeferredResult多线程异步处理请求
    (04)Spring开发中的3种拦截机制
    (03)使用SpringBoot自定义Restful风格异常处理,返回json格式数据
    (02)Restful风格的增删改查、上传、下载案例及其junit测试详解
    (01)Restful简介
    (03)maven项目分模块开发,子项目继承自父项目,打包运行方法
    (018)Spring Boot之常用配置
    (031)Spring Boot之服务的注册与发现,使用zookeeper演示负载均衡
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7249608.html
Copyright © 2020-2023  润新知