Printing the first character in a given string which does not repeat - c++

I am using the following function in c++ to return the first character in a given string which does not repeat,if not found return '#'.
char MyMethod(const char* str, int len){
int i,index=-1;
int *count = new int[256];
for(i=0;i<len;i++)
{
count[*(str+i)]=0;
}
for(i=0;i<len;i++)
{
count[*(str+i)]++;
}
for(i=0;i<len;i++)
{
if(count[*(str+i)]==1)
{
index=i;
break;
}
}
if(index==-1)
return '#';
else
return *(str+index);
}
this method looks fine, but it is always returning the first character of the string.
for example for the following string
aabcdd
it returns 'a' instead of 'b'.

I believe there has been a typo.
The statement :
if(count[*(str+i)]==1);
should not have been terminated:
if(count[*(str+i)]==1)
Remove the semicolon, so that the statements after the if condition are evaluated only when the condition is true.
Otherwise, the statements will be evaluated whatever be the result of if.

Related

Why does cal function always return true value?

When input is pos expecting that cal function return false. But cal function alaways return true.
#include <bits/stdc++.h>
using namespace std;
bool cal(string s)
{
int l=s.size();
if(l==1)
return false;
int l2=l/2;
if(l%2==0)
{
string s1=s.substr (0,l2);
string s2=s.substr(l2,l2);
if(s1==s2)
return true;
cal(s1);
cal(s2);
}
else
{
string s1=s.substr (0,l2);
string s2=s.substr(l2+1,l2);
if(s1==s2)
return true;
cal(s1);
cal(s2);
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
bool a;
a=cal(s);
if(a==true)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
In two of your logic paths, you call cal(s1) and discard the value, then call cal(s2) and similarly ignore the return value. Thus, what you return is something you did not explicitly order; I expect that it's the incidental value of cal(s2).
What did you intend for those branches where s1 != s2 ?
I'm not sure what you're trying to do; the stunted variable names and lack of comments leave us guessing about your intended action. Why should pos (whatever you mean by that) input return false?
Also, there may be a logic error in your code. It appears that you're trying to split a string in half; do you intend to lose the middle character of an odd-length string?
string s1=s.substr (0,l2);
string s2=s.substr(l2+1,l2);

checking for letters in a string of ints

bool isInt(string input) { //checks if string input is an int
if (input[0] == '-') { //checks if negative number
for (int a = 1; a < input.length(); a++) {
if (isdigit(input[a])) {
return true;
}
else {
return false;
}
}
}
for (int b = 0; b < input.length(); b++) {
if (isdigit(input[b])) {
return true;
} else {
return false;
}
}
}
So my code here is to check the string input the user enters and sees if its an integer. It works except cases where if the first character is either - or a number, but if thats followed by characters such as -23ab or -4b, my program won't catch that as an error as it isn't a valid number. I know the error is due to my return true/false statements, but I don't know of any method of how to fix it.
Any ideas?
It doesn't work at all!!
It only cares about the first character in the string because you return no matter the state of the character. You need to store a result in a variable and continue searching until the first failure.
You are returning true as soon as you see 1 digit. You should return true only if you make it to the end of the string w/o an error. You can return false early but for this problem, you should only return true at the end.
As others here said, you're only checking the first character and returning whether the first character is a digit or not....what you'll want to do instead is check if the character is a digit....if so then continue you on to the next digit. The only reason you'll return is if you either went through all the characters or if you found a non digit character.
for each character
if character is a digit
do nothing
else
return that it is false.
return true //you will only get to this statement if all characters are digits
This is what you have...
for each character
if character is a digit
return true
else
return false
So its basically returning before it checks the rest of the characters
Your code is trying too hard. You're testing for both success and failure rather than just looking for a fail case.
The following code takes a position index of 0, if the string isn't empty, it checks for a leading '-' and increments the index position to 1 if it finds that.
Then it simply checks through the string for a non-numeric character and fails if it finds one.
If it reaches the end of the string, then the string is all numeric.
bool isInt(const std::string& in)
{
size_t pos = 0;
if (!in.empty() && in[0] == '-')
pos = 1;
if (pos >= in.size()) // catch "" and "-"
return false;
do {
if (!isdigit(in[pos]))
return false;
} while (++pos < in.length());
return true;
}
This resolves your current problem but there is possible problem still: Is the string "123456789123456789" an int? It's too big to store in an int.

How return position of pointer in function of searching substrings in strings?

Help please how to finish function.
I got exersize for develop function for searching substring in string and return first position of enter.
That is code what i made:
int strstr(const char *str, const char *pattern) {
const char *st = str; // assign adress of string to pointer
const char *pa = pattern; //assign adress of pattern what we must find in string to pointer
while (*st){ // starting sort out string
++st;
if( *st == *pa){ //when first symbol of pattern equal to symbol of string starting the loop
int i = 0; //counter of iteration for possibility to return first enter of substring
for(i;*st == *pa;i++){ //that loop sort out every next symbol of string and pattern for equality
++st;
++pa;
} //loop finish when pattern or string was ended, or any next symbol was not equal
if(*pa == 0){ //if patter was ended return position of first enter
return st-i; //there not compiling((
}
pa-i; //reset pattern
st-i; //reset string
}
}
return -1; //return -1, if substring was not find
}
For hard luck that code not compiling... Error is invalid conversion from ‘const char*’ to ‘int’
What type must be variable i for that? And check my logic please)
return st-i; //there not compiling((
You are returning a pointer to a constant char, where your function requires to return an integer. My best guess is you need to change it into:
return *(st-i)
Use the * to dereference the pointer into the const char object, which is interchangeable with int
The problem is that your function is currentlu defined to return an int.
If you desire to return an int, such as the relative position from the beginning of your string, then you have to return a difference between pointers
return (st-i)-str; // st-i = begin of the pattern found, - str for the relative position
If you desire to return a pointer, then your function signature shall be changed and you should return nullptr instead of -1 when you didn't fin the patter.
Several other minor issues:
incrementing st before starting comparison risk to miss the pattern if the string starts with it.
pa-i and st-i are without effect: it's just expressions, no change is stored. Maybe you wanted to write pa-=i ?
Try the following. At least it looks simpler.:)
#include <iostream>
int strstr( const char *str, const char *pattern )
{
bool found = false;
const char *p = str;
for ( ; *p && !found; ++p )
{
size_t i = 0;
while ( p[i] == pattern[i] && pattern[i] != '\0' ) ++i;
found = pattern[i] == '\0';
}
return found ? --p - str : -1;
}
int main()
{
std::cout << ::strstr( "Hello evsign", "evsign" ) << std::endl;
return 0;
}
The output is
6
As for your code then even the first statement in the loop is wrong
while (*st){ // starting sort out string
++st;
Why is st increased?
Also this loop
for(i;*st == *pa;i++){
shall be written as
for( ;*st == *pa && *pa; i++){

Value returned by strtok() for tokens of length 0?

I have the following piece of C++ code:
string dots="...";
char *points=(char *)malloc(sizeof(char)*20);
strcpy(points,dots.c_str());
points=strtok(points,".");
while(points!=NULL)
{
cout<<points<<endl;
points=strtok(NULL,".");
}
The cout statement prints nothing. What is this character that cout returns for 0 length token match? I have tried to check for '\0' but does not work. Please Help.
EDIT: Complete Program to Validate IP Addresses
#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
int validateIP(string);
int main()
{
string IP;
cin>>IP;
int result=validateIP(IP);
if(result==0)
cout<<"Invalid IP"<<endl;
if(result==1)
cout<<"Valid IP"<<endl;
return 0;
}
//function definition validateIP(string)
int validateIP(string IP)
{
char ip[16];
int dotCount=0;
strcpy(ip,IP.c_str());
//check number of dots
for(int i=0;i<strlen(ip);++i)
{
if(ip[i]=='.')
{
dotCount++;
}
}
if(dotCount!=3)
return 0;
//check range
char *numToken;
numToken = strtok (ip,".");
while (numToken!= NULL)
{
int number;
if(numToken!=NULL) //check for token of length 0(e.g. case: ...)
number=atoi(numToken); //i also checked for (numToken[0]!='\O')
else return 0;
if(number<0 or number>255)
return 0;
numToken=strtok (NULL,".");
}
return 1;
}
The program prints ValidIP for input: ...
Your code has undefined behavior, you haven't allocate memory for points, accessing it invokes UB.
Update, I might write validateIP by using string and STL functions only if I could. Mix C/C++ is not good for maintenance.
#include <sstream>
int to_int(const std::string& s)
{
int i(0);
std::stringstream ss(s);
ss >> i;
return i;
}
bool isValidIp(const std::string& IP)
{
if (std::count(IP.begin(), IP.end(), '.') != 3)
{
return false;
}
std:stringstream ss(IP);
int token;
std::string s;
while(std::getline(ss, s, '.'))
{
int token = to_int(s);
if (token < 0 || token > 255)
{
return false;
}
}
return true;
}
Then you call it:
if (isValidIp(IP))
{
std::cout << "Valid IP" << std::endl;
}
else
{
std::cout << "Invalid IP" << std::endl;
}
The strtok function returns sub-string of the given string delimited by the given character. IMO (to be tested) if your string only contains delimiting characters, the strtok function will return NULL (no more tokens) at the first call.
Moreover in your code snippet, you copy the string to an uninitialized pointer. Replace your call to strcpy by a call to strdup for the underlying memory to be allocated before copying. Edit: you modified your question as I were answering
strtok is used to tokenize the string. Say, i have a string "abc.def.ghi.jkl" then we can use strtok to get the tokens besed on the delimiter.
char a[]="abc.def.ghi.jkl";
char tmp=strtok(a, ".");
if (tmp != NULL) //Required because strtok will return null if it failes find the delimiter
printf("\n value is [%s]", tmp); //out put is abc
So, in your case "..." is the string and '.' is the delimiter which result in empty string because there is no characters between first character and the delimiter '.'
your code will return empty string say "" as an output. for all the sttok function call.
Second you have to allocate memory to the points variable like
char points[dots.length()+1];
If the string only contains delimiting characters, strok return NULL
You probably want this:
int main()
{
string dots=". . ."; //Notice space
char *points=(char *)malloc(sizeof(char)*20);
char *p; // Use a char pointer
strcpy(points,dots.c_str());
p=strtok(points,".");
while(p!=NULL)
{
cout<<points<<endl;
p=strtok(NULL,".");
}
/* Free Memory */
free(points);
}

C++ See If Argument Is Numeric

I'm creating an encryption/decryption program in C++, and I use three user-provided numbers to customize the encryption. I read about isdigit() on cplusplus.com, and made a function based on that:
bool is_numeric(char *string)
{
int sizeOfString = sizeof(string);
int iteration = 0;
bool isNumeric = true;
while(iteration < sizeOfString)
{
if(!isdigit(string[iteration]))
{
isNumeric = false;
break;
}
iteration++;
}
return isNumeric;
}
However, it doesn't seem to work. Whether I give it a number, or a non-numeric character, it still returns false. What is wrong with my approach.
I think I'd use a standard algorithm:
bool is_numeric(char const *string)
{
return std::all_of(string, string+strlen(string),
[](unsigned char c) { return ::isdigit(c); });
}
Note that as it stands, your code can (often will) have undefined behavior (if the string contains anything that works out as a negative number when encoded into a char). This code prevents that by converting the char to an unsigned char as it's passed to the lambda -- that's why I used a lambda instead of just passing ::isdigit as the predicate to all_of.
You are computing the sizeOfString wrong. Try this instead.
bool is_numeric(char *string)
{
int sizeOfString = strlen(string);
int iteration = 0;
bool isNumeric = true;
while(iteration < sizeOfString)
{
if(!isdigit(string[iteration]))
{
isNumeric = false;
break;
}
iteration++;
}
return isNumeric;
}
You may want to add functionality to check for the . character as well! Right now your code only returns true if your string is an integer.
while ('0' <= *string && *string <= '9')
++string;
return *string == '\0';
or, if you prefer using isdigit:
while (is digit((int)*string))
++string;
return *string == '\0';
Another possible solution is using a stringstream:
bool isNumeric(const string& s) {
stringstream ss(s);
int val;
ss >> val;
return ! ss.fail() && ss.eof();
}
stringstream::operator>>(int&) will make the stringstream's failbit to be set if the given string is not numeric, and you need to check if all that's in the string is exactly one integer (and nothing else), so you also test for the eof bit.
This also works for negative numbers, and you can also change the int to double if you want to accept floating point numbers.