去除重复字母 给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小且不能打乱其他字符的相对位置(字典序即在英文字典中单词的排序规则) 示例: 输入:“bcabc” 输出:“abc”
输入:“cbacdcbc” 输出:“acdb”
思路: ①简单特殊情况判断,字符串为空; ②数组record记录字母出现的次数; ③利用字符栈stack(连续数组)存储去除重复字符的结果,利用栈来找到正确次序; ④遍历字符串,判断当前字符是否已经存入栈中,若已经存在,对record数组相应的位置进行’- -’, 表示栈里已经有这个字符没有必要重复存储; ⑤若不存在,通过while循环找到正确位置: ①. 栈不能为空; ②. 栈顶元素大于当前字符; ③. 栈顶字符对应的record的记录次数不能大于1. ⑥入栈。
char* removeDuplicateLetter(char *s) {
// boundary detect
if(s == NULL || strlen(s) == 0) return "";
if(strlen(s) == 1) return s;
// array to record the count of appearance of letters
char record[26] = {0};
int len = (int)strlen(s);
// stack
char* stack = malloc(len * sizeof(char));
int top = -1; // stack top pointer
// record the count for every char in the string
for(int i = 0; i < len; i++) {
record[s[i] - 'a']++;
}
// use stack to process the string to get the result
for(int i = 0; i < len; i++) {
//check is this char already inside the stack
int isExsisting = 0;
for(int j = 0; j < top; j++) {
if(s[i] == stack[j]) {
isExsisting = 1;
break;
}
}
if(isExsisting == 1) {
record[s[i] - 'a'] --;
} else {
while (top > -1 && stack[top] >= s[i] && record[stack[top] - 'a'] > 1) {
record[stack[top] - 'a'] --;
top --;
}
top ++;
stack[top] = s[i];
}
}
printf("the top pointer is %d\n", top);
return stack;
}
字符串匹配算法 题目:有一个主串S = {a, b, c, a, c, a, b, d, c}, 模式串T = {a, b, d}; 请找到模式串在主串中第一次出现的位置,字母均为小写;
①BF算法 暴力解法,一个一个的比较,算法容易理解但是效率低下
typedef char String[MAXSIZE+1];
/* 生成一个其值等于chars的串T */
Status StrAssign(String T,char *chars)
{
int i;
if(strlen(chars)>MAXSIZE)
return ERROR;
else
{
T[0]=strlen(chars); // the first element save the length of the string
for(i=1;i<=T[0];i++)
T[i]=*(chars+i-1);
return OK;
}
}
int Index_BF(String S, String T) {
// main string index
int i = 1;
// model string index
int j = 1;
while (i <= S[0] && j <= T[0]) {
if (S[i] == T[j]) {
i ++;
j ++;
} else {
i = i - j + 2;
j = 1;
}
}
if (j > T[0]) {
return i - T[0];
} else {
return -1;
}
}
②RK算法 求解主串的各个子串和模式串的哈希值,通过比较哈希值来找位置, 通过对比数字而不是对比字母来提高效率
int Index_RK(char* S, char* T) {
// hash value unit
int d = 26;
// the length of S and T
int m = (int)strlen(S);
int n = (int)strlen(T);
// get d^max
int maxD = 1;
for(int i = 0; i < n - 1; i++) {
maxD = maxD*d;
}
unsigned int A = 0; // hash value for T
unsigned int ST = 0; // hash value for subString of S
// get the hash value for T and first subString of S
for(int i = 0; i != n; i++) {
A = (d*A + (T[i] - 'a'));
ST = (d*ST + (S[i] - 'a'));
}
// compare has value of T and subString of S
for(int i = 0; i <= m-n; i++) {
if (A == ST) {
// in case of hash conflict, here we can check is the result correct before we return the index
return i;
} else {
ST = d * (ST - (S[i] - 'a') * maxD) + (S[i + n] - 'a');
}
}
return -1;
}