I am trying to write a c++ program to find the first non-repeated character and if all the characters are repeated it would return -1.
I have designed a solution that keeps track of the count of characters using a integer array which I index using the respective character whose count has to be stored.
Program 1:
Gives erroneous output...
http://ide.geeksforgeeks.org/wxOYog
#include<iostream>
#include<cstring>
using namespace std;
int map[256];
string returnFirstRepeatingChar(string str,int n)
{
int i=0,flag=1;
string result;
for(i=0;i<n;i++)
map[str[i]]++;
for(i=0;i<n;i++)
{
if(map[str[i]]==1)
{
flag=0;
result = str[i];
break;
}
}
if(flag)
return "-1";
else
return result;
}
int main()
{
//code
int t,N,*arr,i,j;
cin>>t;
string str;
while(t--)
{
cin>>N;
memset(&map,0,256);
cin>>str;
cout<<returnFirstRepeatingChar(str,N)<<endl;
}
return 0;
}
Program 2:
Gives correct output...
http://ide.geeksforgeeks.org/jJvJPu
#include<iostream>
#include<cstring>
using namespace std;
int map[256];
string returnFirstRepeatingChar(string str,int n)
{
int i=0,flag=1;
string result;
for(i=0;i<n;i++)
map[str[i]-97]++; //changed from above program
for(i=0;i<n;i++)
{
if(map[str[i]-97]==1) //changed from above program
{
flag=0;
result = str[i];
break;
}
}
if(flag)
return "-1";
else
return result;
}
int main()
{
//code
int t,N,*arr,i,j;
cin>>t;
string str;
while(t--)
{
cin>>N;
memset(&map,0,256);
cin>>str;
cout<<returnFirstRepeatingChar(str,N)<<endl;
}
return 0;
}
Only difference between the two programs is location of required counts in the array map..
In the program 1, it starts from 97 (ascii of a)
In the program 2, it starts from 0.
But program 2 gives correct output, but the program 1 isn't. Why?
Eg: for input: abcdefghij
program 1 output: f
program 2 output: a
One important issue here is this line:
memset(&map,0,256);
Here you are zeroing only the first 256/sizeof(int). In case the sizeof(int) is 4, this makes the first 64 int.
However, your program is using the elements which index is greater than 97, hence the issue appearing.
Hence it should be
memset(&map,0,256*sizeof(int));
or could be also simply written as
memset(map,0,sizeof(map));
Remember: the 3rd parameter of memset is "the number of bytes to fill", not "the number of elements of your array"
Related
I have given an array and I need to find is there any duplicate element present in array or not? (I have to take input from the user.)
This is my first code which is giving the wrong answer for some test cases:
#include<bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
unordered_map<int,int> mp;
int temp=1;
for(int i=0,i<n;i++)
{
int x; cin>>x;
if(mp.find(x)!=mp.end())
{
temp=-1; break;
}
mp[x]++;
}
if(temp==-1) cout<<"YES"<<endl; //if duplicate present
else cout<<"NO"<<endl;
mp.clear();
}
return 0;
}
And this code is running perfectly on all the test cases:
#include<bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
unordered_map<int,int> mp;
int temp=1;
for(int i=0,i<n;i++)
{
int x;
cin>>x;
mp[x]++;
}
if(mp.size()<n) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
mp.clear();
}
return 0;
}
what is the reason behind it?
You used break; in the first code, but didn't use that in the second code.
Using break; will prevent the code from reading part of test case and treat that as next text case, and it will lead to Wrong Answer.
For example, using this input
2
5 5 5 1 2 3
2 2 2
Your first code will print
YES
NO
while the correct output is
YES
YES
To prevent this, the break; should be removed.
#include <bits/stdc++.h>
using namespace std;
string bin(int n){
string x="";
while(n!=0)
{
int z=n%2;
x+=to_string(z);
n%=2;
}
return x;
}
int main(){
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
{
cin>>a[i];
string x=bin(a[i]);
int u=x.size();
int cnt=0;
for(int g=0;g<u;g++)
{
if(x[g]=='1')
++cnt;
}
cout<<cnt<<' ';
}
cout<<'\n';
}
}
This code is given several test cases and each test case will have an array of n integers, for each element in the array I should count the number of ones in the binary representation of it. I wrote a function that expects an integer and returns a string containing the binary representation of it. But I wonder why my code does not end, and not allowing me to receive other numbers in array.
For instance, there's one test case and and only array of 2 integers if I inputted 1 and wait for ever to enter the second number, what's happening?
This is your bin function reduced to the bare minimum:
string bin(int n){
while(n!=0)
{
n%=2;
}
return {};
}
If n is even you will set it to 0 on the first iteration, otherwise you set it to 1 and never change it afterwards (1%2==1). Hence you have a endless loop. I won't spoil you the "fun" of completing the exercise, so I will just point you to using a debugger. If you step trough your code line by line you could have observed how n never changes and why the loop wont stop.
PS: (spoiler-alert) you might want to take a look at std::bitset (end of spoiler)
In the following code we have to first calculate the weights of uniform substrings present in our strings . Uniform sub strings are those which contain just one character like "a" or "aaa". The weight of the character is defined as a-1 b-2......z-26.
After calculating the weights of all the valid uniform substrings we will be given with various queries and we have to check whether the given no. is the array or not.
Here is the link of the code and corresponding output to it:
https://www.ideone.com/pIBPtQ
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
int i=0,j=0,k=0;
int arr[10000];
int c=0;
while(s[i]!='\0')
{
int x=(int)s[i];
x=x-96;
arr[c++]=x;
j=i+1;
int sum=x;
while(s[j]==s[i])
{
sum+=x;
arr[c++]=sum;
j++;
}
i=j;
}
int q;
cin>>q;
for(i=0;i<q;i++)
{
int val;
cin>>val;
bool exists=find(begin(arr),end(arr),val)!=end(arr);
if(exists==true)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
cout<<"the elements of the array are:"<<endl;
for(i=0;i<c;i++)
cout<<arr[i]<<" ";
return 0;
}
You forgot to initialize arr.
Change
int arr[1000];
to
int arr[1000] = {0};
https://www.ideone.com/wIj4vp
Also x=x-96; should be better written as x -= 'a';.
#include <iostream>
using namespace std;
int main(){
string s,str;
cin>>s;
int a[26]={0};
for(int i=0;i<26;i++){
int x=(int)s[i]-97;
if(a[x]==0){
a[x]++;
str+=s[i];
}
}
cout<<str<<endl;
return 0;
}
Input : geeksforgeeks
Ouput:geksfor
�
This is where i am getting some extra characters as ouput why i am getting like that?
Can anyone help me ?
Thanks in advance.
Your loop runs with i in range [0, 26), where i is indexing s, regardless of the length of s (and in this case, s is much shorter than 26 character long). Eventually, you index outside the bounds of s (invoking undefined behavior) and start processing gibberish, and your code starts pushing unique gibberish onto your result string. If you can assume your inputs are always lowercase ASCII, you could iterate with i in range [0, s.size()) (or use C++11 for-each style looping without indexing at all), but short-circuit out if str reaches a length of 26 (because all 26 unique characters have been seen).
One approach:
int main(){
string s,str;
cin>>s;
int a[26]={0};
for(auto c : s){
int x = c-97;
if (a[x] == 0) {
a[x]++;
str += c;
if (str.size() == 26) break;
}
}
cout<<str<<endl;
return 0;
}
I think you have consider the input string in lower case letters.
But one mistake you have done in the code is that you are iterating the for loop for only 26 times.
But lets consider the string such that the letters are repeated after 26th character. There only your code fails. So, you just have to iterate through the whole string.
The correct code is:
#include<iostream>
using namespace std;
int main()
{
string s,str;
cin>>s;
int a[26]={0};
for(int i=0;i<s.size();i++)
{
int x=(int)s[i]-97;
if(a[x]==0)
{
a[x]++;
str+=s[i];
}
}
cout<<str;
return 0;
}
I have to implement c++ code to find out the number of occurrences of a small string in a large string with overlapping allowed. For eg- if large string is acacab and small string is aca, then answer should be 2.
I'm not getting correct answer by making this code:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int i, j, k, c=0;
char lstr[30],sstr[10],tstr[10];
cout<<"Enter large string:"<<endl;
cin>>lstr;
cout<<"Enter small string:"<<endl;
cin>>sstr;
for(i=0;i<strlen(lstr);i++)
{
if(lstr[i]==sstr[0])
{
j=i;
for(k=0;k<strlen(sstr);k++,j++)
{
tstr[k]=lstr[j];
}
}
if(strcmp(tstr,sstr)==0)
c++;
}
cout<<c;
return 0;
}
It's much easier if you use C++ strings instead of C ones:
int c=0;
string lstr, sstr;
cout<<"Enter large string:"<<endl;
cin>>lstr;
cout<<"Enter small string:"<<endl;
cin>>sstr;
for (size_t pos = 0;
(pos = lstr.find(sstr, pos)) != string::npos;
pos++)
{
c++;
}
cout<<c;
This should work, add a '\0' to terminate c-style string, and move if(strcmp(tstr,sstr)==0) in the if(lstr[i]==sstr[0]) statement(otherwise you will continuing increment c when lstr[i] != sstr[0]):
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int i, j, k, c=0;
char lstr[30],sstr[10],tstr[10];
cout<<"Enter large string:"<<endl;
cin>>lstr;
cout<<"Enter small string:"<<endl;
cin>>sstr;
for(i=0;i<strlen(lstr);i++)
{
if(lstr[i]==sstr[0])
{
j=i;
for(k=0;k<strlen(sstr) && j<strlen(lstr);k++,j++)
{
tstr[k]=lstr[j];
}
tstr[k] = 0;
// ^^^^^^^^^^^^
if(strcmp(tstr,sstr)==0)
c++;
}
}
cout<<c;
return 0;
}
This will solve your problem more efficiently in O(n*m) complexity, where n is large string size and m is small string size.
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int i, j, k, c=0;
char lstr[30],sstr[10];
cout<<"Enter large string:"<<endl;
cin>>lstr;
cout<<"Enter small string:"<<endl;
cin>>sstr;
for(i=0; lstr[i]; i++) // You don't need to calculate strlen each time. This loop will break when lstr reaches null ('\0') character
{
if(lstr[i]==sstr[0])
{
for(k=0,j=i; sstr[k] && lstr[j]; k++,j++) // don't need to calculate strlen each time
{
if(sstr[k]!=lstr[j]) // Break if not match
break;
}
if(k==strlen(sstr)) // Whole string matched
c++;
}
}
cout<<c<<"\n";
return 0;
}
If you want to solve this problem in O(n) complexity you can use KMP algorithm. Which is the best choice for this kind of problems.