华为0429笔试
拼尽全力还是个废物。。。
1.LSTM
python
import numpy as np
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def lstm_forward(X, gates, B, H):
T = X.shape[0]
# 遗忘门、输入门、候选细胞状态、输出门 参数
Wxi, Whi, bi = gates[0] # 输入门
Wxf, Whf, bf = gates[1] # 遗忘门
Wxc, Whc, bc = gates[2] # 候选细胞状态
Wxo, Who, bo = gates[3] # 输出门
h_all = []
h = np.zeros((B, H))
c = np.zeros((B, H))
for t in range(T):
xt = X[t]
# 1.遗忘门
ft = sigmoid(xt @ Wxf + h @ Whf + bf)
# 2.输入门
it = sigmoid(xt @ Wxi + h @ Whi + bi)
# 3.候选细胞状态
ct_hat = np.tanh(xt @ Wxc + it @ Whc + bc)
# 4.细胞状态更新
c = ft * c + it * ct_hat
# 5.输出门
ot = sigmoid(xt @ Wxo + it @ Who + bo)
# 6.隐状态更新
h = ot * np.tanh(c)
h_all.append(h.copy())
return h_all, c
def solve():
line = list(map(int, input().split()))
T = line[0]
B = line[1]
D = line[2]
H = line[3]
# 处理输入序列
X = np.zeros((T, B, D))
for i in range(T):
X[i] = np.array(list(map(float, input().split())))
# 处理四个门的参数
def read_gate():
row = list(map(float, input().split()))
Wx = np.array(row[:D * H]).reshape((D, H))
Wh = np.array(row[D * H:D * H + H * H]).reshape((H, H))
b = np.array(row[D * H + H * H:])
return Wx, Wh, b
gates = [read_gate() for _ in range(4)]
h_all, c = lstm_forward(X, gates, B, H)
h = np.concatenate(h_all).flatten()
print(' '.join(f'{item:.4f}' for item in h))
print(' '.join(f'{x:.4f}' for x in c.flatten()))
solve()
2.数据清洗
python
"""
防止 大语言模型 在生成时出现 复读机现象
清洗规则:
1. 空格规范化
首先对文档中所有连续的空白字符(空格、制表符等)合并为一个空格,并去除首尾空格。
规范化后的字符串总长度必须在[L, R]的闭区间内,如果不满足,直接丢弃该文档。
注意:如果文档被保留,最终输出的必须是这个"规范化后"的字符串。
2. 语义单词提取
将规范化后的文档按非字母数字字符(即除了a-z,A-Z,0-9以外的所有字符)进行分割,提取出所有的有效"单词",并全部转化为小写。
例如:"He is A! Spammer"提取出的单词序列为['he', 'is', 'a', 'spammer']。
3. 独立黑名单拦截
给定个 K 黑名单词汇。如果在第2步提取出的单词序列中,精确匹配到了任何一个黑名单词汇(不区分大小写),则丢弃该文档。
注意:必须是独立单词匹配,不能是子串匹配。例如黑名单中有spam,但文档中的spammer可以是合法的。
4. 3-gram复读惩罚
在提取出的单词序列中,任何连续的三个单词构成一个 3-gram。如果该文档中存在任何一个 3-gram 出现次数严格大于M次,则判定为复读机文本,直接丢弃。
例如M = 1时,序列['a','b','c','a','b','c']中,('a', 'b', 'c')出现了2次, 则应该去掉
5. 规范化语义去重
如果两篇文档 提取出的单词序列完全一致,判定为语义重复,仅保留按输入顺序第一次出现的那篇文档
"""
import re
N, L, R, M, K = map(int, input().split())
black_list = set()
if K > 0:
black_list = set(input().split())
seen = set() # 存放已出现的 词序列,用于语义去重
str_list = []
results = []
for _ in range(N):
doc = input()
# 规则1:空格规范化 - split() 自动按所有空白分割并去首尾
normalized = ' '.join(doc.split())
# 长度不在 [L, R] 范围内
if not (L <= len(normalized) <= R):
continue
# 规则2:提取所有字母、数字组成的单词,统一转小写
words = tuple(w.lower() for w in re.findall(r'[a-zA-Z0-9]+', normalized))
# 规则3 黑名单精准匹配
if any(w in black_list for w in words):
continue
# 规则4:统计每个连续三词 组合出现的 出现次数,超过M次则丢弃
if len(words) >= 3:
trigram = {}
bad = False
for i in range(len(words) - 2):
key = (words[i], words[i + 1], words[i + 2])
trigram[key] = trigram.get(key, 0) + 1
# 超过M次 直接丢弃
if trigram[key] > M:
bad = True
break
if bad:
continue
# 规则5语义去重
if words in seen:
continue
seen.add(words)
results.append(normalized)
print('\n'.join(results), end='')
补充知识点
re(正则表达式)
核心函数
-
re.findall(pottern, string):- 作用:寻找所有匹配的部分,返回一个列表
- 场景:提取文档中 所有"单词"
- 例子:re.findall(r'[a-z]+', "hello 123 world") →\rightarrow→ ['hello', 'world']
-
re.sub(pattern, repl, string):- 作用:替换匹配到的部分
- 场景:把所有非字母数字的符号替换为空格,或者删除特定噪声
- 例子:
re.sub(r'[^a-zA-Z0-9]', ' ', "A!B@C") $\rightarrow$ "A B C"
-
re.split(pattern, string)- 作用:按模式分割字符串
- 场景:当分隔符不只是空格(比如逗号,感叹号)
元字符:构建规则的积木
正则是一套描述字符特征的语言
| 符号 | 含义 | 对应你题目中的场景 |
|---|---|---|
[a-z] |
匹配任何小写字母 | 提取语义单词 |
[A-Z] |
匹配任何大写字母 | 处理大小写不敏感的匹配 |
[0-9] |
匹配任何数字 | 题目要求保留字母数字时必用 |
[a-zA-Z0-9] |
匹配字母或数字 | 最常用:定义什么是"有效单词" |
[^a-zA-Z0-9] |
^ 在中括号内表示"非" |
匹配所有标点符号、特殊字符 |
\s |
匹配任何空白字符(空格、换行、制表符) | 规范化空格 |
数量修饰符(控制匹配多少个)
+:匹配 1 次或多次。例如 [a-z]+ 会把 hello 当作一个整体提取,而不是 5 个字母。
*:匹配 0 次或多次。
{n,m}:匹配 n 到 m 次。
字符串转换相关
.lower():全部转为小写。"HELLO".upper()→\rightarrow→"hello"
.upper():全部转为大写。"hello".upper()→\rightarrow→"HELLO"
.lower():全部转为小写。"WORLD".lower()→\rightarrow→"world"
.capitalize():仅首字母大写,其他全部小写。"hello world".capitalize()→\rightarrow→"Hello world"
.title():每个单词的首字母都大写(标题格式)。"hello world".title()→\rightarrow→"Hello World"
.swapcase():大小写反转(大变小,小变大)。"Hello World".swapcase()→\rightarrow→"hELLO wORLD"