AtCoder Beginner Contest 324 E

https://atcoder.jp/contests/abc324/tasks/abc324_e

各Sに対し、左からと右からでTと何文字一致するかを調べますが、コードが共通化しにくいのが辛いですね。

// Joint Two Strings
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}


//////////////////// process ////////////////////

fn read_input() -> (String, Vec<String>) {
    let v: Vec<String> = read_vec();
    let N: usize = v[0].parse().unwrap();
    let T: String = v[1].to_string();
    let S: Vec<String> = (0..N).map(|_| read::<String>()).collect();
    (T, S)
}

fn match_number(s: &String, T: &String) -> usize {
    let mut q = T.chars().enumerate();
    let mut p = q.next().unwrap();
    for c in s.chars() {
        if c == p.1 {
            match q.next() {
                Some(p1) => p = p1,
                None     => return p.0 + 1
            }
        }
    }
    p.0
}

fn match_number_rev(s: &String, T: &String) -> usize {
    let mut q = T.chars().rev().enumerate();
    let mut p = q.next().unwrap();
    for c in s.chars().rev() {
        if c == p.1 {
            match q.next() {
                Some(p1) => p = p1,
                None     => return p.0 + 1
            }
        }
    }
    p.0
}

fn match_both(s: &String, T: &String) -> (usize, usize) {
    (match_number(s, T), T.len() - match_number_rev(s, T))
}

fn accumulate(v: &Vec<usize>, L: usize) -> Vec<usize> {
    let freq = frequency(v, L);
    let mut acc: Vec<usize> = vec![0; L];
    acc[0] = freq[0];
    for i in 1..L {
        acc[i] = acc[i-1] + freq[i]
    }
    acc
}

fn frequency(v: &Vec<usize>, L: usize) -> Vec<usize> {
    let mut freq: Vec<usize> = vec![0; L];
    for &e in v.iter() {
        freq[e] += 1
    }
    freq
}

fn F(T: String, S: Vec<String>) -> usize {
    let v: Vec<(usize, usize)> = S.iter().map(|s| match_both(s, &T)).collect();
    let v1: Vec<usize> = v.iter().map(|&(e, _)| e).collect();
    let v2: Vec<usize> = v.iter().map(|&(_, e)| e).collect();
    
    let L = T.len() + 1;
    let acc = accumulate(&v2, L);
    let freq = frequency(&v1, L);
    
    (0..L).map(|i| acc[i]*freq[i]).sum::<usize>()
}


//////////////////// main ////////////////////

fn main() {
    let (T, S) = read_input();
    println!("{}", F(T, S))
}