在Web中搜索(Searching the Web, ACM/ICPC Beijing 2004, UVa1597)rust解法

输入n篇文章和m个请求(n<100,m≤50000),每个请求都是以下4种格式之一。

A:查找包含关键字A的文章。

A AND B:查找同时包含关键字A和B的文章。

A OR B:查找包含关键字A或B的文章。

NOT A:查找不包含关键字A的文章。

处理询问时,需要对于每篇文章输出证据。前3种询问输出所有至少包含一个关键字的行,第4种询问输出整篇文章。关键字只由小写字母组成,查找时忽略大小写。每行不超过80个字符,一共不超过1500行。

样例:

输入

复制代码
4
A manufacturer, importer, or seller of
digital media devices may not (1) sell,
or offer for sale, in interstate commerce,
or (2) cause to be transported in, or in a
manner affecting, interstate commerce,
a digital media device unless the device
includes and utilizes standard security
technologies that adhere to the security
system standards.
**********
Of course, Lisa did not necessarily
intend to read his books. She might
want the computer only to write her
midterm. But Dan knew she came from
a middle-class family and could hardly
afford the tuition, let alone her reading
fees. Books might be the only way she
could graduate
**********
Research in analysis (i.e., the evaluation
of the strengths and weaknesses of
computer system) is essential to the
development of effective security, both
for works protected by copyright law
and for information in general. Such
research can progress only through the
open publication and exchange of
complete scientific results
**********
I am very very very happy!
What about you?
**********
6
computer
books AND computer
books OR protected
NOT security
very
slick

输出

复制代码
want the computer only to write her
----------
computer system) is essential to the
==========
intend to read his books. She might
want the computer only to write her
fees. Books might be the only way she
==========
intend to read his books. She might
fees. Books might be the only way she
----------
for works protected by copyright law
==========
Of course, Lisa did not necessarily
intend to read his books. She might
want the computer only to write her
midterm. But Dan knew she came from
a middle-class family and could hardly
afford the tuition, let alone her reading
fees. Books might be the only way she
could graduate
----------
I am very very very happy!
What about you?
==========
I am very very very happy!
==========
not found
==========

解法:

rust 复制代码
use std::{
    collections::{BTreeMap, BTreeSet, HashMap},
    io,
};
#[derive(PartialEq)]
enum WordOp {
    AND,
    OR,
    None,
    NOT,
}

fn get_words(s: &String) -> Vec<String> {
    let w: String = s
        .chars()
        .map(|x| {
            if x.is_alphabetic() {
                x.to_ascii_lowercase()
            } else {
                ' '
            }
        })
        .collect();
    let wds: Vec<String> = w.split_whitespace().map(|x| x.to_string()).collect();
    wds
}
fn main() {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let n: usize = buf.trim().parse().unwrap();
    let mut articles: Vec<Vec<String>> = vec![];//每篇文章的所有行
    let mut words: Vec<HashMap<String, BTreeSet<usize>>> = vec![];//每篇文章的所有单词和单词所在的行号
    for _i in 0..n {
        let mut article: Vec<String> = vec![];
        let mut wd: HashMap<String, BTreeSet<usize>> = HashMap::new();
        loop {
            let mut buf = String::new();
            io::stdin().read_line(&mut buf).unwrap();
            if buf.trim() == "*".repeat(10) {
                break;
            }
            article.push(buf.trim().to_string());
            //count words
            let v: Vec<String> = get_words(&buf);
            let line_idx = article.len() - 1;
            for w in v.iter() {
                wd.entry(w.to_string())
                    .and_modify(|x| {
                        x.insert(line_idx);
                    })
                    .or_insert(BTreeSet::from([line_idx]));
            }
        }
        articles.push(article);
        words.push(wd);
    }
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let m: usize = buf.trim().parse().unwrap();
    let mut cmds = vec![];
    for _i in 0..m {
        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        cmds.push(buf.trim().to_string());
    }
    for cmd in cmds.iter() {
        if let Some(idx) = cmd.find("OR") {
            let word1 = cmd[0..idx - 1].to_string();
            let word2 = cmd[idx + 3..].to_string();
            find_word(&articles, &words, &word1, &word2, WordOp::OR);
        } else if let Some(idx) = cmd.find("AND") {
            let word1 = cmd[0..idx - 1].to_string();
            let word2 = cmd[idx + 4..].to_string();
            find_word(&articles, &words, &word1, &word2, WordOp::AND);
        } else if let Some(idx) = cmd.find("NOT") {
            let word1 = cmd[idx + 4..].to_string();
            find_word(&articles, &words, &word1, &"".to_string(), WordOp::NOT);
        } else {
            let word1 = cmd;
            find_word(&articles, &words, word1, &"".to_string(), WordOp::None);
        }
        println!("{}", "=".repeat(10));
    }
}

fn print_result(find_result: BTreeMap<usize, BTreeSet<usize>>, articles: &Vec<Vec<String>>) {
    if find_result.is_empty() {
        println!("not found");
    } else {
        let mut cnt = 0;
        for (k, v) in find_result.iter() {
            for i in v.iter() {
                println!("{}", articles[*k][*i]);
            }
            cnt += 1;
            if cnt != find_result.len() {
                println!("{}", "-".repeat(10));
            }
        }
    }
}

fn find_word(
    articles: &Vec<Vec<String>>,
    words: &Vec<HashMap<String, BTreeSet<usize>>>,
    word1: &String,
    word2: &String,
    op: WordOp,
) {
    let mut find_result: BTreeMap<usize, BTreeSet<usize>> = BTreeMap::new();
    for (aidx, lines) in articles.iter().enumerate() {
        let mut find_line_idx: BTreeSet<usize> = BTreeSet::new();
        let ws = words.get(aidx).unwrap();
        if op == WordOp::OR {
            if ws.contains_key(word1) || ws.contains_key(word2) {
                if let Some(idx) = ws.get(word1) {
                    find_line_idx.append(&mut idx.clone());
                }
                if let Some(idx) = ws.get(word2) {
                    find_line_idx.append(&mut idx.clone());
                }
                find_result.insert(aidx, find_line_idx);
            }
        } else if op == WordOp::AND {
            if ws.contains_key(word1) && ws.contains_key(word2) {
                let idx = ws.get(word1).unwrap();
                find_line_idx.append(&mut idx.clone());
                let idx = ws.get(word2).unwrap();
                find_line_idx.append(&mut idx.clone());
                find_result.insert(aidx, find_line_idx);
            }
        } else if op == WordOp::None {
            if ws.contains_key(word1) {
                let idx = ws.get(word1).unwrap();
                find_line_idx.append(&mut idx.clone());
                find_result.insert(aidx, find_line_idx);
            }
        } else if op == WordOp::NOT {
            if !ws.contains_key(word1) {
                find_line_idx.append(&mut (0..lines.len()).collect());
                find_result.insert(aidx, find_line_idx);
            }
        }
    }
    print_result(find_result, &articles);
}
相关推荐
无名之逆13 小时前
Hyperlane:Rust 语言打造的 Web 后端框架新标杆
开发语言·前端·网络·网络协议·rust·github·ssl
勇敢牛牛_15 小时前
【Rust交叉编译】在x86_64架构下交叉编译aarch64-linux-musl版的rust-opencv
linux·opencv·rust·aarch64
Hello.Reader18 小时前
调试 Rust + WebAssembly 版康威生命游戏
游戏·rust·wasm
helloweilei1 天前
Rust学习笔记 之 char类型
rust
红尘散仙1 天前
三、WebGPU 基础入门——绘制三角型
rust·typescript·gpu
无名之逆1 天前
Hyperlane:Rust 生态中的轻量级高性能 HTTP 服务器库,助力现代 Web 开发
服务器·开发语言·前端·后端·http·面试·rust
无名之逆1 天前
轻量级、高性能的 Rust HTTP 服务器库 —— Hyperlane
服务器·开发语言·前端·后端·http·rust
无名之逆1 天前
探索Hyperlane:用Rust打造轻量级、高性能的Web后端框架
服务器·开发语言·前端·后端·算法·rust
Source.Liu1 天前
【CXX】6.9 CxxVector<T> — std::vector<T>
c++·rust·cxx
无名之逆2 天前
告别死锁!Hyperlane:Rust 异步 Web 框架的终极解决方案
服务器·开发语言·前端·网络·http·rust