学习Rust的第22天:mini_grep第2部分

书接上文,在本文中,我们学习了如何通过将 Rust 程序的逻辑移至单独的库箱中并采用测试驱动开发 (TDD) 实践来重构 Rust 程序。通过在实现功能之前编写测试,我们确保了代码的可靠性。我们涵盖了基本的 Rust 概念,例如错误处理、环境变量和命令行参数。本文最后提出了最后一个改进:将错误消息重定向到 stderr 以提供更好的用户体验。

Recap 回顾

This is our code so far
这是我们到目前为止的代码

use std::env;
use std::fs;
use std::process;
use std::error::Error;

struct Config {
    query: String,
    file: String,
}

impl Config{
    fn new(args: &[String]) -> Result<Config, &str>{
        if args.len() < 3{
            return Err("Not enough arguments.");
        }

        let query: String = args[1].clone();
        let file: String = args[2].clone();

        Ok(Config{query,file})
    }
}

fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    println!("file contents: {}",contents);

    Ok(())
}

fn main(){
    let args: Vec<String> = env::args().collect();

    let config = Config::new(&args).unwrap_or_else(|err|{
        println!("Problem parsing arguments: {}",err);
        println!("Expected: {} search_query filename", args[0]);
        process::exit(1);
    });

    if let Err(e) = run(config) {
        println!("Application error: {}",e);
        process::exit(1);
    }
}

Explanation: 解释:

use std::env;
use std::fs;
use std::process;
use std::error::Error;

These lines import specific modules from the standard library (std).
这些行从标准库 ( std ) 导入特定模块。

  • env: Provides functions for interacting with the environment (e.g., command-line arguments).
    env :提供与环境交互的函数(例如命令行参数)。
  • fs: Offers file system operations like reading and writing files.
    fs :提供文件系统操作,例如读取和写入文件。
  • process: Provides functions for interacting with processes (e.g., exiting a process).
    process :提供与进程交互的功能(例如,退出进程)。
  • error::Error: Imports the Error trait, which is used for error handling.
    error::Error :导入 Error 特征,用于错误处理。
struct Config {
    query: String,
    file: String,
}
  • Defines a struct named Config with two fields: query and file, both of type String.
    定义一个名为 Config 的结构体,其中包含两个字段: query 和 file ,均为 String 类型。
impl Config{
    fn new(args: &[String]) -> Result<Config, &str>{
        if args.len() < 3 {
            return Err("Not enough arguments.");
        }
    let query: String = args[1].clone();
        let file: String = args[2].clone();
        Ok(Config{query, file})
    }
}

Implements methods for the Config struct.
实现 Config 结构的方法。

  • Defines a constructor method new for creating a new Config instance.
    定义一个构造函数方法 new 用于创建新的 Config 实例。
  • Takes a slice of strings (&[String]) representing command-line arguments as input.
    将表示命令行参数的字符串片段 ( &[String] ) 作为输入。
  • Returns a Result where Ok contains a Config instance if arguments are sufficient, and Err contains an error message otherwise.
    如果参数足够,则返回 Result ,其中 Ok 包含 Config 实例,否则 Err 包含错误消息。
fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    println!("file contents: {}",contents);
    Ok(())
}

Defines a function run that takes a Config instance as input.
定义一个函数 run ,它将 Config 实例作为输入。

  • Attempts to read the contents of the file specified in the Config.
    尝试读取 Config 中指定的文件的内容。
  • Prints the contents of the file.
    打印文件的内容。
  • Returns Ok(()) if successful, indicating no error.
    如果成功则返回 Ok(()) ,表示没有错误。
fn main(){
    let args: Vec<String> = env::args().collect();
    let config = Config::new(&args).unwrap_or_else(|err|{
        println!("Problem parsing arguments: {}",err);
        println!("Expected: {} search_query filename", args[0]);
        process::exit(1);
    });
    if let Err(e) = run(config) {
        println!("Application error: {}",e);
        process::exit(1);
    }
}

Defines the main function, the entry point of the program.
定义 main 函数,程序的入口点。

  • Retrieves command-line arguments and collects them into a vector of strings.
    检索命令行参数并将它们收集到字符串向量中。
  • Attempts to create a Config instance from the command-line arguments.
    尝试从命令行参数创建 Config 实例。
  • If successful, continues with the program execution.
    如果成功,则继续执行程序。
  • If unsuccessful, prints an error message and exits the program.
    如果不成功,则打印错误消息并退出程序。
  • Calls the run function with the Config instance.
    使用 Config 实例调用 run 函数。
  • Handles any errors that occur during the execution of run by printing an error message and exiting the program.
    通过打印错误消息并退出程序来处理 run 执行期间发生的任何错误。
let config = Config::new(&args).unwrap_or_else(|err|{
        println!("Problem parsing arguments: {}",err);
        println!("Expected: {} search_query filename", args[0]);
        process::exit(1);
    });
  • This is a closure, an error-handling mechanism used when creating a Config instance from command-line arguments. It prints error details and expected usage if parsing fails, then exits the program with an error code. We will study about closures in detail in the upcoming articles
    这是一个闭包,是从命令行参数创建 Config 实例时使用的错误处理机制。如果解析失败,它会打印错误详细信息和预期用法,然后使用错误代码退出程序。我们将在接下来的文章中详细研究闭包

Extracting logic to a library crate
将逻辑提取到库箱中

Our main.rs file is kind of bloated at the moment and all oof our logic is stored in one place, to tackle this situation we can create a library crate and store all the logic there and our main.rs file can call the library crate for logic.
我们的 main.rs 文件目前有点臃肿,我们所有的逻辑都存储在一个地方,为了解决这种情况,我们可以创建一个库板条箱并将所有逻辑存储在那里,我们的 main.rs
First things first, create a lib.rs file in the src directory, this is where we will store all our logic…
首先,在 src 目录中创建一个 lib.rs 文件,这是我们存储所有逻辑的地方......

$ touch src/lib.rs
├── Cargo.lock
├── Cargo.toml
├── lorem.txt
├── src
│   ├── lib.rs
│   └── main.rs
└── target
    ├── CACHEDIR.TAG
    └── debug

We will move our run() function and the Config struct and implementation to the lib.rs file with the relevant use statements
我们将把 run() 函数以及 Config 结构和实现移至 lib.rs 文件,并包含相关的 use 语句

// lib.rs

use std::fs;
use std::error::Error;

pub struct Config {
    pub query: String,
    pub file: String,
}

impl Config{
    pub fn new(args: &[String]) -> Result<Config, &str>{
        if args.len() < 3{
            return Err("Not enough arguments.");
        }

        let query: String = args[1].clone();
        let file: String = args[2].clone();

        Ok(Config{query,file})
    }
}

pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    println!("file contents: {}",contents);

    Ok(())
}

Remember, everything in rust is private by default, that is where we can use the pub keyword to make it public
请记住,默认情况下,rust 中的所有内容都是私有的,这就是我们可以使用 pub 关键字将其公开的地方

Then we can import the Config struct from the library crate and call the run function from there as well in the main.rs file.
然后我们可以从库箱中导入 Config 结构,并在 main.rs 文件中调用 run 函数。

use std::env;
use std::process;

use minigrep::Config;

fn main(){
    let args: Vec<String> = env::args().collect();

    let config = Config::new(&args).unwrap_or_else(|err|{
        println!("Problem parsing arguments: {}",err);
        println!("Expected: {} search_query filename", args[0]);
        process::exit(1);
    });

    if let Err(e) = minigrep::run(config) {
        println!("Application error: {}",e);
        process::exit(1);
    }
}

Now seems like a good time for us to dive into Test-driven development, this is an important concept when it comes to programming. It involves
现在似乎是我们深入研究测试驱动开发的好时机,这是编程时的一个重要概念。它涉及

  • Writing a test that fails
    编写失败的测试
  • Writing code to make it pass
    编写代码使其通过
  • Refactoring the code to make it readable
    重构代码以使其可读
  • REPEAT 重复

So let’s write a failing test
那么让我们编写一个失败的测试

#[cfg(test)]
mod tests{
  #[test]
  fn single_result_test(){
    let query = "dolor";
    let contents = "Lorem
ipsum
dolor
sit
amet";
    assert_eq!(vec!["dolor"], search(query,contents));
  }
}

We have not yet created the search function, and running the test command now will result in a compilation error because of that…
我们还没有创建搜索功能,现在运行测试命令将导致编译错误,因为......

So let’s create a search function
那么让我们创建一个搜索功能

pub fn search(query: &str, contents: &str) -> Vec<&str> {
  let mut results = Vec::new();
  for line in contents.lines(){
    if line.contains(query){
      results.push(line);
    }
  }
  results
}

As of now this function will give us an error to work with because out Vector is going to be tied to either query or contents and we haven’t specified the lifetime for it yet, so let’s do that
到目前为止,这个函数会给我们带来一个错误,因为 out Vector 将绑定到 query 或 contents 并且我们还没有指定它的生命周期,所以让我们这样做吧

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
  let mut results = Vec::new();
  for line in contents.lines(){
    if line.contains(query){
      results.push(line);
    }
  }
  results
}

Running the test now, will pass
现在运行测试,将通过

running 1 test
test tests::one_result ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/main.rs (target/debug/deps/minigrep-35c886545281e89c)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests minigrep

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Now that the search function works, lets use that in our run function
现在搜索功能可以工作了,让我们在运行功能中使用它

pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    let result = search(&config.query, &contents);

    for lines in result {
        println!("{}",lines);
    }

    Ok(())
}

Running this program we get
运行这个程序我们得到

cargo run dolor lorem.txt

dolor

It works, but there is one major problem here
它可以工作,但是这里有一个主要问题
Our search logic is case sensitive, Let’s fix it
我们的搜索逻辑区分大小写,让我们修复它

Continuing TDD, let’s make a failing test and then work our way up
继续 TDD,让我们进行一次失败的测试,然后继续努力

#[test]
fn case_insensitive(){
  let query = "DoLoR";
  let contents = "Lorem
ipsum
dolor
sit
amet
DOLOR
DolOR
doLOR";
  assert_eq!(vec!["dolor","DOLOR","DolOR","doLOR"], search_case_insensitive(query,contents));
    }

This test will fail, because we don’t have the search_case_insensitive function as of now
这个测试将会失败,因为我们现在还没有 search_case_insensitive 函数

We will use most of the logic of the previous function here, and modify a few things
我们将在这里使用上一个函数的大部分逻辑,并修改一些内容

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str>{
    let mut results = Vec::new();
    let query = query.to_lowercase();
    for line in contents.lines(){
        if line.to_lowercase().contains(&query){
    results
}

The difference in logic is as follows:
逻辑上的区别如下:

search_case_insensitive: 搜索不区分大小写:

  • This function converts both the query and each line of the content to lowercase using the to_lowercase() method. This ensures that the comparison is case insensitive.
    此函数使用 to_lowercase() 方法将查询和每一行内容转换为小写。这确保了比较不区分大小写。
  • After converting the query and the line to lowercase, it checks if the lowercase version of the line contains the lowercase version of the query.
    将查询和行转换为小写后,它检查该行的小写版本是否包含查询的小写版本。
  • If a match is found, it doesn’t actually push the original line into the results vector. Instead, it returns an empty results vector, thus indicating that it didn’t store the original lines matching the case-insensitive query. There’s a missing line to push the matched line into results.
    如果找到匹配项,它实际上不会将原始行推入结果向量中。相反,它返回一个空结果向量,从而表明它没有存储与不区分大小写的查询匹配的原始行。缺少一行将匹配行推入 results 。

search: 搜索:

  • This function searches for the query within each line of the content without altering the case.
    此函数在内容的每一行中搜索查询,而不改变大小写。
  • It iterates over each line of the content, and for each line, it checks if the line contains the query.
    它迭代内容的每一行,并针对每一行检查该行是否包含查询。
  • If a match is found, it pushes the original line (in its original case) into the results vector.
    如果找到匹配项,它将原始行(在其原始情况下)推送到结果向量中。
  • It doesn’t perform any case conversion, so the search is case sensitive by default.
    它不执行任何大小写转换,因此默认情况下搜索区分大小写。

Environment variables 环境变量

Now that we have two search functions, our run function needs to know which function to call, but to do that we will add a boolean to the Config struct named case_sensitive
现在我们有两个搜索函数,我们的 run 函数需要知道要调用哪个函数,但为此,我们将向名为 case_sensitive

pub struct Config{
  pub query: String,
  pub file: String,
  pub case_sensitive: bool,
}

Then we will modify our run function to use the case_sensitive field…
然后我们将修改 run 函数以使用 case_sensitive 字段...

pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    let result = if config.case_sensitive{
        search(&config.query, &contents);
    }else {
        search_case_insensitive(&config.query, &contents);
    }
    for lines in result {
        println!("{}",lines);
    }
    Ok(())
}

Now we modify the new function to use environment variables for case_sensitivity
现在我们修改新函数以使用 case_sensitivity 的环境变量

We need to have the env module in scope to use this functionality
我们需要在范围内包含 env 模块才能使用此功能

use std::env;
impl Config{
    pub fn new(args: &[String]) -> Result<Config, &str>{
        if args.len() < 3{
            return Err("Not enough arguments.");
        }
        let query: String = args[1].clone();
        let file: String = args[2].clone();
        let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
        Ok(Config{query,file,case_sensitive})
    }
}

Now for the final step we need to display our errors to stderr instead of stdout
现在,最后一步我们需要将错误显示到 stderr 而不是 stdout
All out error handling is in the main.rs file so let’s get to it. This step is really easy, We just need to change out println! for eprintln!this redirects the output to stderr. This is useful when a user wants to send the output stream to a file, they can still see the errors on their terminal screen.
所有错误处理都在 main.rs 文件中,所以让我们开始吧。这一步非常简单,我们只需要将 println! 更改为 eprintln! 这会将输出重定向到 stderr. 这在用户想要发送输出时很有用流到文件,他们仍然可以在终端屏幕上看到错误。

Congratulations on creating your very first useful Rust program
恭喜您创建了第一个有用的 Rust 程序

Directory structure : 目录结构:

├── Cargo.lock
├── Cargo.toml
├── lorem.txt
├── src
│   ├── lib.rs
│   └── main.rs
└── target
    ├── CACHEDIR.TAG
    └── debug

Code: 代码:

lib.rs 库文件

use std::fs;
use std::error::Error;
use std::env;

pub struct Config {
    pub query: String,
    pub file: String,
    pub case_sensitive: bool,
}

impl Config{
    pub fn new(args: &[String]) -> Result<Config, &str>{
        if args.len() < 3{
            return Err("Not enough arguments.");
        }

        let query: String = args[1].clone();
        let file: String = args[2].clone();
        let case_sensitive = env::var("CASE_INSENSITIVE").is_err();

        Ok(Config{query,file,case_sensitive})
    }
}

pub fn run(config: Config) -> Result<(), Box<dyn Error>>{
    let contents = fs::read_to_string(config.file)?;
    let result = if config.case_sensitive{
        search(&config.query, &contents)
    }else {
        search_case_insensitive(&config.query, &contents)
    };

    for lines in result {
        println!("{}",lines);
    }

    Ok(())
}

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str>{
    let mut results = Vec::new();
    for line in contents.lines() {
        if line.contains(query){
            results.push(line);
        }
    }
    results
}

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str>{
    let mut results = Vec::new();
    let query = query.to_lowercase();
    for line in contents.lines(){
        if line.to_lowercase().contains(&query){
            results.push(line);
        }
    }
    results
}

#[cfg(test)]
mod tests{
    use super::*;

    #[test]
    fn case_sensitive(){
        let query = "dolor";
        let contents = "Lorem
ipsum
dolor
DoloR
sit
amet";
        assert_eq!(vec!["dolor"], search(query,contents));
    }

    #[test]
    fn case_insensitive(){
        let query = "DoLoR";
        let contents = "Lorem
ipsum
dolor
sit
amet
DOLOR
DolOR
doLOR";
        assert_eq!(vec!["dolor","DOLOR","DolOR","doLOR"], search_case_insensitive(query,contents));
    }
}

main.rs 主程序.rs

use std::env;
use std::process;

use minigrep::Config;

fn main(){
    let args: Vec<String> = env::args().collect();

    let config = Config::new(&args).unwrap_or_else(|err|{
        eprintln!("Problem parsing arguments: {}",err);
        eprintln!("Expected: {} search_query filename", args[0]);
        process::exit(1);
    });

    if let Err(e) = minigrep::run(config) {
        eprintln!("Application error: {}",e);
        process::exit(1);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/590309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【linux-汇编-点灯之思路-程序】

目录 1. ARM汇编中的一些注意事项2. IMXULL汇编点灯的前序&#xff1a;3. IMXULL汇编点灯之确定引脚&#xff1a;4. IMXULL汇编点灯之引脚功能编写&#xff1a;4.1 第一步&#xff0c;开时钟4.2 第二步&#xff0c;定功能&#xff08;MUX&#xff09;4.3 第三步&#xff0c;定电…

【笔试训练】day17

1.小乐乐该数字 遇到按位处理的情况可以考虑用字符串去读 代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include<string> using namespace std;int main() {string str;cin >> str;int ans 0;for (int i 0; i < str.siz…

JavaEE 初阶篇-深入了解 Junit 单元测试框架和 Java 中的反射机制(使用反射做一个简易版框架)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Junit 单元测试框架概述 1.1 使用 Junit 框架进行测试业务代码 1.2 Junit 单元测试框架的常用注解&#xff08;Junit 4.xxx 版本&#xff09; 2.0 反射概述 2.1 获…

神经网络中的优化方法

一、引入 在传统的梯度下降优化算法中&#xff0c;如果碰到平缓区域&#xff0c;梯度值较小&#xff0c;参数优化变慢 &#xff0c;遇到鞍点&#xff08;是指在某些方向上梯度为零而在其他方向上梯度非零的点。&#xff09;&#xff0c;梯度为 0&#xff0c;参数无法优化&…

机器人系统ros2-开发实践04-ROS2 中 tf2的定义及示例说明

1. what ros2 tf2 &#xff1f; tf2的全称是transform2&#xff0c;在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;它是专门用于处理和变换不同坐标系间位置和方向的库。这个名字来源于“transform”这个词&#xff0c;表示坐标变换&#xff0c;而“2”则…

【Leetcode每日一题】 动态规划 - 简单多状态 dp 问题 - 删除并获得点数(难度⭐⭐)(70)

1. 题目解析 题目链接&#xff1a;740. 删除并获得点数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 问题分析 本题是「打家劫舍」问题的变种&#xff0c;但核心逻辑依然保持一致。题目要求从给定的数组nums中选择…

C++ stack和queue的使用方法与模拟实现

文章目录 一、 stack的使用方法二、 queue的使用方法三、 容器适配器四、 stack的模拟实现五、 queue的模拟实现 一、 stack的使用方法 stack介绍文档 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的…

Windows如何通过wsl2迅速启动Docker desktop的PHP的Hyperf项目容器?

一、安装WSL 什么是WSL&#xff1f; 官网&#xff1a;什么是WSL&#xff1f; Windows Subsystem for Linux (WSL) 是一个在Windows 10和Windows 11上运行原生Linux二进制可执行文件的兼容性层。 换句话说&#xff0c;WSL让你可以在Windows系统上运行Linux环境&#xff0c;而无需…

【linux】unzip解压乱码或者报错处理办法

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

2023-2024年数字化转型报告/方案合集(精选198份)

数字化转型报告/方案&#xff08;精选198份&#xff09; 2023-2024年 来源&#xff1a;2023-2024年数字化转型报告/方案合集&#xff08;精选198份&#xff09; 【以下是资料目录】 2023-2024年度医药健康行业数字化调研报告 2023-2024中国财务数字化报告 2023⻝品饮料行业…

Redis运维篇-快速面试笔记(速成版)

文章目录 1. Redis的持久化1.1 RDB&#xff08;快照模式&#xff09;1.2 AOF 模式 2. Redis主从模型&#xff08;高可用&#xff09;2.1 Redis的主从复制2.2 Redis拓扑结构 3. Redis集群模式&#xff08;高并发&#xff09;3.1 Redis的Slots3.2 集群模式的常用命令3.3 多主多从…

使用 MediaMTX 和 FFmpeg 推拉 RTSP 流媒体

实时流传输协议 RTSP&#xff08;Real-Time Streaming Protocol&#xff09;是 TCP/IP 协议体系中的一个应用层协议&#xff0c;由哥伦比亚大学、网景和 RealNetworks 公司提交的 IETF RFC 标准。该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP 在体系…

Unity射击游戏开发教程:(8)构建 UI 元素:添加分数显示

用户界面决定用户如何与屏幕交互。UI 适用于所有类型的游戏和应用程序,在此示例中,我们将为我的太空射击游戏设置一个简单的记分板。 第一步是在层次结构中创建一个 UI 元素。只需在层次结构中右键单击,滚动 UI 并选择要添加的 UI 元素类型。在本例中,我们将使用文本元素。…

STM32入门_江协科技_3~4_OB记录的自学笔记_软件安装新建工程

3. 软件安装 3.1. 安装Keil5 MDK 作者的资料下载的连接如下&#xff1a;https://jiangxiekeji.com/download.html#32 3.2. 安装器件支持包 因为新的芯片层出不穷&#xff0c;所以需要安装Keil5提供的器件升级版对软件进行升级&#xff0c;从而支持新的芯片&#xff1b;如果不…

如何将 redis 快速部署为 docker 容器?

部署 Redis 作为 Docker 容器是一种快速、灵活且可重复使用的方式&#xff0c;特别适合开发、测试和部署环境。本文将详细介绍如何将 Redis 部署为 Docker 容器&#xff0c;包括 Docker 安装、Redis 容器配置、数据持久化、网络设置等方面。 步骤 1&#xff1a;安装 Docker 首…

ICode国际青少年编程竞赛- Python-1级训练场-基本操作

ICode国际青少年编程竞赛- Python-1级训练场-基本操作 1、 Dev.step(3)2、 Dev.step(1)3、 Dev.step(7)4、 Dev.step(-1)5、 Dev.step(-5)6、 Dev.step(3) Dev.step(-8)7、 Dev.turnRight() Dev.step(1)8、 Dev.turnLeft() Dev.step(1)9、 Dev.step(4) Dev.tur…

串的模式匹配之BF算法实现

概述 BF算法-暴力枚举 匹配失败处理 匹配成功结束 算法思想 代码实现 定义串的存储结构&#xff1a;装字符的ch数组标记长度的length 最坏时间复杂度分析 代码整合

微调Mistral 7B以实现命名实体识别 (NER)

文章来源&#xff1a;fine-tuning-mistral-7b-for-named-entity-recognition-ner 2024 年 4 月 19 日 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;命名实体识别&#xff08;NER&#xff09;被认为是一项关键任务&#xff0c;应用范围广泛&#xff0c;包括信息…

电脑找不到msvcp140.dll如何修复?msvcp140.dll丢失的多种解决方法分享

在日常电脑操作过程中&#xff0c;用户可能会遇到一个令人困扰的问题&#xff0c;即屏幕上突然弹出一条错误提示&#xff1a;“由于找不到msvcp140.dll&#xff0c;无法继续执行代码”。这一情况往往导致应用程序无法正常启动或运行&#xff0c;给工作和娱乐带来不便。不过&…

ICode国际青少年编程竞赛- Python-1级训练场-for循环入门

ICode国际青少年编程竞赛- Python-1级训练场-for循环入门 1、 for i in range(4):Dev.step(4)Dev.turnLeft()2、 for i in range(3):Dev.step(6)Dev.turnRight()3、 for i in range(3):Dev.turnRight()Dev.step(2)Dev.turnLeft()Dev.step(-3)4、 for i in range(4):Dev…