按键盘输入文本的最短路径

时间:2011-12-27 17:56:00

标签: c# algorithm

我从用户那里获得自定义字符串。现在我需要设计最短路径,在包含9个按钮的键盘中按下该字符串。

注意:

  • 解决方案字母应按字母顺序排列,即a,b,c,d,e,......
  • 每个号码至少应包含一个键盘字符

解决方案,如果输入text ='hello'

  1. a,b,c,d
  2. e,f,g
  3. h,i,j,k
  4. l,m,n
  5. o,p,q
  6. r,s,t
  7. u,v,w
  8. x,y
  9. ž
  10. 或者

    1. a,b,c,d
    2. e,f,g
    3. h,i,j,k
    4. l,m,n
    5. 0
    6. P
    7. q
    8. - [R
    9. s,t,u,v,w,x,y,z
    10. 使用此键盘我需要按“3,2,4,4,5”键入“hello”

      因此,如果您想使用此设计的键盘输入'hello',您只需按下5个键盘按钮,因为这是最少的键数。

      我认为这个问题是用贪婪的方法或回溯算法解决的。

2 个答案:

答案 0 :(得分:3)

让我们将字母表推广到{1,...,n}。设k是键的数量。对于1≤i<1。 j≤k,可能键{i,...,j}的成本(=按下次数)为1f i + 2f i + 1 + ... +(j - i + 1)f j ,其中f i 是字母i的频率。我们正在寻找由k个密钥组成的最低成本精确覆盖。

此问题具有以下最佳子结构:修复任意最优解并删除其上带有{m + 1,...,n}的密钥。结果是k - 1键和字母{1,...,m}问题的最优解;否则,我们可以通过重新排列第一个k-1键来改进第一个最佳解决方案。

因此,我们可以应用动态编程。对于每0≤i≤n且每0≤j≤k,使用j键计算{1,...,i}的最佳排列。这种安排C i,j 的成本满足复发

对于所有j≥0,

C 0,j = 0 对于所有i> C i,0 =∞; 0
C i,j = min 0≤i'&lt;我(C i',j-1 + c i',j ),

其中c a,b 是密钥{a,...,b}的成本。人们可以从最佳参数序列中恢复这种安排。

答案 1 :(得分:2)

每个有效的键盘对应一个26位数字,正好有9位设置为1.只有2042975个有效组合要尝试,在其他需要更多思考的方法之前,暴力应该是首先尝试的。算法就像这个伪代码:

int best_score = int.max
list<int> keypads
for int mask between 1 and 1<<26
    if bit_count(mask) != 9 or mask ends in 1 continue
    int lookup[26]
    int p = 1
    for int i between 0 and 26
        lookup[i] = p
        if mask's bit i is set to 1, p = 1 ; otherwise, p = p + 1
    int total = 0
    for each char ch in word
        total = total + lookup[ch]
    if total < best
        keypads = new list {mask}
        best = total
    else if total == best
        keypads.add(mask)
print best, keypads