2011-03-04 59 views
1

假設我有一個字符串「text」,插入位置「caret」,然後想要查找當前單詞(由空格分隔)。從字符數組中獲取當前單詞的最有效方法

我現在這樣做的方式似乎效率低下,我想知道是否有人有這樣做的有效方式?

const char* text; 
int caret; 
int initpos; 
int start; 
int count = 0; 
char word[256]; 

// text and caret values assigned here. 

initpos = caret; 
while(caret > 0 && text[caret] != ' ') // get start 
{ 
    caret--; 
    count++; 
} 
start = caret; 
caret = initpos; 

while(text[caret] && text[caret] != ' ') // get end 
{ 
    caret++; 
    count++; 
} 

word = strsub(text, start, count); 
+0

該代碼不能編譯,你不能分配給一個數組名。 – unwind 2011-03-04 11:15:54

+0

在我看來,很難打敗這些代碼(假設@ unwind的評論,以及未初始化的「caret」,並且從數組邊界開始行走只是嘗試將問題修剪成可輕鬆發佈和討論的事例) - 你必須在每個角色之前和之後看看每個角色,找到一個比個人角色檢查更快找到空間的技巧似乎不太可能。 – sarnold 2011-03-04 11:20:53

+0

也許你還想考慮水平製表符等除了空格。 – Flinsch 2011-03-04 11:23:04

回答

5

通過「似乎效率低下」,你的意思是代碼看起來低效你或你測量,並找到您想要的目的,太慢了嗎?

你的方法需要O(ñ)步驟,其中ñ是最長的單詞在你輸入的長度。這很快,除非你的文字有DNA字符串的大小。

對於某些數據集,更快的方法是使用單詞開始和結束位置的索引。存儲時間間隔的二叉搜索樹將適合此帳單,但代價爲O(檢索時間),其中N是輸入中的單詞數。可能不值得。

0
#include <ctype.h> 

... 
// Other definitions from above. 
char *p = word; 
char *q = text + caret; 
while(q >= text && !isblank(*q)) { 
    q--; 
} 
if (q < text) q++; // All non-blanks. 
while (*q && !isblank(*q)) { 
    *p++ = *q++; 
} 
*p = '\0'; 
// word now has nul terminated non-blank characters, p points to EOL or blanks. 
+0

我不認爲這與提供的示例代碼相同:它不會看起來「向後」來查找單詞的開頭。要查看原始海報想要的更多內容,請啓動'vim',使用'v'進入視覺選擇模式,並使用'aW'選擇「一個WORD」。無論您將光標放在單詞的哪個位置,整個單詞都會被選中。 – sarnold 2011-03-04 11:35:24

+0

@sarnold:你說得對。我需要更多的咖啡。你最初必須走回頭路尋找空白或字符串的開頭。 – 2011-03-04 11:43:07

1

我認爲這是一種有效的方法。我只是建議檢查字符是否是字母,而不是空格:

while(caret > 0 && ((text[caret]>='A' && text[caret]<='Z') || (text[caret]>='a' && text[caret]<='z'))) 

這會捕獲其他情況,例如,當一個點,一個數字,一個括號等字終止時

+1

爲什麼不用'isalpha()'(在''中聲明)呢?您的條件不會「捕捉」ã'或'ÿ'或其他許多單詞形成字符,而'isalpha()'具有適當的語言環境集合,可捕獲所有單詞字符。 – pmg 2011-03-04 12:15:41

相關問題