1.1 字符串的旋转
题目描述:
将前部的字符子串整体移到字符串的尾部 (abcdef->defabc)
算法思想:
1、采用暴力的解法,每次移动一个字符到末尾,那么一次操作需要移动n个字符(n为字符串长度),若子串长度设为m,共需进行m*n次移位操作。则时间复杂度为O(mn),空间复杂度为O(1)
void LeftShiftOne(char *s, int n){ char first_word = s[0]; for(int i = 1; i < n; i++ ){ s[i-1] = s[i]; } s[n-1] = first_word; } void LeftRotateString(char *s, int m){ while(m--){ LeftShiftOne(s, 10); } }
2、新时代优秀青年肯定不能使用这种简单低效的解法。于是考虑先将需要移动的子串和剩余子串分别进行反转,再进行整体反转(三步反转法:1、分块 2、子串反转 3、整体反转)
void ReverseString(char*s, int from, int to){//字符串反转算法,切记不要将字符串拆开分别存在数组中,直接用字符指针操作字符串,方便快捷 char temp; while(from < to){ temp = s[from]; s[from++] = s[to]; s[to--] = temp; } }
int main(){ char text[] = "worldhello"; ReverseString(text, 0, 4); //三次反转操作 ReverseString(text, 5, 9); ReverseString(text, 0, 9); printf("%s", text); return 0; }
1.1.3 单词翻转
题目描述:
翻转句子中单词的顺序,要求单词内字符的顺序不变。例:输入“I am a student.”输出“student. a am I”
算法思想:
做字符串反转,先考虑子串反转,再考虑整个字符串反转。 反转函数要牢记。
void ReverseString(char*s, int from, int to){ char temp; while(from < to){ temp = s[from]; s[from++] = s[to]; s[to--] = temp; } }
int main(){ char text[] = "I am a student."; int from(0), to; for(int i = 0; i < 15; i++){ if(text[i] == ' '){ to = i-1; ReverseString(text, from, to); from = i+1; } } ReverseString(text, 0, 14); printf("%s", text); return 0; }
1.2 字符串的包含
题目描述:
给定长串a和短串b,请快速判断短串b中的字符是否都在长串a中
算法思想:
1、排序后轮询。先对a、b字符串进行排序,依次将b中的每个字符和a中的每个字符进行比较,如果不同,输出false,否则输出true
两次排序分别需要O(mlogm)+O(nlogn),线性扫描需要O(m+n)
bool StringContain(string &a, string &b){ sort(a.begin(), a.end()); sort(b.begin(), b.end()); int i,j = 0; for(; j < b.length(); ){ if(b[j] == a[i]) j++; else if(i < a.length()){ i++; } else return false; } return true; }
2、素数相乘。素数有一个特别的性质:只能被1和自身整除。用26个素数代表26个字母,进行a字符串的素数相乘操作,再将b字符串对应的素数作为除数,如果相除有余数,输出false,否则输出ture
bool StringContain(string &a, string &b){ const int p[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101}; int count_a= 1, temp; for(int i =0; i < a.length(); i++) count_a *= p[a[i]-'A']; for(int i = 0; i < b.length(); i++) if(count_a % p[b[i]-'A']) return false; return true; }
但是,素数相除极易导致整数溢出(超过long long),所以该方法看似可行,实则不可行
3、