2011-03-04 168 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

相关问题