前缀算法

前缀算法能够从一个给定数据空间中找出其前缀特征,即前缀集合。前缀集合具有确定性,能够匹配该前缀集合的数据一定属于该数据空间,否则将一定不属于该数据空间。这样,对一个数据空间的描述既可以利用上下边界来表示,也可以使用该数据空间的前缀特征来表示。

算法1给出了计算给定区间前缀集合算法的伪代码。算法的输入是n位二进制数区间的起始值a1a2...an和结束值b1b2...bn,二进制数的左边是高位,右边是低位,输出是该二进制区间的前缀集合。该算法是一个递归算法,首先,找到二进制区间的起始值和结束值的关键位,即从左到右数第一个不相等的比特位,如果没有找到关键位,则说明该二进制区间的上下边界是重合的,它的前缀特征就是该重合的点;然后,如果起始值的关键位k右边的各位都是0,而且结束值的关键位k右边的各位都是1,则该二进制区间的前缀就是关键位k之前的相似部分;接着,如果前两个条件都不满足,则将起始值和结束值的关键位右边的各位分别作为新的边界输入,递归调用前缀算法去分别计算两个子空间的前缀特征;最后,将子空间的前缀特征与关键位k左边的相似位进行整合,返回二进制区间的前缀集合。


#include <iostream>
#include <vector>
using namespace std;
vector<char *> Search_Prefix(char *begin,char *end)
{
vector<char *> vec;
int len=strlen(begin);
char *tmp;
tmp=new char[len+1];
memset(tmp,'*',len);
tmp[len]='\0';
int k=0;
for (;k<len&&begin[k]==end[k];k++)
{
tmp[k]=begin[k];
}
if (k==len) {
vec.push_back(begin);
return vec;
};
bool bTrue=true;
for (int l=k;l<len;l++)
{
if(!(begin[l]=='0'&&end[l]=='1'))
{
bTrue=false;
}
}
if (bTrue)
{
/* 可取消注释,则11** 返回11* */
// if (k==0)
// {
// vec.push_back("*");
// return vec;
// }
vec.push_back(tmp);
return vec;

}
char *nBegin;
char *nEnd;
int offset=k+1;
int lef=len-offset;
nBegin=new char[lef+1];
nEnd=new char[lef+1];
memset(nBegin,'0',lef);
memset(nEnd,'1',lef);
nBegin[lef]='\0';
nEnd[lef]='\0';
vector<char *> Set_PrefixA=Search_Prefix(begin+offset,nEnd);
vector<char *>Set_PrefixB=Search_Prefix(nBegin,end+offset);
int i=0;
char *Atmp;

for (i=0;i<Set_PrefixA .size();i++)
{
Atmp=new char[len+1];
memset(Atmp,0,len);
Atmp[len]='\0';
strncpy(Atmp,tmp,k);
strcat(Atmp,"0");
strcat(Atmp,Set_PrefixA.at(i));
vec.push_back(Atmp);
}
for (i=0;i<Set_PrefixB.size();i++)
{
Atmp=new char[len+1];
memset(Atmp,0,len);
Atmp[len]='\0';
strncpy(Atmp,tmp,k);
strcat(Atmp,"1");
strcat(Atmp,Set_PrefixB.at(i));
vec.push_back(Atmp);
}
return vec;
}

int main()
{

vector<char *> vec;
vec=Search_Prefix("1101100101","1110100110");
cout<<endl<<"[1101100101,1110100110]"<<endl;
for (int i=0;i<vec.size();i++)
{
cout<<vec.at(i)<<endl;
}
return 0;
}

<think>我们来实现一个寻找字符串数组中最长公共前缀的函数。 基本思路:纵向扫描,从第一个字符开始,依次比较所有字符串的同一位置的字符,直到出现不匹配或某个字符串结束。 例如:输入["flower","flow","flight"],输出"fl" 另一种思路:先找到最短的字符串,然后依次比较每个字符。 这里我们采用纵向扫描的方法。 步骤: 1. 如果输入列表为空,则返回空字符串。 2. 以第一个字符串为基准,遍历其每个字符。 3. 对于第一个字符串的每个位置i,检查其他字符串在位置i的字符是否相同。 4. 如果遇到某个字符串长度不足i,或者字符不相同,则返回当前已经匹配的前缀。 5. 如果都相同,则将当前字符加入公共前缀。 代码实现如下: </think>### Python 最长公共前缀算法 最长公共前缀(Longest Common Prefix)指字符串数组中所有字符串共有的最长前缀子串。以下是高效实现及解析: ```python def longestCommonPrefix(strs): if not strs: # 空数组处理 return "" # 以字典序最小和最大的字符串作为基准(因公共前缀必然存在于二者之间) min_str = min(strs) max_str = max(strs) # 遍历最小字符串的每个字符 for i, char in enumerate(min_str): if char != max_str[i]: # 遇到首个差异字符时终止 return min_str[:i] return min_str # 最小字符串本身为公共前缀 # 测试示例 print(longestCommonPrefix(["flower", "flow", "flight"])) # 输出 "fl" print(longestCommonPrefix(["dog", "racecar", "car"])) # 输出 "" ``` #### 算法解析: 1. **边界处理**:若输入为空列表,直接返回空字符串。 2. **字典序原理**:`min()`和`max()`按字典序排序,数组的公共前缀必是字典序最小和最大字符串的公共前缀。 3. **字符比对**:逐个比较最小字符串与最大字符串的字符,首处差异位置即为前缀终止点。 4. **时间复杂度**:O(n*m),其中n是字符串数量,m是平均长度(实际因`min/max`和单次遍历,效率较高)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值