2012-12-10 67 views
-1

我們的一個自助終端應用程序缺少物理鍵盤,我們需要爲其添加文本輸入。由於它只有一個數字鍵盤,我們認爲我們不妨使用舊手機進入方法。我已經能夠發現它被稱爲multitap(去圖),但我找不到任何算法實現。有人知道嗎?多抽頭/多按/三抽頭算法

(我不能限制輸入到一個字典,所以我不能使用T9樣的辦法)

+1

這可能是一個有趣的算法來表達[FSM](http://en.wikipedia.org/wiki/Finite-state_machine) –

+0

不完全是你在找什麼,而是一個整潔的紙上類似輸入法:http://pdos.csail.mit.edu/~jj/jannotti.com/papers/iconic-uist02/ –

回答

1

我會用在組合的定時器與一個int計數抽頭。這是純粹的僞代碼,但會提供基本的想法。

long lastEvent = 0; 
int lastNum = 0; 
int taps = 0; 


eventListener(KeyEventArgs e) 
{ 
    if (e.Value == lastNum) 
    { 
     if ((DateTime.Now.ToFileTimeUtc() - lastEvent) < AppropriateTimeLimit) 
     { 
       taps++; 
     } 
     else 
     { 
       GetLetter(taps, lastNum); 
       lastEvant = DateTime.Now.ToFileTimeUtc(); 
       taps = 0; 
     } 
    } 
    else 
    { 
       GetLetter(taps, lastNum); 
       lastEvant = DateTime.Now.ToFileTimeUtc(); 
       taps = 0; 
       lastNum = e.Value; 
    } 
} 

char GetLetter(int taps, int num) 
{ 
    if (num == 1) 
     return punctuationVals[taps % length -1]; 
    else if (num == 0) 
     return ' '; //from what I remember 0 was for spaces on most phones 
    else 
    { 
     int val; 
     if (taps > 3) 
      val = taps % 4; // old phones wrap around back to the first char if I press the key 5 times 
     else 
      val = taps; 
      return values[num][val]; 
    } 

} 

char[][] values = new char[9][4]; // statically code all of your chars in these arrays 
char[] punctuationVals = new char[idkHowMany]; 

所以這裏是設計概述。首先,我們有一個處理所有輸入事件的事件監聽器。我們知道在以下兩種情況下,敲擊序列是完整的1)時間已過(如果您還記得在舊手機上打字,如果我想輸入'abc',我必須按2次,等待一秒左右,按2兩次等待另一秒,按兩次三次)或2)按下新鍵。

在這兩種情況下,我們都需要知道最後一個按鍵是什麼,所以我們跟蹤它。如果鍵輸入與最後一個按鍵不匹配,那麼我們可以安全地輸出最後一個按鍵,因此我們呼叫GetLetter,將水龍頭重置爲0,將最後的偶數時間設置爲現在,並將lastNum設置爲剛纔的數字按下。這是更簡單的情況。

在有人試圖輸入'abc'的情況下,我們需要知道何時區分第一個輸入的結尾和下一個的開始。爲此我們使用一個計時器。如果第一次敲擊和剛剛發生的敲擊之間的差異在一定範圍內(可能是半秒或一秒),那麼我們增加敲擊次數,如果它超出了敲擊次數,我們認爲他們已經從'a'到'b',此時我們會經歷與用戶按下與上次不同的鍵時所經歷的相同輸出過程,除非我們不更改最後一次按下的鍵的值,因爲它沒有改變。

GetLetter是值得討論的最後一件事。這很簡單,你用一個二維數組編碼2-9,爲了使索引變得簡單,我們將保留0和1,但將它們留空。

意思是說,數組是類似的;

'', '','', '' 
    '', '', '', '' 
    '2', 'a', 'b', 'c' 
    '3', 'd', 'e', 'f' 
    //ect 

這使得索引更簡單,只需GetLetter(2, 2)返回values[2][2]這是正確的 'B'。

因爲在2鍵上連續7次敲擊會產生'c',所以如果它大於3,我們會對該值做4次修改(3次因爲4%4是0,應該產生索引0處的數字本身) 。現在GetLetter(6, 2)將返回正確'b'的values[2][2]

1是一個特例。爲此,我們只使用一個具有多個值(可能是20或者某個值)的一維數組,並且我們也對它的輸入做了模數,但顯然它是基於該數組的長度。我對這種情況的模數可能是錯誤的,但修復起來很簡單。

0

它實際上是四水龍頭,看着我的電話撥號盤上的字母。

我不知道是否有星號和磅鍵的標準,但可以將字母放在查找表中。

例如,

7 key, three taps, returns R 
5 key, one tap, returns J 

如果你確實需要的數量,這是一個額外的水龍頭。

7 key, five taps, returns 7 

我相信我古老的手機上的英鎊鍵從大寫轉小寫,小寫大寫。還有一個標題案例,它會產生一個大寫字母並轉換爲小寫字母。

星號鍵彈出一個標點符號表。您可以使用2,4,6,8鍵來瀏覽表格並選擇一個符號。

+1

它實際上是完全不同的,並且需要每個輸入的模數。舊手機會將20個標點符號分配爲1.如果我想鍵入「+」或「%」,則需要15次點擊。 – evanmcdonnal

1

因此,除零之外的每個按鈕都以4爲增量運行,因此,無論某個鍵盤號碼上有多少次點擊,只需將其除以4即可,其餘爲1 =數字2 =第一個字母3 =第二個字母,0 =第三個字母。然後,根據你希望有多少符號,以允許用戶使用,你可以使用相同的理念,爲鍵盤上的0和符號

1-ABC

2高清

3 GHI

4- JKL

5- MNO

6- PQR

7-S-T-U

8-V-W-X

9-Y-Z空白

0 - 符號