万能字符单词拼写 - 华为OD统一考试-LMLPHP

题目描述

有一个字符串数组 words 和一个字符串 chars。假如可以用 chars 中的字母拼写出 words 中的某个"单词"(字符串),那么我们就认为你掌握了这个单词。

words 的字符仅由 a-z 英文小写宁母组成,例如“abc”。

chars 由 a- z 英文小写字母和“?”组成,其中英文“?"表示万能字符,能够在拼写时当作任意一个英文字母。例如“?"可以当作"a"等字母。

注意: 每次拼写时,chars 中的每个字母和万能字符都只能使用一次。

输出词汇表 words 中你掌握的所有单词的个数。没有掌握任何单词,则输出0。

输入描述

第一行: 输入数组 words 的个数,记作N。

第二行~第N+1行: 依次输入数组words的每个字符串元素。

第N+2行: 输入字符串 chars

输出描述

输出一个整数,表示词汇表 words 中你掌握的单词个数

备注

1 <= words.length <= 100

1 <= words[i].length, chars.length <= 100

所有字符串中都仅包含小写英文字母、英文问号

示例1

输入
4
cat
bt
hat
tree
atach??

输出
3

说明:可以掌握的单词 "cat”、“bt"和"hat"。

示例2

输入
3
hello
world
cloud
welldonehohneyr

输出:
2

说明:可以掌握的单词 "hello”、“world"。

示例3

输入
3
apple
car
window
welldoneapplec?

输出:
2

说明:可以掌握的单词 "apple”、“car"。

题解

Java

import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author code5bug
 */
public class Main {

    // 统计字符串各字符个数
    public static int[] counter(String s) {
        // cnt[26] 表示 '?' 号的个数
        int[] cnt = new int[27];
        for (char c : s.toCharArray()) {
            if (c == '?') cnt[26]++;
            else cnt[c - 'a']++;
        }
        return cnt;
    }

    // 检测 source 字符个数能否由 target 拼接而来(target[26] 表示 '?' 的个数)
    public static boolean canSpell(int[] source, int[] target) {
        int t = target[26];  // '?' 号个数
        for (int i = 0; i < 26 && t >= 0; i++) {
            if (source[i] <= target[i]) continue;

            t -= (source[i] - target[i]);
        }

        return t >= 0;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = Integer.parseInt(in.nextLine());

        List<String> words = IntStream.range(0, N)
                .mapToObj(i -> in.nextLine())
                .collect(Collectors.toList());
        String chars = in.nextLine();
        int[] tcnt = counter(chars);
        int canSpellWordCnt = 0;
        for (String word : words) {
            if (canSpell(counter(word), tcnt)) canSpellWordCnt++;
        }

        System.out.println(canSpellWordCnt);
    }
}

Python

from collections import Counter

N = int(input())
words = [input() for _ in range(N)]
BASE_COUNTER = Counter(input())


def can_spell(word) -> bool:  # 能否拼出 word
    word_counter = Counter(word)
    wildcard_cnt = BASE_COUNTER['?']
    for c, cnt in word_counter.items():
        bcnt = BASE_COUNTER.get(c, 0)
        if bcnt < cnt:  # 数量不够通配符来凑
            wildcard_cnt -= cnt - bcnt

    return wildcard_cnt >= 0


can_spell_word_cnt = sum([1 for word in words if can_spell(word)])
print(can_spell_word_cnt)

C++

#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int> counter(string& word) {
    vector<int> cnt(27);
    for(char c : word) {
        if(c == '?') cnt[26]++;
        else cnt[c -'a']++;
    }
    return cnt;
}

bool canSpell(const vector<int>& source, const vector<int>& target) {
    int t = target[26];
    for(int i=0; i<26; i++) {
        if(source[i] <= target[i]) continue;

        t -= source[i] - target[i];
    }

    return t >= 0;
}

int main() {
    int N;

    cin >> N;
    cin.ignore(); // 消耗掉换行符

    vector<string> words;
    string line;

    for(int i=0; i<N; i++) {
        getline(cin, line);
        words.push_back(line);
    }
    getline(cin, line);
    vector<int> tcnt = counter(line);
    int canSpellWordCnt = 0;
    for(string& word : words) {
        if(canSpell(counter(word), tcnt)) {
            canSpellWordCnt++;
        }
    }

    cout << canSpellWordCnt << endl;
    return 0;
}

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

01-09 11:15