数据结构-串
2016-07-20 11:15
323 查看
字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。我们求整个字符串的排列,可以看成两步:首先求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换。第二步固定第一个字符,求后面所有字符的排列。这个时候我们仍把后面所有的字符分成两部分:后面字符的第一个字符,以及这个字符之后的所有字符串。然后把第一个字符逐一和他后面的字符交换。
全排列问题。可以参考: 全排列算法及实现
class Solution { public: vector<string> Permutation(string str) { vector<string> result; if (str.length() == 0 || str.length() > 9) { return result; } PermutationHelp(result, 0, str); return result; } void PermutationHelp(vector<string> &ans, int k, string str) // 遍历第k位所有的可能 { if (k == str.size()-1) { ans.push_back(str); } unordered_set<char> us; //记录出现的字符 sort(str.begin() + k,str.end()); // 遍历第k位的所有可能 for (int i = k; i <= str.size()-1; i++) { if (us.find(str[i]) == us.end()) { us.insert(str[i]); // 交换第k位数字 swap(str[i], str[k]); PermutationHelp(ans, k+1, str); // 返回 swap(str[k], str[i]); } } } };
翻转单词顺序列
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?解法1:
class Solution { public: string ReverseSentence(string str) { if (str.length() <= 1) { return str; } // 一个字符一个字符处理 string tmp = ""; string result = ""; for (int i = 0; i < str.length(); i++) { if (str[i] != ' ') { tmp += str[i]; }else{ // 遇到空格符 result = " " + tmp + result; // 置位 tmp = ""; } } if (tmp.length() > 0) { result = tmp + result; } return result; } };
解法2:
两次翻转,第一步翻转句子中所有的字符。比如翻转”I am a student.”中所有的字符得到”.tneduts a ma I”,此时不但翻转了句子中单词的顺序,连单词的字符顺序也被翻转了。第二步在翻转每个单词中字符的顺序,就得到了”student. a am I”。
class Solution { public: // 反转整个字符串 string Reverse(string str){ if (str.length() <= 1) { return str; } int startIndex = 0; int endIndex = str.length() - 1; while (startIndex < endIndex) { swap(str[startIndex], str[endIndex]); startIndex++; endIndex--; } return str; } string ReverseSentence(string str) { if (str.length() <= 1) { return str; } // 先翻转整个字符串 string resverStr = Reverse(str); // 一个字符一个字符处理 string tmp = ""; string result = ""; for (int i = 0; i < resverStr.length(); i++) { if (resverStr[i] != ' ') { tmp += resverStr[i]; }else{ // 遇到空格符 result = result + Reverse(tmp) + " "; // 置位 tmp = ""; } } if (tmp.length() > 0) { result = result + Reverse(tmp); } return result; } };
左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!以”abcdefg”为例,我们可以把它分为两部分。由于想把它的前两个字符移到后面,我们就把前两个字符分到第一部分,把后面的所有字符都分到第二部分。我们先分别翻转这两部分,于是就得到”bagfedc”。接下来我们再翻转整个字符串,得到的”cdefgab”刚好就是把原始字符串左旋转2位的结果。
class Solution { public: string LeftRotateString(string str, int n) { if (str.length() <= 1 || n > str.length() - 1) { return str; } int startIndex = 0; int endIndex = n - 1; // 先交换前一部分 while (startIndex < endIndex) { swap(str[startIndex], str[endIndex]); startIndex++; endIndex--; } // 再交换后一部分 startIndex = n; endIndex = str.length() - 1; while (startIndex < endIndex) { swap(str[startIndex], str[endIndex]); startIndex++; endIndex--; } // 最后再交换整个字符串 startIndex = 0; endIndex = str.length() - 1; while (startIndex < endIndex) { swap(str[startIndex], str[endIndex]); startIndex++; endIndex--; } return str; } };
把字符串转换成整数
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。主要考虑各种边界条件。
class Solution { // 1.数据上下 溢出 // 2.空字符串 // 3.只有正负号 // 4.有无正负号 // 5.错误标志输出 public: bool g_InvalidValue = false; int StrToInt(string str) { if (str.length() == 0) { g_InvalidValue = false; return 0; } int number = 0; int i = 0; if (str[0] == '+' || str[0] == '-') { // 允许存在+-号 i++; } for (; i < str.length(); i++) { if (str[i] > '0' && str[i] < '9' ) { number += (str[i] - '0')* pow(10, str.length() - 1 - i); }else{ g_InvalidValue = true; return 0; } } if (str[0] == '-') { number = -number; } return number; } };
表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100”,”5e2”,”-123”,”3.1416”和”-1E-16”都表示数值。 但是”12e”,”1a3.14”,”1.2.3”,”+-5”和”12e+4.3”都不是。class Solution { public: // 扫面字符串中的0到9的数位 void scanDigits(char** string) { while (**string != '\0' && **string >= '0' && **string <= '9') { ++(*string); } } // 用来匹配科学计数法表示的数值的结尾部分 bool isExponential(char** string) { // 判断首字符是不是e或E if (**string != 'e' && **string != 'E') { return false; } ++(*string); // 判断E后面是不是+号或者-号 if (**string == '+' || **string == '-') { ++(*string); } if (**string == '\0') { return false; } scanDigits(string); return (**string == '\0') ? true:false; } bool isNumeric(char* string) { if (string == NULL) { return false; } if (*string == '+' || *string == '-') { ++(string); } if (*string == '\0') { return false; } bool numeric = true; scanDigits(&string); if (*string != '\0') { // 判断是不是小数 if (*string == '.') { // 向后移一位 ++(string); // 继续扫描 scanDigits(&string); if (*string == 'e' || *string == 'E' ) { numeric = isExponential(&string); }else if (*string == '\0'){ numeric = true; }else{ numeric = false; } }else if (*string == 'e' || *string == 'E'){ // 是整数 numeric = isExponential(&string); }else{ numeric = false; } } return numeric; } };
正则表达式匹配
请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配class Solution { public: bool matchCore(char* str,char* pattern) { if (*str == '\0' && *pattern == '\0') { return true; } if (*str != '\0' && *pattern == '\0') { return false; } if (*(pattern+1) == '*') { if (*pattern == *str || (*pattern == '.' && *str != '\0') ) { // 字符串的第一个字符与模式中的第一个字符匹配 // 移动到下一个状态 return matchCore(str+1, pattern+2) // 保持当前状态 || matchCore(str+1, pattern) // 忽视'*' || matchCore(str, pattern + 2); }else{ return matchCore(str, pattern + 2); } } if (*str == *pattern || (*pattern == '.' && *str != '\0') ) { return matchCore(str+1, pattern+1); } return false; } bool match(char* str, char* pattern) { if (str == NULL || pattern == NULL) { return false; } return matchCore(str, pattern); } };
字符串中第一个不重复的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是”g”。当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符是”l”。用一个字典统计字符出现的次数。
class Solution { public: vector<char> vec; map<char, int> mapdata; void Insert(char ch) { vec.push_back(ch); mapdata[ch]++; } //return the first appearence once char in current stringstream char FirstAppearingOnce() { for (int i = 0; i < vec.size(); i++) { // 获取该元素的个数 if (mapdata[vec[i]] == 1) { return vec[i]; } } return '#'; } };
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)