关于做书的网站seo哪家好
web/
2025/10/8 23:59:37/
文章来源:
关于做书的网站,seo哪家好,可以做驾校推广的网站,优化方案2022版语文这是一个半技术向的博客#xff0c;主题来源于我读过的某本书的片段#xff0c;这是一个稍稍有些前置知识的故事#xff0c;主题的大概内容就是假定世界存在某个规则序列#xff0c;通过一代代的探索#xff0c;可以获取到此序列的内容。本文将模拟此情形#xff0c;写一…这是一个半技术向的博客主题来源于我读过的某本书的片段这是一个稍稍有些前置知识的故事主题的大概内容就是假定世界存在某个规则序列通过一代代的探索可以获取到此序列的内容。本文将模拟此情形写一个随机数的小测试应用来不严谨的证明或者准确来说是用代码讲述这个故事天有五贼见之者昌。 传说在一个由某逗写的代码世界里面世界里藏着一段取值范围为 0 到 100 且长度为 10 的序列。某逗将此序列称为世界序列。在此世界里面还生活着一群名为 Element 的小人儿。这些 Element 小人儿都在探索和追求着世界序列。因为呀每当此世界经过一代的时候嗯约等于某个大循环执行一遍的时候将会根据此世界序列的内容再加上某逗规定的算法决定哪些 Element 小人儿需要被淘汰掉。已知的是如果 Element 小人儿越了解准确世界序列那 Element 小人儿就越能生存下来此世界每经过一代将会淘汰一批 Element 小人儿。而存活下来的 Element 小人儿将会迎来新的一轮生娃过程。可以由存活下来的 Element 小人儿创建出更多的下一代的 Element 小人儿在经过此世界的很多代之后咱来看看存活下来的 Element 小人儿是否都掌握了正确的世界序列接下来就是写代码的内容了命题确定了其实通过简单的大学数学的知识是能够计算出结果的只不过咱是计算机系的肯定要写点代码啦按照本文的题注天有五贼见之者昌先用代码写天有五贼。我的文学修养还不够不能达意的解释天有五贼见之者昌这句话。只能用代码的方式以一个片面的方式来解释。在某逗写的代码世界里面此世界的世界序列就是对应着天有五贼的意思。这片天地有五贼五贼大概就是金木水火土五行的意思也等于说世界的规则或者说世界的本源。本文的世界序列就大概属于某逗写的代码世界里面的本源。而见之者昌可以认为是如果有人可以知晓五贼约等于说如果有人可以知道世界的规则或者说世界的本源那他将会昌盛。对应某逗写的代码世界里面的 Element 小人儿如果 Element 小人儿能够知晓世界序列那他更能在此代码世界的一代代循环里面存活而且 Element 小人儿也就能生产更多的下一代的 Element 小人儿不断昌盛某逗写的代码世界里的世界序列序列里面的每个项都可以用一个 Key 的只读结构体来表示。之所以不直接使用 int 等来表示那是为了给一个单位这属于程序员的修养。如以下代码定义了 Key 这个只读结构体本文代码基于 dotnet 7 版本编写本文代码都在 GitHub 上开源readonly record struct Key(int N)
{public const int MaxKeyValue 100;
}世界序列也就是一个 ListKey 类型。当然有了代码世界为了代码世界能够好好工作还需要一个世界管理者也就是以下代码定义的 Manager 类型在 Manager 里面就存放了世界序列代码如下class Manager
{public ListKey KeyList { get; }... // 忽略其他代码
}生活在代码世界里面的是一群 Element 小人儿使用的是 Element 类型每个 Element 小人儿都有自己的一段序列。这就是 Element 小人儿最重要的也是不断探索的内容class Element
{public ListKey KeyList { get; } new ListKey();... // 忽略其他代码
}在代码世界刚开始的时候也就是 Manager 被创建出来的时候将会立刻初始化世界序列public Manager(){KeyList new ListKey();for (int i 0; i 10; i){var key Random.Shared.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));}}世界开始的时候将会进入 Manager 的 Start 方法在初始化世界时将会创建出首批的 Element 小人儿如以下代码由于怕电脑被玩坏这里约束了 Element 小人儿的数量大概只有 10000 个class Manager
{public void Start(){for (int i 0; i 10000; i){var element CreateElement();ElementList.Add(element);}}public ListElement ElementList { get; } new ListElement();... // 忽略其他代码
}以上的 CreateElement 方法是一个用来辅助创建 Element 小人儿对象的方法在实现他之前还请先看看 Element 类型的构造函数吧在 Element 类型里面不仅包含了 KeyList 属性还包括了两个辅助代码运行的属性分别是 Random 随机数属性和 FinishBuildKey 属性还请让我卖个关子在本文后续部分再来揭晓 FinishBuildKey 属性的作用。在 Element 类型的构造函数里面将要求传入 Random 属性以让 Element 在每一代里面拥有猜测世界序列的能力且多个 Element 之间有奇妙的关系class Element
{public Element(Random random){Random random;}public Random Random { get; }private bool FinishBuildKey { get; set; }public ListKey KeyList { get; } new ListKey();... // 忽略其他代码
}在了解到 Element 的构造函数之后相信大家也能猜到 CreateElement 方法的实现了private Element CreateElement(){Element element new Element(new Random(Random.Shared.Next()));return element;}在完成了代码世界的首批 Element 小人儿创建之后就要进入激烈的世界迭代了。先创建一个大循环大概是 10000 次。表示这个世界将会开始迭代 10000 次for (int i 0; i 10000; i){... // 忽略其他代码}在每一代的开始时都会让每个 Element 小人儿进行一轮思考让 Element 决定是否在自己的 KeyList 里面加上新的 Key 值。当然每个 Element 小人儿的思考方式现在就是通过 Random 随机数生成的哈for (int i 0; i 10000; i){foreach (var element in ElementList){element.BuildKey();}... // 忽略其他代码}以上的 BuildKey 函数就是放在 Element 里的函数用于让 Element 小人儿思考新的 Key 值是什么大概的实现如下class Element
{public bool BuildKey(){var key Random.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));return true;}... // 忽略其他代码
}当然了有些 Element 小人儿决定放弃思考也就是 Element 可以不再生成新的 Key 值。这也就是上文卖关子的 FinishBuildKey 属性的作用此属性用来判断是否此 Element 已不再生成新的 Key 值了约等于此 Element 认为自己已猜出了世界序列class Element
{public bool BuildKey(){if (KeyList.Count 0 (FinishBuildKey || Random.Shared.Next(10) 1)){FinishBuildKey true;return false;}var key Random.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));return true;}... // 忽略其他代码
}等待各个 Element 思考完成之后此代码世界的考验就要开始了。在此世界的天道规则是从当前的世界序列里面通过当前世界的代数也就是世界大循环的 i 变量的值决定出世界序列中的一个 Key 值。对于每个 Element 来说也要根据当前世界的代数返回一个 Key 值。一旦 Element 的返回的 Key 和此世界的 Key 值不相同那么此 Element 将会被淘汰说起来简单先来看看代码如何实现先实现从当前的世界序列里面通过当前世界的代数也就是世界大循环的 i 变量的值决定出世界序列中的一个 Key 值class Manager
{public void Start(){... // 忽略其他代码for (int i 0; i 10000; i){... // 忽略其他代码var key GetKey(i);... // 忽略其他代码}}public Key GetKey(int n){var index n % KeyList.Count;return KeyList[index];}... // 忽略其他代码
}每个 Element 也实现 GetKey 方法也是通过传入的序号返回一个 Key 值class Element
{public Key GetKey(int n){var index n % KeyList.Count;return KeyList[index];}... // 忽略其他代码
}判断 Element 返回的 Key 是否和世界的相同如果不相同将会淘汰。代码只需要一句话就可以完成实现那就是返回 Key 不相同的从 Manager 的 ElementList 列表里面移除class Manager
{public void Start(){... // 忽略其他代码for (int i 0; i 10000; i){... // 忽略其他代码var key GetKey(i);ElementList.RemoveAll(element element.GetKey(i).N ! key.N);... // 忽略其他代码}}... // 忽略其他代码
}对于从 ElementList 被移除的 Element 来说等待这些 Element 就是凌驾于此世界之上的 dotnet 的 GC 回收机制将其当初垃圾清理掉经过了世界的一次考验最后剩下的 Element 不多。此世界显得十分空旷就给了这些存活的 Element 创建子 Element 的机会在 Element 里实现 Create 方法用来通过当前的 Element 创建新的 Element 对象class Element
{public Element Create(){Element element new Element(Random);foreach (var key in KeyList){element.KeyList.Add(key);}return element;}... // 忽略其他代码
}通过以上代码可以看到新创建的 Element 不仅继承了用来思考的 Random 随机数还继承了前辈对世界序列的思考也就是 KeyList 元素。接下来新的 Element 可以继续在前辈的基础上对世界序列进行思考在 Manager 完成考验将调用 Element 的 Create 方法让此世界继续被填充class Manager
{public void Start(){... // 忽略其他代码for (int i 0; i 10000; i){... // 忽略其他代码var currentCount ElementList.Count;while (ElementList.Count 10000){for (int index 0; index currentCount; index){var element ElementList[index];ElementList.Add(element.Create());}}... // 忽略其他代码}}... // 忽略其他代码
}如果当前的世界考验干掉了绝大部分的 Element 对象那么剩下的 Element 就有更多的机会创建出新的 Element 对象为了防止灭世也就是某次考验干掉了此世界上所有 Element 小人儿在每次迭代的时候如果世界太过空旷将会额外加上从空白里创建的新 Element 对象和世界的首批 Element 一样从石头蹦出来的每次迭代都会尝试加上一些从石头里面蹦出来的新 Element 对象更改后的代码如下class Manager
{public void Start(){... // 忽略其他代码for (int i 0; i 10000; i){... // 忽略其他代码bool addElement false;var currentCount ElementList.Count;while (ElementList.Count 10000){for (int index 0; index currentCount; index){var element ElementList[index];ElementList.Add(element.Create());}if (addElement){continue;}addElement true;var addCount 10000 - ElementList.Count;addCount Math.Min(addCount, 100);for (int index 0; index addCount; index){var element CreateElement();ElementList.Add(element);}}... // 忽略其他代码}}... // 忽略其他代码
}如此的进行迭代在完成了世界的大循环也就是 10000 次之后将会开始最后的审判。判断剩下的 Element 是否了解了世界序列以及了解了多少次class Manager
{public void Start(){... // 忽略其他代码for (int i 0; i 10000; i){... // 忽略其他代码}for (var i 0; i KeyList.Count; i){var key GetKey(i);ElementList.RemoveAll(element element.GetKey(i).N ! key.N);}}... // 忽略其他代码
}最后剩下的都是明了世界序列也就是明了此世界本质的 Element 小人儿完成代码编写之后放入 Main 函数用来启动世界internal class Program
{static void Main(string[] args){Manager manager new Manager();manager.Start();}
}此代码版本放在 GitHub 上可以从 https://github.com/lindexi/lindexi_gd/commit/49878e97df5c75c22d40294b6970aaf46b11c218 获取全部代码运行代码的结果是最后剩下的 Element 小人儿都明了世界序列。其实这也是因为继承了前辈们的知识从前辈那里拿到了 KeyList 才让越后创建的 Element 有越高的生存率以上是一个简单的版本世界序列是非常裸的参与计算或者说没有参与计算就根据序列进行返回。接下来对这个世界的游戏规则加上更多的难度应用上加法规则。加法规则就是取随机的数值例如 3 个数值作为序号再根据序号一一取出 Key 值接着将 Key 值取和返回一个数值。此规则同时也对每个 Element 执行一旦发现 Element 计算出来的最终数值和世界计算出来的不匹配那就将此 Element 淘汰新的这个游戏规则其实对 Element 来说更有挑战性也同时带来了新的数学上的计算方法那就是如果 Element 猜测的世界序列和此世界的世界序列不匹配也有可能在取出的数值里面通过加法返回相同的值。换句话说每个 Element 在一轮迭代里面如果没有被淘汰那也是无法知道当前猜测的世界序列是否正确。对比之前的规则之前的规则一旦猜测错误自然就会被淘汰改造一下代码让 Element 和 Manager 都继承 IKeyManager 接口方便同时应用上相同的加法规则。这个 IKeyManager 接口定义如下interface IKeyManager
{Key GetKey(int n);
}加法计算规则的代码实现如下根据传入参数的序列获取的 Key 值取 Key 值的总和class Manager
{private int BuildByKey(IKeyManager keyManager, IListint indexList){var n 0;foreach (var index in indexList){var key keyManager.GetKey(index);n key.N;}return n;}... // 忽略其他代码
}看到这里也许机智的大家也就猜到了。世界序列对应着世界的本源数据而加法规则对应的通过世界本源数据进行的一套规则。有世界本源数据加上世界的本源规则即可展现出有趣的世界。有世界的本源规则的存在也就是此代码世界的加法规则的存在将会让 Element 小人儿更加难以知道自己所了解的世界规则是对是错按照以上的加法规则只要几个 Key 相加的和相等即可而从数学上这是无法反算唯一解的。举个例子假定 indexList 里面有三个序号分别是 1 2 3 三个序号。而 keyManager 里面根据 1 2 3 返回的 Key 分别是 10 20 30 三个 Key 值计算出的结果是 60 的值。那反过来已知返回值是 60 且传入序号是 1 2 3 三个序号。请问 keyManager 存放的 KeyList 里面的第 1 和 第 2 和 第 3 的 Key 应该是多少 抽象出来的数学题就是已知三个数加起来的总和是 60 求这三个数。读过小学数学的大家自然就知道这三个数没有唯一解如此加法规则一开始就要求取序列里面的几个 Key 值这就要求 Element 小人儿需要一开始就初始化一段 Key 列表。否则就不好玩了。经过实际的测试结果我发现如果不告诉 Element 小人儿 世界序列的长度 的话那 Element 小人儿 几乎不能在世界大循环结束之前明了世界序列。降低游戏的难度我将告诉 Element 小人儿 世界序列 的长度是 10 个 Key 值。同时也更改了 Element 的 BuildKey 方法让此方法可以在一开始就生成了序列在之前的代码基础上修改 Element 的 BuildKey 方法本来是 BuildKey 方法每次世界迭代都会调用现在修改为只有 Element 被创建时才调用修改过之后的代码如下以下的代码还不是最终的版本在下文将会告诉大家最终的版本代码class Element
{public void BuildKey(){const int count 10;while (KeyList.Count count){var key Random.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));}}... // 忽略其他代码
}以上的代码可以让 Element 创建出来一段序列序列长度和世界序列长度相同接着从世界循环里面删掉每次迭代都调用 BuildKey 方法的代码也就是这段代码foreach (var element in ElementList){element.BuildKey();}将调用 BuildKey 方法的代码放入到 CreateElement 方法里修改之后的方法代码如下class Manager
{private Element CreateElement(){Element element new Element(new Random(Random.Shared.Next()));element.BuildKey();return element;}... // 忽略其他代码
}每次世界迭代都会取出随机三个数值将这三个随机数值传入到 BuildByKey 方法里通过加法规则算出总和。将此方式分别应用在世界序列和每个 Element 上将计算结果和世界序列计算出来的不相同的 Element 淘汰掉实现的代码如下每次迭代随机三个数值可以先放入到一个数组里面class Manager
{public void Start(){... // 忽略其他代码var indexList new int[3];for (int i 0; i 10000; i){... // 忽略其他代码}}... // 忽略其他代码
}每次调用 UpdateRandomIndexList 方法将 indexList 加上三个随机数值class Manager
{public void Start(){... // 忽略其他代码var indexList new int[3];for (int i 0; i 10000; i){UpdateRandomIndexList(indexList);... // 忽略其他代码}}private void UpdateRandomIndexList(int[] indexList){for (var i 0; i indexList.Length; i){indexList[i] Random.Shared.Next();}}... // 忽略其他代码
}先计算世界序列经过 BuildByKey 的值class Manager
{public void Start(){... // 忽略其他代码var indexList new int[3];for (int i 0; i 10000; i){UpdateRandomIndexList(indexList);var key BuildByKey(this, indexList);... // 忽略其他代码}}... // 忽略其他代码
}接着依然是一句代码将 ElementList 里面计算结果不等于 key 值的 Element 淘汰class Manager
{public void Start(){... // 忽略其他代码var indexList new int[3];for (int i 0; i 10000; i){UpdateRandomIndexList(indexList);var key BuildByKey(this, indexList);ElementList.RemoveAll(element BuildByKey(element, indexList) ! key);... // 忽略其他代码}}... // 忽略其他代码
}淘汰之后依然就到了根据剩下存活的 Element 构建出来新的 Element 的步骤了。由于这次的 BuildKey 只有在元素创建的时候才被调用这就意味着需要改造 Create 方法让 Element 的在创建时调用 BuildKey 方法修改之后的代码如下class Element
{public Element Create(){Element element new Element(Random);foreach (var key in KeyList){element.KeyList.Add(key);}element.BuildKey();return element;}... // 忽略其他代码
}而根据以上的 BuildKey 方法的代码只是将 KeyList 序列生成到 10 个显然不符合当前的需求。毕竟现在在创建的时候就设置了 KeyList 内容了这会让 BuildKey 方法啥都没有做。 继续优化 BuildKey 方法让此方法可以将 KeyList 进行更改class Element
{public void BuildKey(){const int count 10;while (KeyList.Count count){var key Random.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));}KeyList[Random.Next(count)] new Key(Random.Next(Key.MaxKeyValue));}... // 忽略其他代码
}以上代码就是优化完成之后的 BuildKey 方法。大概映射的含义就是子 Element 可以从前辈继承到 KeyList 知识只是子 Element 要做出变化变化就是修改 KeyList 中的数据。当前的变化只是修改一项而已更改完成之后即可开始跑代码。当前的代码的含义总的来说就是在此世界里面有一段世界序列世界规则将根据世界序列计算出一个值同样的世界规则也使用相同的算法应用在每个 Element 小人儿上一旦发现两者计算结果不相同那么 Element 小人儿将被淘汰。存活下来的 Element 小人儿将可以创建出下一代 Element 小人儿出来创建的时候可以将自己的知识传授给下一代。而下一代 Element 小人儿也不是全盘接受的而是会经过自己的思考优化从前辈继承到 KeyList 知识只不过呢在此世界里面世界规则只是一个加法规则。而下一代 Element 小人儿的思考也只是一段随机数尝试运行程序可以看到这一次灭世的情况发生的次数比一开始的代码的多。灭世的情况就是在世界的某一代中存活下来的 Element 小人儿的数量是 0 个。可以看到当前代码的规则让 Element 小人儿更加难以应对。但也同时发现了这样的规律一旦开始有某个 Element 小人儿掌握了一定数量的正确的世界序列的值时此 Element 小人儿将可以创建出更多更好存活的下一代 Element 小人儿举个例子来说明运行的情况假定世界序列就是从 0 到 9 的 10 个 Key 数值。某个 Element 掌握的序列就是 1020120120 序列。刚好一开始的 indexList 就是取前三个这就让 Element 存活起来了。于是接下来 Element 将创建出下一代的 Element 出来。下一代的 Element 刚好修改的第 3 个从0开始序号为 4 的值修改之后的是 1024120120 序列。下一轮世界取的 indexList 是 1 2 3 三个序号世界序列计算结果是 1236 的值。而原先的 Element 计算出来的是 0202 被淘汰而下一代的 Element 计算出来的是 0246 存活。可以看到尽管下一代的 Element 没有思考出正确的世界序列然而在世界规则的处理下依然还是可以存活的只不过在偏离世界序列的情况下可以存活的代数自然是有限的这也能说明能存活下来的 Element 前辈掌握的世界序列是有一定的正确性的但是下一代的 Element 是不知道前辈有哪些序列是正确的甚至前辈的 KeyList 都是偏离世界序列的只是刚好满足当前的世界规则而存活在经过了世界大循环之后可以再来看看存活下来的 Element 小人儿掌握世界序列的情况。这次的结果是绝大部分的 Element 小人儿掌握了正确的世界序列之后少部分的 Element 小人儿掌握了错误的世界序列。这些少部分的掌握错误的世界序列的 Element 小人儿都是在最后几代世界循环里面创建的。也就是说活的足够久的 Element 小人儿都是掌握了正确的世界序列的这也能映射到现实世界的一部分能够存活下来的生物或者人都是掌握了一定的世界序列也就是世界本源或者说世界的知识或者说是符合世界规则。掌握的越多或者说行为越靠近世界规则就越能存活此代码版本放在 GitHub 上可以从 https://github.com/lindexi/lindexi_gd/commit/5f7d17b206b904db424d17fed6cef48eb0965496 获取全部代码这个代码游戏到这里还没有结束可以玩的还有很多。例如修改下一代的 Element 的思考逻辑让下一代的 Element 更加有想法想要更改更多的知识。在修改之后的代码世界下一代的 Element 更加质疑前辈的知识会更多的思考世界序列而不是和之前的代码一样只是修改世界序列里面的一项修改之后的代码如下class Element
{public void BuildKey(){const int count 10;while (KeyList.Countcount){var key Random.Next(Key.MaxKeyValue);KeyList.Add(new Key(key));}var updateCount Random.Next(1, count);for (int i 0; i updateCount; i){KeyList[Random.Next(count)] new Key(Random.Next(Key.MaxKeyValue));}}... // 忽略其他代码
}运行一下代码可以看到此时运行的情况是在很多代的世界大循环里面即世界代数里大量存在灭世的情况。因为下一代的 Element 小人儿思考越多代表着继承到的前辈的知识越少。继承的知识越少越难以存活。这也能说明前辈们的知识是有用的此代码版本放在 GitHub 上可以从 https://github.com/lindexi/lindexi_gd/commit/9bb128484abfa9fe6f5ba3ff66a91505fb3105b5 获取全部代码好了今天的小测试就到这里。通过这个代码故事可以告诉咱在这个代码世界里面是符合天有五贼见之者昌的道理越接近世界序列的 Element 小人儿将越能存活。这个和当前的现实世界也差不多在这个代码世界里面前辈的知识是有用的学习前辈的知识可以更好帮助存活符合书籍是人类进步的阶梯这句话的道理。通过让前辈的知识传授给下一代可以逐渐让整个世界在一代一代的循环里面存活的 Element 小人儿的数量越多在此代码世界里面前辈传授给下一代的知识也不一定是完全正确的下一代需要进行质疑因为前辈说不定活不过世界的下次迭代前辈的知识只是刚好在当前的世界规则下是正确的不代表着在下一次迭代的世界规则还是正确的。映射到现实世界那就是需要质疑前辈的知识前辈的知识放在前辈的时代是正确的不代表在当前也是正确的。但是将前辈们的知识全抛掉那自然也是不对的现实世界里面也许存在世界序列和世界规则然而现实世界里面可不会告诉大家有多少个世界序列列表世界序列的每个项的取值范围是多少世界序列有多长等。试试在代码世界里面让代码世界的世界序列的取值范围更大或者是世界序列更长试试看修改之后的灭世次数。同样现实世界不会告诉大家世界规则是什么有多少个规则。现实世界的世界序列和世界规则更加复杂这就让在现实世界进行探索世界的本质更加难。但是有一点是正确的那就是学习前辈们的知识同时进行自己的思考在一代代的努力下可以不断靠近世界的本质这个代码世界还有很多可以玩的例如可以修改更有趣的世界规则也就是 BuildByKey 方法。修改 Element 的思考方式等
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/89332.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!