最近碰到了一个程序设计方面的小问题,最后以一种不完美的的方法解决了它,说出来可能比较有意思:
在写我的程序(FlashIME,http://www.d2ksoft.com 一种仿输入法软件)当中,需要有一个类记住最近的输入到当前编辑器的字符串(旧字符串)。
当我下一次输入新的字符串的时候,我必须在输入新的字符串之前,先比较剪贴板中的内容是否和旧字符串的内容一样。如果一样,就有一些操作,如果不一样,又有另外一些操作(操作的细节无关紧要)。然后我输入新的字符串,再用新字符串的内容更新旧字符串的内容。
我用一个CManageStr类来存储旧字符串,一开始这个类CManageStr是这样设计的:
class CManageStr{
public:
CManageStr():_buf(0){
}
~CManageStr(){
free(_buf);
_buf=0;
}
bool compare_with_clip();
update_from_new(const char* input);
{
free(_buf);
_buf=0;
_buf=malloc(strlen(input)+1);
strcpy(_buf,input);
}
private:
char* _buf;
}
因为不能知道最近输入的字符串可能有多大,所以一开始的想法是用动态分配内存的办法存储旧字符串。
但是由于开发的是仿输入法的程序,所以CManageStr类型的对象将会被多个进程共享使用。而指针显然不能被多个进程共享。这样就不能使用诸如_buf之类的指针类型的数据成员。
仔细考虑为什么要存储最近输入的字符串?实际上目的只是为了和剪贴板中的字符串比较,比较的结果只需要知道两个字符串是否相同。如果能够放宽“相同”的定义,那么就可以重新设计CManageStr的数据成员,以使得CManageStr对象可以被多个进程共享。
例如,将字符串中的所有字符的ascii码相加得到一个整数(check sum)。要比较两个字符串是否相等,只要比较它们的checksum是否相等就可以了。我还可以去每个字符串的前128位得到子字符串。然后比较这两个子字符串。在我的程序中,我结合使用了这两个办法。当然这样做只能保证有很大的概率得到我想要的结果。但是考虑到我程序的具体应用环境,一个大概率正确(而不是绝对正确)的结果也是可以接受的。
class CManageStr{
public:
CManageStr():_latest_checksum(0){
}
~CManageStr(){
}
bool compare_with_clip();
update_from_new(const char* input);
{
sample(input,_latest_prefix,_latest_checksum);
}
private:
void sample(const char* input, char *prefix, unsigned long& checksum)
{ ...
}
private:
char _latest_prefix[128];
unsigned long _latest_checksum;
}