当前位置: 首页 > news >正文

Rust 练习册 :Pig Latin与语言游戏

Pig Latin(猪拉丁语)是一种英语语言游戏,通过改变单词的拼写来创造一种"秘密语言"。它在英语国家非常流行,尤其在儿童中。在 Exercism 的 “pig-latin” 练习中,我们需要实现一个函数来将英语文本转换为 Pig Latin。这不仅能帮助我们掌握字符串处理和模式匹配技巧,还能深入学习Rust中的字符处理、词汇分析和文本转换算法。

什么是 Pig Latin?

Pig Latin 是一种英语语言游戏,规则如下:

  1. 以元音开头的单词:在单词末尾加上 “ay”

    • apple → appleay
    • egg → eggay
  2. 以辅音开头的单词:将开头的辅音(或辅音群)移到单词末尾,然后加上 “ay”

    • pig → igpay
    • school → oolschay
  3. 以 “qu” 开头或包含 “qu” 的单词:将 “qu” 视为一个整体处理

    • queen → eenquay
    • square → aresquay
  4. 特殊情况

    • 以 “xr” 或 “yt” 开头的单词被视为以元音开头
    • 当 “y” 跟在辅音后面时,被视为元音

让我们先看看练习提供的函数签名:

pub fn translate(input: &str) -> String {unimplemented!("Using the Pig Latin text transformation rules, convert the given input '{}'",input);
}

我们需要实现 translate 函数,将输入的英语文本转换为 Pig Latin。

设计分析

1. 核心要求

  1. 元音识别:正确识别英语中的元音字母(a, e, i, o, u)
  2. 辅音群处理:处理连续的辅音字母
  3. 特殊规则:处理 “qu”, “xr”, “yt” 等特殊情况
  4. 短语处理:处理包含多个单词的短语

2. 技术要点

  1. 字符处理:高效处理字符串中的字符和子串
  2. 模式匹配:使用模式匹配处理不同的转换规则
  3. 文本分割:正确分割单词和处理空格
  4. 边界情况:处理各种边界情况和特殊规则

完整实现

1. 基础实现

pub fn translate(input: &str) -> String {// 分割单词并转换每个单词input.split_whitespace().map(translate_word).collect::<Vec<String>>().join(" ")
}fn translate_word(word: &str) -> String {// 处理空单词if word.is_empty() {return String::new();}// 检查是否以元音开头(包括特殊规则)if starts_with_vowel_sound(word) {format!("{}ay", word)} else {// 找到辅音群的结束位置let consonant_cluster_end = find_consonant_cluster_end(word);let consonant_cluster = &word[..consonant_cluster_end];let rest = &word[consonant_cluster_end..];format!("{}{}ay", rest, consonant_cluster)}
}fn starts_with_vowel_sound(word: &str) -> bool {let chars: Vec<char> = word.chars().collect();// 检查第一个字母是否为元音if chars.is_empty() {return false;}match chars[0] {'a' | 'e' | 'i' | 'o' | 'u' => true,'x' | 'y' => {// 特殊情况:xr 和 yr 被视为元音开头if chars.len() > 1 {chars[1] == 'r'} else {false}}_ => false,}
}fn find_consonant_cluster_end(word: &str) -> usize {let chars: Vec<char> = word.chars().collect();let mut i = 0;while i < chars.len() {match chars[i] {'a' | 'e' | 'i' | 'o' | 'u' => {// 特殊情况:如果辅音后跟着qu,需要一起移动if i > 0 && chars[i] == 'u' && i > 0 && chars[i-1] == 'q' {// 继续,因为qu应该被视为一个整体i += 1;continue;}break;}'y' => {// y在辅音后被视为元音if i > 0 {break;}i += 1;}_ => i += 1,}}// 计算字符边界位置word.char_indices().nth(i).map(|(pos, _)| pos).unwrap_or(word.len())
}fn char_to_byte_index(word: &str, char_index: usize) -> usize {word.char_indices().nth(char_index).map(|(pos, _)| pos).unwrap_or(word.len())
}

2. 优化实现

pub fn translate(input: &str) -> String {input.split_whitespace().map(translate_word).collect::<Vec<String>>().join(" ")
}fn translate_word(word: &str) -> String {if word.is_empty() {return String::new();}let consonant_cluster_end = find_consonant_cluster_end(word);if consonant_cluster_end == 0 {// 以元音开头format!("{}ay", word)} else {// 以辅音开头let (consonant_cluster, rest) = word.split_at(consonant_cluster_end);format!("{}{}ay", rest, consonant_cluster)}
}fn find_consonant_cluster_end(word: &str) -> usize {let chars: Vec<char> = word.chars().collect();let mut i = 0;// 特殊规则:以xr或yt开头的单词被视为以元音开头if chars.len() >= 2 && ((chars[0] == 'x' && chars[1] == 'r') || (chars[0] == 'y' && chars[1] == 't')) {return 0;}while i < chars.len() {match chars[i] {'a' | 'e' | 'i' | 'o' | 'u' => {break;}'y' => {// y在不是第一个字母时被视为元音if i > 0 {break;}i += 1;}'q' => {// 特殊处理qu组合if i + 1 < chars.len() && chars[i + 1] == 'u' {i += 2; // 跳过qubreak;}i += 1;}_ => i += 1,}}// 转换字符索引为字节索引word.char_indices().nth(i).map(|(pos, _)| pos).unwrap_or(word.len())
}

3. 函数式实现

pub fn translate(input: &str) -> String {input.split_whitespace().map(|word| {let chars: Vec<char> = word.chars().collect();if chars.is_empty() {return String::new();}// 特殊规则:以xr或yt开头if chars.len() >= 2 && ((chars[0] == 'x' && chars[1] == 'r') || (chars[0] == 'y' && chars[1] == 't')) {return format!("{}ay", word);}// 查找元音位置let vowel_index = chars.iter().enumerate().find(|(i, &c)| {match c {'a' | 'e' | 'i' | 'o' | 'u' => true,'y' => *i > 0, // y在非首位时为元音'q' => {// 特殊处理quif *i + 1 < chars.len() && chars[*i + 1] == 'u' {true} else {false}}_ => false,}}).map(|(index, c)| {if c == 'q' && index + 1 < chars.len() && chars[index + 1] == 'u' {index + 2 // 跳过qu} else {index}}).unwrap_or(chars.len());if vowel_index == 0 {format!("{}ay", word)} else {let (consonant_cluster, rest) = word.split_at(word.char_indices().nth(vowel_index).map(|(pos, _)| pos).unwrap_or(word.len()));format!("{}{}ay", rest, consonant_cluster)}}).collect::<Vec<String>>().join(" ")
}

测试用例分析

通过查看测试用例,我们可以更好地理解需求:

#[test]
fn test_word_beginning_with_a() {assert_eq!(pl::translate("apple"), "appleay");
}

以元音"a"开头的单词在末尾加上"ay"。

#[test]
fn test_word_beginning_with_e() {assert_eq!(pl::translate("ear"), "earay");
}

以元音"e"开头的单词在末尾加上"ay"。

#[test]
fn test_word_beginning_with_i() {assert_eq!(pl::translate("igloo"), "iglooay");
}

以元音"i"开头的单词在末尾加上"ay"。

#[test]
fn test_word_beginning_with_o() {assert_eq!(pl::translate("object"), "objectay");
}

以元音"o"开头的单词在末尾加上"ay"。

#[test]
fn test_word_beginning_with_u() {assert_eq!(pl::translate("under"), "underay");
}

以元音"u"开头的单词在末尾加上"ay"。

#[test]
fn test_word_beginning_with_a_vowel_and_followed_by_a_qu() {assert_eq!(pl::translate("equal"), "equalay");
}

以元音开头的单词即使包含"qu"也按元音规则处理。

#[test]
fn test_word_beginning_with_p() {assert_eq!(pl::translate("pig"), "igpay");
}

以辅音开头的单词将辅音移到末尾并加上"ay"。

#[test]
fn test_word_beginning_with_k() {assert_eq!(pl::translate("koala"), "oalakay");
}

以辅音"k"开头的单词将辅音移到末尾并加上"ay"。

#[test]
fn test_word_beginning_with_y() {assert_eq!(pl::translate("yellow"), "ellowyay");
}

以"y"开头的单词将"y"视为辅音处理。

#[test]
fn test_word_beginning_with_x() {assert_eq!(pl::translate("xenon"), "enonxay");
}

以"x"开头的单词将"x"视为辅音处理。

#[test]
fn test_word_beginning_with_q_without_a_following_u() {assert_eq!(pl::translate("qat"), "atqay");
}

"q"后不跟"u"时,单独作为辅音处理。

#[test]
fn test_word_beginning_with_ch() {assert_eq!(pl::translate("chair"), "airchay");
}

以辅音群"ch"开头的单词将整个辅音群移到末尾。

#[test]
fn test_word_beginning_with_qu() {assert_eq!(pl::translate("queen"), "eenquay");
}

以"qu"开头的单词将"qu"作为一个整体移到末尾。

#[test]
fn test_word_beginning_with_qu_and_a_preceding_consonant() {assert_eq!(pl::translate("square"), "aresquay");
}

辅音后跟"qu"的单词将辅音和"qu"一起移到末尾。

#[test]
fn test_word_beginning_with_th() {assert_eq!(pl::translate("therapy"), "erapythay");
}

以辅音群"th"开头的单词将整个辅音群移到末尾。

#[test]
fn test_word_beginning_with_thr() {assert_eq!(pl::translate("thrush"), "ushthray");
}

以辅音群"thr"开头的单词将整个辅音群移到末尾。

#[test]
fn test_word_beginning_with_sch() {assert_eq!(pl::translate("school"), "oolschay");
}

以辅音群"sch"开头的单词将整个辅音群移到末尾。

#[test]
fn test_word_beginning_with_yt() {assert_eq!(pl::translate("yttria"), "yttriaay");
}

以"yt"开头的单词被视为以元音开头。

#[test]
fn test_word_beginning_with_xr() {assert_eq!(pl::translate("xray"), "xrayay");
}

以"xr"开头的单词被视为以元音开头。

#[test]
fn test_y_is_treated_like_a_vowel_at_the_end_of_a_consonant_cluster() {assert_eq!(pl::translate("rhythm"), "ythmrhay");
}

当"y"跟在辅音后面时,被视为元音。

#[test]
fn test_a_whole_phrase() {assert_eq!(pl::translate("quick fast run"), "ickquay astfay unray");
}

短语中的每个单词都应单独转换。

性能优化版本

考虑性能的优化实现:

pub fn translate(input: &str) -> String {// 预分配结果字符串以避免多次重新分配let mut result = String::with_capacity(input.len() + input.len() / 4);let mut first_word = true;for word in input.split_whitespace() {if !first_word {result.push(' ');} else {first_word = false;}translate_word_in_place(word, &mut result);}result
}fn translate_word_in_place(word: &str, result: &mut String) {if word.is_empty() {return;}let consonant_cluster_end = find_consonant_cluster_end_optimized(word);if consonant_cluster_end == 0 {// 以元音开头result.push_str(word);result.push_str("ay");} else {// 以辅音开头let consonant_cluster = &word[..consonant_cluster_end];let rest = &word[consonant_cluster_end..];result.push_str(rest);result.push_str(consonant_cluster);result.push_str("ay");}
}fn find_consonant_cluster_end_optimized(word: &str) -> usize {let bytes = word.as_bytes();let mut i = 0;// 特殊规则:以xr或yt开头if bytes.len() >= 2 && ((bytes[0] == b'x' && bytes[1] == b'r') || (bytes[0] == b'y' && bytes[1] == b't')) {return 0;}while i < bytes.len() {match bytes[i] {b'a' | b'e' | b'i' | b'o' | b'u' => {break;}b'y' => {// y在不是第一个字母时被视为元音if i > 0 {break;}i += 1;}b'q' => {// 特殊处理qu组合if i + 1 < bytes.len() && bytes[i + 1] == b'u' {i += 2; // 跳过qubreak;}i += 1;}_ => i += 1,}}i
}// 使用查找表的版本
static VOWELS: [bool; 256] = {let mut array = [false; 256];array[b'a' as usize] = true;array[b'e' as usize] = true;array[b'i' as usize] = true;array[b'o' as usize] = true;array[b'u' as usize] = true;array
};fn find_consonant_cluster_end_lookup(word: &str) -> usize {let bytes = word.as_bytes();let mut i = 0;// 特殊规则:以xr或yt开头if bytes.len() >= 2 && ((bytes[0] == b'x' && bytes[1] == b'r') || (bytes[0] == b'y' && bytes[1] == b't')) {return 0;}while i < bytes.len() {let byte = bytes[i];if VOWELS[byte as usize] {break;}match byte {b'y' => {// y在不是第一个字母时被视为元音if i > 0 {break;}i += 1;}b'q' => {// 特殊处理qu组合if i + 1 < bytes.len() && bytes[i + 1] == b'u' {i += 2; // 跳过qubreak;}i += 1;}_ => i += 1,}}i
}

错误处理和边界情况

考虑更多边界情况的实现:

pub fn translate(input: &str) -> String {// 处理空输入if input.is_empty() {return String::new();}input.split_whitespace().map(translate_word_safe).collect::<Vec<String>>().join(" ")
}fn translate_word_safe(word: &str) -> String {// 处理空单词if word.is_empty() {return String::new();}// 处理只包含标点符号的单词if !word.chars().any(|c| c.is_alphabetic()) {return word.to_string();}// 分离单词和后缀标点符号let (clean_word, punctuation) = split_word_and_punctuation(word);if clean_word.is_empty() {return word.to_string();}let translated = translate_clean_word(&clean_word);format!("{}{}", translated, punctuation)
}fn split_word_and_punctuation(word: &str) -> (String, String) {let chars: Vec<char> = word.chars().collect();let mut split_index = chars.len();// 从后向前查找第一个字母for (i, &c) in chars.iter().enumerate().rev() {if c.is_alphabetic() {split_index = i + 1;break;}}let clean_word: String = chars[..split_index].iter().collect();let punctuation: String = chars[split_index..].iter().collect();(clean_word, punctuation)
}fn translate_clean_word(word: &str) -> String {let consonant_cluster_end = find_consonant_cluster_end(word);if consonant_cluster_end == 0 {format!("{}ay", word)} else {let (consonant_cluster, rest) = word.split_at(consonant_cluster_end);format!("{}{}ay", rest, consonant_cluster)}
}fn find_consonant_cluster_end(word: &str) -> usize {let chars: Vec<char> = word.chars().collect();// 特殊规则:以xr或yt开头if chars.len() >= 2 && ((chars[0] == 'x' && chars[1] == 'r') || (chars[0] == 'y' && chars[1] == 't')) {return 0;}let mut i = 0;while i < chars.len() {match chars[i] {'a' | 'e' | 'i' | 'o' | 'u' => {break;}'y' => {// y在不是第一个字母时被视为元音if i > 0 {break;}i += 1;}'q' => {// 特殊处理qu组合if i + 1 < chars.len() && chars[i + 1] == 'u' {i += 2; // 跳过qubreak;}i += 1;}_ => i += 1,}}// 转换字符索引为字节索引word.char_indices().nth(i).map(|(pos, _)| pos).unwrap_or(word.len())
}// 返回Result的版本
#[derive(Debug, PartialEq)]
pub enum TranslationError {EmptyInput,InvalidCharacter,
}impl std::fmt::Display for TranslationError {fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {match self {TranslationError::EmptyInput => write!(f, "输入为空"),TranslationError::InvalidCharacter => write!(f, "输入包含无效字符"),}}
}impl std::error::Error for TranslationError {}pub fn translate_safe(input: &str) -> Result<String, TranslationError> {// 处理空输入if input.is_empty() {return Err(TranslationError::EmptyInput);}// 检查是否包含非ASCII字符(简化检查)if !input.is_ascii() {// 这里可以添加更复杂的检查}Ok(translate(input))
}

扩展功能

基于基础实现,我们可以添加更多功能:

pub struct PigLatinTranslator {preserve_case: bool,preserve_punctuation: bool,
}impl PigLatinTranslator {pub fn new() -> Self {PigLatinTranslator {preserve_case: true,preserve_punctuation: true,}}pub fn with_case_preservation(mut self, preserve: bool) -> Self {self.preserve_case = preserve;self}pub fn with_punctuation_preservation(mut self, preserve: bool) -> Self {self.preserve_punctuation = preserve;self}pub fn translate(&self, input: &str) -> String {if input.is_empty() {return String::new();}input.split_whitespace().map(|word| self.translate_word(word)).collect::<Vec<String>>().join(" ")}fn translate_word(&self, word: &str) -> String {if word.is_empty() {return String::new();}if self.preserve_punctuation {self.translate_word_with_punctuation(word)} else {self.translate_clean_word(word)}}fn translate_word_with_punctuation(&self, word: &str) -> String {// 分离单词和标点符号let (clean_word, punctuation) = self.split_word_and_punctuation(word);if clean_word.is_empty() {return word.to_string();}let translated = self.translate_clean_word(&clean_word);format!("{}{}", translated, punctuation)}fn split_word_and_punctuation(&self, word: &str) -> (String, String) {let chars: Vec<char> = word.chars().collect();let mut split_index = chars.len();// 从后向前查找第一个字母for (i, &c) in chars.iter().enumerate().rev() {if c.is_alphabetic() {split_index = i + 1;break;}}let clean_word: String = chars[..split_index].iter().collect();let punctuation: String = chars[split_index..].iter().collect();(clean_word, punctuation)}fn translate_clean_word(&self, word: &str) -> String {let consonant_cluster_end = self.find_consonant_cluster_end(word);if consonant_cluster_end == 0 {format!("{}ay", word)} else {let (consonant_cluster, rest) = word.split_at(consonant_cluster_end);format!("{}{}ay", rest, consonant_cluster)}}fn find_consonant_cluster_end(&self, word: &str) -> usize {let chars: Vec<char> = word.chars().collect();// 特殊规则:以xr或yt开头if chars.len() >= 2 && ((chars[0] == 'x' && chars[1] == 'r') || (chars[0] == 'y' && chars[1] == 't')) {return 0;}let mut i = 0;while i < chars.len() {match chars[i] {'a' | 'e' | 'i' | 'o' | 'u' => {break;}'y' => {// y在不是第一个字母时被视为元音if i > 0 {break;}i += 1;}'q' => {// 特殊处理qu组合if i + 1 < chars.len() && chars[i + 1] == 'u' {i += 2; // 跳过qubreak;}i += 1;}_ => i += 1,}}// 转换字符索引为字节索引word.char_indices().nth(i).map(|(pos, _)| pos).unwrap_or(word.len())}// 反向转换:从Pig Latin转换回英语(简化版)pub fn reverse_translate(&self, input: &str) -> String {input.split_whitespace().map(|word| self.reverse_translate_word(word)).collect::<Vec<String>>().join(" ")}fn reverse_translate_word(&self, word: &str) -> String {if !word.ends_with("ay") {return word.to_string();}let base_word = &word[..word.len() - 2]; // 移除"ay"// 简化实现:假设所有以元音结尾的词是以元音开头的// 实际实现会更复杂if base_word.ends_with("ay") || base_word.ends_with("ey") || base_word.ends_with("iy") || base_word.ends_with("oy") || base_word.ends_with("uy") {base_word.to_string()} else {// 简化的辅音处理base_word.to_string()}}
}// 单词分析器
pub struct WordAnalysis {pub original: String,pub translated: String,pub starts_with_vowel: bool,pub consonant_cluster: String,pub cluster_length: usize,
}impl PigLatinTranslator {pub fn analyze_word(&self, word: &str) -> WordAnalysis {let translated = self.translate_word(word);let consonant_cluster_end = self.find_consonant_cluster_end(word);let starts_with_vowel = consonant_cluster_end == 0;let consonant_cluster = if starts_with_vowel {String::new()} else {word[..consonant_cluster_end].to_string()};WordAnalysis {original: word.to_string(),translated,starts_with_vowel,consonant_cluster,cluster_length: consonant_cluster.chars().count(),}}
}// 便利函数
pub fn translate(input: &str) -> String {let translator = PigLatinTranslator::new();translator.translate(input)
}pub fn translate_with_options(input: &str, preserve_case: bool, preserve_punctuation: bool) -> String {let translator = PigLatinTranslator::new().with_case_preservation(preserve_case).with_punctuation_preservation(preserve_punctuation);translator.translate(input)
}

实际应用场景

Pig Latin在实际开发中有以下应用:

  1. 教育软件:语言学习和教学工具
  2. 儿童游戏:儿童编程和语言游戏应用
  3. 文本处理:自然语言处理中的文本变换
  4. 隐私保护:简单的文本混淆和隐私保护
  5. 娱乐应用:趣味文本转换和社交媒体应用
  6. 语言学研究:语言游戏和语言变换研究
  7. 密码学:简单的编码和解码练习
  8. 编程教学:字符串处理和算法教学示例

算法复杂度分析

  1. 时间复杂度:O(n)

    • 其中n是输入文本的字符数,需要遍历每个字符
  2. 空间复杂度:O(n)

    • 需要存储转换后的结果字符串

与其他实现方式的比较

// 使用正则表达式的实现
use regex::Regex;pub fn translate_regex(input: &str) -> String {let re = Regex::new(r"\b([aeiouAEIOU][a-zA-Z]*)|([b-df-hj-np-tv-zB-DF-HJ-NP-TV-Z]+)([a-zA-Z]*)\b").unwrap();re.replace_all(input, |caps: &regex::Captures| {if let Some(vowel_word) = caps.get(1) {// 以元音开头的单词format!("{}ay", vowel_word.as_str())} else {// 以辅音开头的单词let consonant_cluster = caps.get(2).unwrap().as_str();let rest = caps.get(3).unwrap().as_str();format!("{}{}ay", rest, consonant_cluster)}}).to_string()
}// 使用nom解析器的实现
use nom::{character::complete::{alpha1},combinator::{recognize, opt},sequence::{tuple},bytes::complete::tag,multi::many0,branch::alt,IResult,
};pub fn translate_nom(input: &str) -> String {// 使用nom解析器库实现Pig Latin转换// 这里只是一个示例,实际实现会更复杂unimplemented!()
}// 使用状态机的实现
#[derive(Debug, Clone, Copy)]
enum TranslationState {Start,VowelStart,ConsonantStart,ConsonantCluster,ReadingRest,
}pub fn translate_state_machine(input: &str) -> String {let mut result = String::new();let mut current_word = String::new();let mut in_word = false;for c in input.chars() {if c.is_whitespace() {if in_word {// 处理当前单词let translated = translate_single_word(&current_word);result.push_str(&translated);current_word.clear();in_word = false;}result.push(c);} else {if !in_word {in_word = true;}current_word.push(c);}}// 处理最后一个单词if in_word {let translated = translate_single_word(&current_word);result.push_str(&translated);}result
}fn translate_single_word(word: &str) -> String {// 这里复用之前的实现let consonant_cluster_end = find_consonant_cluster_end(word);if consonant_cluster_end == 0 {format!("{}ay", word)} else {let (consonant_cluster, rest) = word.split_at(consonant_cluster_end);format!("{}{}ay", rest, consonant_cluster)}
}// 使用第三方库的实现
// [dependencies]
// inflector = "0.11"pub fn translate_with_library(input: &str) -> String {// 使用第三方库进行文本处理// 这里只是一个示例unimplemented!()
}

总结

通过 pig-latin 练习,我们学到了:

  1. 字符串处理:掌握了复杂的字符串处理和文本转换技巧
  2. 模式匹配:学会了使用模式匹配处理复杂的语言规则
  3. 算法设计:理解了如何将语言规则转换为算法实现
  4. 边界处理:深入理解了各种边界情况和特殊规则的处理
  5. 性能优化:学会了预分配内存和使用高效算法等优化技巧
  6. 文本分析:理解了如何分析和处理自然语言文本

这些技能在实际开发中非常有用,特别是在文本处理、自然语言处理、教育软件等场景中。Pig Latin转换虽然是一个语言游戏问题,但它涉及到了字符串处理、模式匹配、算法设计、边界处理等许多核心概念,是学习Rust文本处理的良好起点。

通过这个练习,我们也看到了Rust在文本处理和自然语言处理方面的强大能力,以及如何用安全且高效的方式实现复杂的语言规则。这种结合了安全性和性能的语言特性正是Rust的魅力所在。

http://www.dtcms.com/a/585024.html

相关文章:

  • Tomcat的基本使用作用
  • 完整网站建设教程网站建设需要会什么软件
  • 【ASP.Net MVC 】使用Moq让单元测试变得更简单
  • Linux:线程的概念与控制
  • 零基础学AI大模型之嵌入模型性能优化
  • 【二叉搜索树】:程序的“决策树”,排序数据的基石
  • Canvas/SVG 冷门用法:实现动态背景与简易数据可视化
  • 昆明做网站做的好的公司智能建站系统 网站建设的首选
  • kali安装npm/sourcemap
  • 协作机器人的关节是通过什么工艺加工的
  • 轻松开启数字化时代,一键部署实现CRM落地
  • 长春市网站推广网站开发技术人员
  • JavaScript 指南
  • C++ LeetCode 力扣刷题 541. 反转字符串 II
  • C++死锁深度解析:从成因到预防与避免
  • 达梦DMDSC知识
  • 【C++】基于C++的RPC分布式网络通信框架(二)
  • Python 实现:从数学模型到完整控制台版《2048》游戏
  • 第1课-通过DIFY实现一个完整的Text2Sql来讲AI原生及Agentic RAG长什么样
  • 站长平台wordpress调用分类产品
  • 2.3 Transformer 变体与扩展:BERT、GPT 与多模态模型
  • 《Windows 服务器 ×WinSCP 保姆级配置指南:从 0 到 1 实现 “无痛” 远程文件管理》
  • 用nas做网站泰安集团
  • 自己做的网站可以运营不wordpress和json
  • 怎么做文学动漫网站公司logo设计图片欣赏
  • 网站建设 模块厦门网站建设哪家不错
  • 深圳做高端网站建设公司做家装的网站有什么不同
  • 武威网站建设DS716 II 做网站
  • 网站开发授权书如何更换网站域名
  • 做企业网站的轻量级cms一站式互联网营销平台