Below is a problem I encountered during an online course. There are a lot of similar questions asked on this, but I couldn't find a solution there as well as I believe my specific issue is a bit different from the rest.
Given a string
s
, find the first non-repeating character in the string If there is no such character print ‘@’. You are required to complete the functionInput Format: String s
Output Format: First non-repeating character or @
You are supposed to implement
char char FirstNonRepeatedchar(char* str, int len)
: which takes a pointer to input string str and length of the string(including ‘\0’). The function should return either the first non repeating character or ‘@’Input Constraint: All input characters will be either lower or upper case english alphabets.
str[i] [a,z][A,Z]
There will not be any space in the input string.
/************ Prefix Code Begins*******************/
#include <iostream>
#include <string>
using namespace std;
//function finds the first non-repeating character
char FirstNonRepeatedchar(const char* , int);
int main(){
int len;
string line;
getline (cin, line);
len = int(line.length());
cout << FirstNonRepeatedchar(line.c_str(), len);
return 0;
}
/******************* Prefix Code Ends******************/
Also, note I cannot change anything in the prefix code above. I wrote 2 solutions: first one below is giving correct output.
char FirstNonRepeatedchar(const char* str, int len){
int count[26]={0};
for(int i=0;i<len;i++)
{
count[*(str+i)]++;
}
for(int i=0;i<len;i++)
{
if(count[*(str+i)]==1)
return *(str+i);
}
return '@';
}
The above solution iterates the string twice. So, I tried to improve the complexity by implementing it using a hash.
char FirstNonRepeatedchar(const char* str, int len){
int count[26]={0};
int j;
char c;
if(isupper(*str)==1)
{ c='A';
}
else
c='a';
for(int i=0;i<len;i++)
{ j=*(str+i)-c;
if(count[j]<0)
;
else if(count[j]==0)
count[j]=i+1;
else if(count[j]>0)
count[j]=-i;
}
int min=len+1;
for(int i=0;i<26;i++)
{
if(count[i]>0 && count[i]<min)
min=count[i];
}
if(min==len+1)
return '@';
else
return *(str+min-1);
}
Is the second solution I gave the most optimized solution possible for this problem?
count
is uninitialised. In your second implementation, upper case letters cause array access out of bounds. Please ensure your code is working before asking for review. \$\endgroup\$toupper()
ortolower()
would fix it though. \$\endgroup\$count
. You need to usemalloc
ornew
, or just use an array. \$\endgroup\$