一、有效的括号
判断一组括号序列是否闭合(一一对应)
思路:使用栈(先进后出)
public bool isValid(string s)
{
Deque<Character> stack = new LinkedList<Character>();
for(char c: s.toCCahrArry())
{
//入栈--直接插入对应的结构,可以免去后期判断
if(c == '(')
stack.push(')');
else if(c =='{')
stack.push('}')
else if(c =='[')
stack.push(']')
//出栈并进行匹配
else if(stack.isEmpty() || stack.pop()!=c)
return false;
}
return stack.isEmpty();
}
二、字符串相加
将两个非负数字符串相加(不能将其转换为数字)<但是可以将单个位上的数字转换为int型>
思路:将其按位相加(必须从低位到高位逆序相加)
public string addString(string num1,string num2)
{
StringBuilder sb = new StringBuilder();
int carry = 0;
for(int i=num1.length()-1,j=num2.lenght()-1; i>=0||j>=0||carry==1; i--,j--)
{
int x = i<0? 0:num1.charAt(i)-'0';
int y = i<0? 0:num2.charAt(j)-'0';
sb.append((x+y+carry)%10);
carry = (x+y+carry)/10;
}
return sb.reverse().toString();
}
三、字符串匹配
检查字符串中是否存在某段特定的字符串
1.BF算法
思路:将被检字符串后移直到对齐母串中对应的序列
//关键代码如下
for(int i=sourceOffset+fromIndex;i<=max;i++)
{
if(source[i]!=first)
while(++i<=max && source[i]!=first); //未找到第一个对齐字母
if(i<=max) //找到第一个对齐字母,检测下面的是否对齐
{
int j = i+1;
int end = j+targetCount - 1;
for(int k=targetOffset + 1; j<end && source[j]==target[k];j++,k++)
if(j==end)
return i-sourceOffset //完成全段匹配
}
}
return -1;//未找到指定字符串
2.BM算法
利用匹配失败的信息尽可能多的排除无法匹配的内容
思路:从尾部开始对齐。
①若无法对齐且此字符并未出现则将前面的字符串视为“坏字符”,从而下次将直接跳过该段字符(表现为头移动到此字符的后一位)
②若无法对齐且此字符在序列中出过现则将前面的字符串视为“好后缀”,从而下次将直接将此字符与其在被匹配字符串中出现的位置对齐
整体可以总结为: 坏字符的位置 - 模式串中上次出现的位置(为-1)
好后缀的位置 - 模式串中上次出现的位置
③移动时综合坏字符和好后缀的移动距离,取其中移动距离大的那一个
3.KMP算法
改进的BM算法(从开头进行匹配),区别在于遇到部分匹配的情况需要结合部分匹配值进行移动
移动位数 = 已匹配字符数 - 对应的部分匹配值
部分匹配值表为前缀和后缀共有元素的长度