题目描述:请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"
class Solution { public: void Insert(char ch) { s += ch; hash[ch]++; } char FirstAppearingOnce() { for (int i = 0; i < s.size();i++) { if (hash[s[i]] == 1) return s[i]; } return '#'; } private: string s; char hash[256] = { 0 }; }
题目分析:
字符串流键入,在插入函数处,我们将字符串连接起来形成字符串,由于字符串值不超过256,所以将hash表设为256长度的数组,我们想要找出第一个非重复的字符,重复的必然hash[ch]==2,所以非重复的只要判断条件为1即可。
下面再看一个常见的算法题,数学中常用的全排列,我思考了两天时间,发现自己真是蠢,把结果输出一下就能弄懂别人代码的思路了,吸取教训,下面看题:
题目描述:
输入一个字符串,打印出该字符串的全排列,例如,输入“abc”,则得到abc,acb,bac,bca,cba,cab六种结果,其实往更深层次考虑还有重复的情况,我们首先考虑不重复的情况,全排列算法
题目分析:
首先按数学的思路,我们固定第一个字符a,然后求后面的bc有几种全排列,我们发现这就是一个递归问题,但是我们希望得到全部的全排列,因此我们每轮需要把首字符换成字符中的一个值,这里我们用一个循环可以解决。
#include <iostream> using namespace std; int sum = 0;//记录有多少种组合 void Swap(char str[], int a, int b) { char temp = str[a]; str[a] = str[b]; str[b] = temp; } void Perm(char str[], int begin, int end) { if (begin == end) { for (int i = 0; i <= end; i++) { cout << str[i]; } cout << endl; sum++; } else { for (int j = begin; j <= end; j++) { //cout << "swap(" << str << "," << begin << "," << j << ")" << endl; Swap(str, begin, j); //cout << "perm(" << str << "," << begin+1 << "," << end << ")" << endl; Perm(str, begin + 1, end); //cout << "swap(" << str << "," << j << "," << begin << ")" << endl; Swap(str, j, begin); } } } int main() { int n; char c[16]; char tmp; cin >> n; tmp = getchar(); // 接受回车 if (1 <= n && n <= 15) { for (int i = 0; i < n; i++) { c[i] = getchar(); } Perm(c, 0, n - 1); } cout << sum; cout << endl; return 0; }