题目描述
有一个字符串数组 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;
}
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏