我一直在尝试实现一种有效的字符串比较算法,该算法将根据字符变化给出点数。
例如:
String #1: abcd
String #2: acdb
Initial Point: 0
此处字符串#2字符c
将其索引从2更改为1,并且d将其索引从4更改为3.其中两个(2-1=1
和4-3=1
)相加到2点到初始点。不是家庭作业或任何东西,我只是不想创建一个基本的for循环逐个比较每个字符,并想问是否可以应用任何有效的方法(如散列等)?
答案 0 :(得分:2)
你过于复杂化了一件简单的事情。你不能比比较每个角色和在你发现不同的第一个角色停止比较时更有效率 - 这基本上是strcmp
的作用。您可以做的唯一典型优化是,如果您已经知道两个字符串的长度(当您使用std::string
或其他计数字符串时发生),如果两个长度不同,则立即确定它们不相等。
答案 1 :(得分:1)
这听起来像你真正想要的是Levenshtein距离(但不完全是这样)。 这是第一次削减。
它的作用是在游戏树中浏览 a 的所有可能重新排列,看它们是否匹配 b 。 它将成本与每次重新安排相关联,表示为下降的预算。
外部循环首先以预算0开始,因此只允许完全匹配。
如果没有成功,那么它的预算为1,发现所有匹配只包含一次重排。
如果没有成功,那么它的预算为2,依此类推。
在匹配时,它会保留一个整数数组 delta ,告诉 a 的每个元素已被交换了多远。 每当它获得成功时,它就会打印出那个delta数组,这就是你为了获得那场比赛所做的掉期记录。
void walk(char* a, char* b, int* delta, int budget, int& nSuccess){
delta[0] = 0;
if (budget < 0) return;
if (a[0] == '\0' && b[0] == '\0'){ // end of both strings
nSuccess++;
// print out the deltas
return;
}
if (a[0] == '\0') return; // excess chars in b
if (b[0] == '\0') return; // excess chars in a
if (a[0] == b[0]){ // first chars are equal, move to next
walk(a+1, b+1, delta+1, budget, nSuccess);
return;
}
for (int i = 1; a[i] != '\0'; i++){
delta[0] = i;
swap(a[0], a[i]);
if (a[0] == b[0]){
walk(a+1, b+1, delta+1, budget-1, nSuccess);
}
swap(a[0], a[i]);
delta[0] = 0;
}
}
void top(char* a, char* b){
int nSuccess = 0;
int delta[512];
for (int budget = 0; nSuccess==0; budget++){
walk(a, b, budget, delta, nSuccess);
}
}
算法的性能在N中是指数的,其中N是使字符串匹配所需的最小重排次数。 因此,在您确认每个字符串的每个字符数相同之后,可能不应该使用它, 并且只有在需要查看重新排列记录时才使用它。