面试题:2012民生银行总行笔试题
今天下午参加民生银行总行的笔试,最后一个题是一个小的算法题。
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。并且要求是用两种方法。
在网上搜索了一下,网上说这是2006年google的面试题。
方法1:
最简单,容易想到的就是双循环的那种,从前往后进行遍历,这种的复杂度是O(n^2)
简单的C++代码如下:
bool method1(const string& s,char& c){
int len=s.size();
int i;
vector<bool> flag(len);
for(int i=0;i<len;i++)
flag[i]=true;
for(i=0;i<len-1;i++){
if(flag[i]){
int j;
for(j=i+1;j<len;j++){
if(s[j]==s[i]) {
flag[j]=false;
break;
}
}
if(j==len) {
c=s[i];
return true;
}
}
flag[i]=false;
}
if(i==len-1)
return false;
}
int len=s.size();
int i;
vector<bool> flag(len);
for(int i=0;i<len;i++)
flag[i]=true;
for(i=0;i<len-1;i++){
if(flag[i]){
int j;
for(j=i+1;j<len;j++){
if(s[j]==s[i]) {
flag[j]=false;
break;
}
}
if(j==len) {
c=s[i];
return true;
}
}
flag[i]=false;
}
if(i==len-1)
return false;
}
这儿需要注意的是需要用一个数组记录哪个字符已经出现过,这个非常重要,不然,如果前面已经出现过而后面没有出现过的字符有可能错认为是第一次出现。
比如,对于字符串”afadrrwsof“,如果不记录哪个字符出现过的话,会错认为第二个a是第一次出现
方法二:
因为是字符串,所以共有256个字符,可以使用一个256大小的数组来记录字符出现的个数。
其实这个方法很简单的。但是我想的有点复杂了,我想同时用一个数组记录256个字符第一次出现的位置,然后从第一次出现的字符中找到最先出现的字符。其实没有必要,只需要再将字符串扫描一遍就可以了,方法三就是这样实现的。
bool method2(string& s,char& c){
const int N=256;
int pos[N];
int count[N];
for(int i=0;i<N;i++){
pos[i]=-1;
count[i]=0;
}
int len=s.size();
for(int i=0;i<len;i++){
int t=static_cast<int>(s[i]);
if(pos[t]==-1){
pos[t]=i;
}
count[t]++;
}
int minp=len;
int position=-1;
for(int i=0;i<N;i++){
if(count[i]==1&&minp>pos[i]){
position=i;
minp=pos[i];
}
}
if(position!=-1){
c=s[minp];
return true;
}
else
return false;
}
const int N=256;
int pos[N];
int count[N];
for(int i=0;i<N;i++){
pos[i]=-1;
count[i]=0;
}
int len=s.size();
for(int i=0;i<len;i++){
int t=static_cast<int>(s[i]);
if(pos[t]==-1){
pos[t]=i;
}
count[t]++;
}
int minp=len;
int position=-1;
for(int i=0;i<N;i++){
if(count[i]==1&&minp>pos[i]){
position=i;
minp=pos[i];
}
}
if(position!=-1){
c=s[minp];
return true;
}
else
return false;
}
方法三:
bool method3(const string& s,char& c){
const int N=256;
int len=s.size();
int count[N];
for(int i=0;i<N;i++)
count[i]=0;
for(int i=0;i<len;i++) {
int t=static_cast<int>(s[i]);
count[t]++;
}
for(int i=0;i<len;i++){
int t=static_cast<int>(s[i]);
if(count[t]==1)
{
c=s[i];
return true;
}
}
return false;
}
const int N=256;
int len=s.size();
int count[N];
for(int i=0;i<N;i++)
count[i]=0;
for(int i=0;i<len;i++) {
int t=static_cast<int>(s[i]);
count[t]++;
}
for(int i=0;i<len;i++){
int t=static_cast<int>(s[i]);
if(count[t]==1)
{
c=s[i];
return true;
}
}
return false;
}
下面是对三个方法进行测试: 主要是随机生成30个字符串,对这些字符串进行测试。
int main(){
const string alpha="abcdefghigklmnopqrstuvwxyz";
const int n=10;
string s(n,' ');
for(int j=0;j<30;j++) {
for(int i=0;i<n;i++) {
int pos=rand()%26;
s[i]=alpha[pos];
}
char c1=-1,c2=-1,c3=-1;
cout<<"s="<<s<<" ";
method1(s,c1);
cout<<c1<<" ";
method2(s,c2);
cout<<c2<<" ";
method3(s,c3);
cout<<c3<<" ";
cout<<endl;
}
}
const string alpha="abcdefghigklmnopqrstuvwxyz";
const int n=10;
string s(n,' ');
for(int j=0;j<30;j++) {
for(int i=0;i<n;i++) {
int pos=rand()%26;
s[i]=alpha[pos];
}
char c1=-1,c2=-1,c3=-1;
cout<<"s="<<s<<" ";
method1(s,c1);
cout<<c1<<" ";
method2(s,c2);
cout<<c2<<" ";
method3(s,c3);
cout<<c3<<" ";
cout<<endl;
}
}
下面是运行的结果: