这道题目是说使用手机上的数字小键盘发送短信的话,有些英文字母需要多次按同一个数字键才能输入。比如很常用的字母“s”就需要按四次“7”键才 行。我们的任务是写一个程序,在不改变字母的顺序的情况下,将这些字母分配到各个按键上,使用得输入信息的总的按键次数最少。输入信息中各个字母出现的频 率是已经给定的。
下面就是使用动态规划算法解答的 C 语言源程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#include <stdio.h> #include <string.h> #define MAX (90 + 1) static int cost[MAX][MAX], price[MAX][MAX], index[MAX][MAX]; void initialize( int L, int F[]) { memset (price, 0x40, sizeof (price)); price[0][0] = 0; for ( int i = 1; i <= L; i++) for ( int j = i; j <= L; j++) cost[i][j] = cost[i][j - 1] + (j - i + 1) * F[j - 1]; } void compute( int K, int L) { for ( int i = 1; i <= K; i++) for ( int j = i; j <= L; j++) for ( int n = 1; n <= j - i + 1; n++) { int sum = price[i - 1][j - n] + cost[j - n + 1][j]; if (sum <= price[i][j]) price[i][j] = sum, index[i][j] = n; } } void output( int K, int L, char keys[], char letters[]) { if (K == 0) return ; output(K - 1, L - index[K][L], keys, letters); printf ( "%c: " ,keys[K - 1]); for ( int i = L - index[K][L]; i < L; i++) putchar (letters[i]); puts ( "" ); } int main( void ) { int F[MAX - 1], T; scanf ( "%d" , &T); for ( int K, L, n = 1; n <= T; n++) { char keys[MAX], letters[MAX]; scanf ( "%d%d%s%s" , &K, &L, keys, letters); for ( int i = 0; i < L; i++) scanf ( "%d" , F + i); initialize(L, F); compute(K, L); printf ( "Keypad #%d:\n" , n); output(K, L, keys, letters); puts ( "" ); } return 0; } |
假设我们有以下输入:
1 3 9 123 ABCDEFGHI 1 30 10 10 10 31 11 12 9
运行该程序将得到以下输出:
Keypad #1: 1: A 2: BCDE 3: FGHI
使用上一节的输入数据运行该程序,主要的运行状态如下所示:
上述程序中:
注意,这道题目要求在同等代价下将字符尽量分配到后面的按键中,所以第 24 行比较代价时使用“<=”,以便尽量增加后面按键的字符数。 如果将这个程序第 24 行的“<=”改为“<”,则将得到以下输出:
Keypad #1: 1: ABC 2: DE 3: FGHI
此时,策略是在同等代价下将字符尽量分配到前面的按键中。
维基百科网站的 Letter frequency 给出了英语中二十六个字母出现的频率,如下表所示:
Letter | Frequency |
---|---|
a | 8.167% |
b | 1.492% |
c | 2.782% |
d | 4.253% |
e | 12.702% |
f | 2.228% |
g | 2.015% |
h | 6.094% |
i | 6.966% |
j | 0.153% |
k | 0.772% |
l | 4.025% |
m | 2.406% |
n | 6.749% |
o | 7.507% |
p | 1.929% |
q | 0.095% |
r | 5.987% |
s | 6.327% |
t | 9.056% |
u | 2.758% |
v | 0.978% |
w | 2.360% |
x | 0.150% |
y | 1.974% |
z | 0.074% |
根据上表设置相应的输入文件:
1 8 26 23456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ 8167 1492 2782 4253 12702 2228 2015 6094 6966 153 772 4025 2406 6749 7507 1929 95 5987 6327 9056 2758 978 2360 150 1974 74
运行结果如下所示:
Keypad #1: 2: AB 3: CD 4: EFG 5: HIJK 6: LM 7: NOPQ 8: RS 9: TUVWXYZ
数字“9”键上居然有七个英文字母,可见最后几个英文字母出现的频率很低。看来在英文国家手机的数字键盘应该如上设置才能够更好地输入信息。当然, 我们输入中文又是另外一回事了,用拼音和用五笔输入法,各个字母的频率也是不同的。其实手机向智能化发展,越来越多地使用全键盘了,不再使用数学小键盘。
原文:http://www.cnblogs.com/zhaoxinshanwei/p/3859332.html