个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创模拟算法(1)_替换所有的问号
收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌
目录
1. 模拟算法简介 :
1.1 定义与基本概念
1.2 模拟算法的类型
1.3 应用领域
1.4 模拟算法的优点与缺点
1.5 实现与工具
1.6 未来发展
2. 题目链接 :
3. 题目描述 :
4. 解法(模拟) :
算法思路 :
代码展示 :
结果分析 :
1. 模拟算法简介 :
模拟算法(Simulation Algorithm)是一种通过模仿真实世界系统或过程来解决问题的计算方法。模拟算法广泛应用于各种领域,包括工程、科学、经济学、交通、气象等,尤其是在难以使用解析方法获得解决方案的问题中。
1.1 定义与基本概念
模拟算法是指通过构建模型来模拟一个系统的行为和过程,从而进行分析和预测。模拟通常涉及以下几个步骤:
建模:创建一个代表实际系统的数学或计算机模型。
执行模拟:使用计算机程序或手动方式运行模型,观察系统的行为。
分析结果:收集和分析模拟输出,以获取有关系统性能或行为的信息。
1.2 模拟算法的类型
模拟算法可以分为几种类型:
离散事件模拟(Discrete Event Simulation, DES):
关注系统中事件的发生,事件在时间上是离散的。例如,排队系统、生产线等。
连续模拟(Continuous Simulation):模拟变化是连续的,通常用于描述物理过程,如流体动力学、生态系统等。
蒙特卡洛模拟(Monte Carlo Simulation):通过随机抽样来估计系统的特性和行为,常用于风险评估和决策分析。
代理基础模拟(Agent - based Simulation):模拟个体(代理)在特定环境中进行交互,研究系统的整体行为。
1.3 应用领域
模拟算法的应用领域非常广泛,包括但不限于:
工业工程:用于优化生产流程和资源配置。
交通管理:模拟交通流、交通信号控制等。
金融:用于风险评估、投资组合优化和期权定价。
环境科学:模拟生态系统变化、气候变化等。
医学:用于疾病传播模型、公共卫生政策评估等。
1.4 模拟算法的优点与缺点
优点:
灵活性:能够模拟复杂系统,适用于解析方法难以解决的问题。
可视化:模拟结果可视化,便于理解和分析系统行为。
实验能力:可以在不干扰真实系统的情况下进行虚拟实验。
缺点:
计算成本:复杂系统的模拟可能需要大量的计算资源。
准确性依赖:模型的准确性和可靠性取决于初始假设和输入数据的质量。
时间消耗:某些模拟可能需要较长的时间来执行。
1.5 实现与工具
实现模拟算法通常需要编程能力,常用的编程语言和工具包括:
编程语言:Python、R、MATLAB、Java、C++等。
专用软件:如 AnyLogic、Simul8、Arena 等。
数据分析工具:如 Tableau、Excel、R、Python 的数据分析库等。
1.6 未来发展
随着计算能力的提升和大数据技术的发展,模拟算法在实时系统分析、智能决策支持等领域的应用将越来越广泛。同时,结合人工智能和机器学习技术,模拟算法的预测能力和效率也将进一步提升。
总之,模拟算法是一种强大的工具,能够帮助我们更好地理解和优化复杂系统的行为。通过合理的建模和模拟,可以为实际决策提供有力的支持。
2. 题目链接 :
OJ链接 : 替换所有的问号
3. 题目描述 :
给你一个仅包含小写英文字母和 '?'
字符的字符串 s
,请你将所有的 '?'
转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。
注意:你 不能 修改非 '?'
字符。
题目测试用例保证 除 '?'
字符 之外,不存在连续重复的字符。
在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。
示例 1:
输入:s = "?zs" 输出:"azs" 解释:该示例共有 25 种解决方案,从 "azs" 到 "yzs" 都是符合题目要求的。只有 "z" 是无效的修改,因为字符串 "zzs" 中有连续重复的两个 'z' 。
示例 2:
输入:s = "ubv?w" 输出:"ubvaw" 解释:该示例共有 24 种解决方案,只有替换成 "v" 和 "w" 不符合题目要求。因为 "ubvvw" 和 "ubvww" 都包含连续重复的字符。
提示:
-
1 <= s.length <= 100
-
s
仅包含小写英文字母和'?'
字符
4. 解法(模拟) :
算法思路 :
纯模拟.从前往后遍历整个字符串,找到问号之后,就用a~z的每个字符去尝试替换即可.
细节问题:
我们每次判断都需要比较当前字符的前一个和后一个,但是当我们当前字符为首字符或者是最后一个字符时,我们这样判断就会访问过界,所以我们需要加上边界判断.
代码展示 :
class Solution {
public:
string modifyString(string s) {
for(int i = 0; i < s.size(); i++)
{
if(s[i] == '?')
{
char ch;
for(ch = 'a'; ch <= 'z'; ch++)
{
if((i == 0 || ch != s[i - 1]) && (i == s.size() - 1 || ch != s[i + 1]))
{
s[i] = ch;
break;
}
}
}
}
return s;
}
};
替换逻辑:
对于每个 '?',尝试用 'a' 到 'z' 中的字母进行替换。通过 for (ch = 'a'; ch <= 'z'; ch++) 遍历字母。
在循环中,首先检查字符 ch 是否与前一个字符(s[i - 1])不同,且与后一个字符(s[i + 1])不同。具体条件是:
i == 0 || ch != s[i - 1]:如果是字符串的第一个字符,或者 ch 与前一个字符不同。
i == s.size() - 1 || ch != s[i + 1]:如果是字符串的最后一个字符,或者 ch 与后一个字符不同。
如果这两个条件都满足,说明选择的字母 ch 是有效的,可以替换当前的 '?',然后用 s[i] = ch; 更新字符,并通过 break; 跳出字母循环。
结果分析 :
代码的时间复杂度分析
外层循环:遍历字符串的每个字符,复杂度为 O(n),其中 n 是字符串的长度。
内层循环:对于每个 '?',最坏情况下需要遍历 26 个字母(从 'a' 到 'z')。因此,最坏情况下,内层循环的时间复杂度是 O(26),即常数时间 O(1)。
总体时间复杂度为:O(n)。代码的空间复杂度
空间复杂度:该算法只使用了常数的额外空间来存储字符 ch,因此空间复杂度为 O(1)。