checking for letters in a string of ints - c++

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.

Related

Balanced paranthesis question based on stack

Here is the question:
A bracket sequence is called regular if it is possible to obtain correct arithmetic expression by inserting characters + and 1 into this sequence. For example, sequences (())(), () and (()(())) are regular, while )(, (() and (()))( are not. Let's call a regular bracket sequence "RBS".
You are given a sequence s of n characters (, ), and/or ?. There is exactly one character ( and exactly one character ) in this sequence.
You have to replace every character ? with either ) or ( (different characters ? can be replaced with different brackets). You cannot reorder the characters, remove them, insert other characters, and each ? must be replaced.
Determine if it is possible to obtain an balanced sequence or not after these replacements.
EX:
5
()
(?)
(??)
??()
)?(?
Output:
YES
NO
YES
YES
NO
Here is my code:
#include <bits/stdc++.h>
using namespace std;
bool checkValidString(string s) {
stack<char>st;
for(int i=0;i<s.length();i++)
{
if(!st.empty() && (((st.top() == '(') && s[i] == '?') || ((st.top() == '?') && s[i] == ')') || st.top() == '(' && s[i] == ')'))
{
st.pop();
}
else
{
st.push(s[i]);
}
}
if(st.empty())
{
return true;
}
int si = st.size();
bool odd = false;
if(si%2!=0)
{
odd = true;
}
while(!st.empty())
{
char c = st.top();
if(c!='?')
{
return false;
}
st.pop();
}
if(odd)
{
return false;
}
return true;
}
int main() {
// your code goes here
int n;
cin>>n;
while(n--)
{
string s;
cin>>s;
bool ans = checkValidString(s);
if(ans == 1)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
However it is giving wrong answer,Can you help where I am going wrong?Thanks.
This kind of problem won't work by the logic for checking valid parenthesis.
Example: The test case where input string = (?)? will fail in your case. But it is a valid string as it can take the form (()).
So now, how do you approach such a problem?
Let's figure out what are all the possible input strings can look like.
Test Cases:
If number if question marks are odd, then it's an invalid string.
If Opening bracket appears before closing one, and we have odd number of question marks between them:
(???)? or ?(???) => Both are valid strings, as they can take the form ((())).
If Opening bracket appears before closing one, and we have even number of question marks between them:
(????) or ??(??)?? => These kind of strings are always valid.
If Opening parenthesis comes closing parenthesis:
?)(? => This string is also valid as it can take the from ()().
The only thing we need to worry about is if ) is the first position or ( is at the last position:
)??( => Always an invalid string.
)?(? => Always an invalid string.
?)?( => Always an invalid string.
Therefore, the problem gets simplified to 3 main conditions:
The length of the string should be even: For this to be true, the number of ? characters in the string should be even.
The string should not start with ).
The string should not end with (.
Have a look at the following code which has Accepted status on Codeforces:
#include <iostream>
#include <string>
int main(){
int t;
scanf("%d", &t);
while(t--){
std::string s;
std::cin>>s;
int len = s.length();
int countQuestion = 0;
for(int i=0;i<len;i++){
if(s[i]=='?'){
countQuestion++;
}
}
//Check 1: If question count is even?
if(countQuestion & 1){
printf("NO\n");
}else{
if(s[0] == ')' || s[len-1] == '('){
printf("NO\n");
}else{
printf("YES\n");
}
}
}
return 0;
}
Verdict:
If you wanted to check a string of brackets to see if it was valid, you'd keep a counter of open brackets as you walk through the string. You'd start it at 0, increment it for every ( and decrement it for every ). You'd check to make sure that it never goes negative and that it ends at 0.
If some of the brackets are replaced by question marks, you can imagine doing the same thing, but at every position you can calculate all the possible non-negative values of the counter. If that set of values ever goes empty, then a valid bracket string is impossible. If that set doesn't include 0, then a valid bracket string is impossible.
It turns out (and you can prove by induction), that the set of possible values always includes every 2nd number between two numbers x and y.
After ?, [x,y] -> [x-1,y+1], excluding numbers < 0
After (, [x,y] -> [x+1,y+1]
After ), [x,y] -> [x-1,y-1], excluding numbers < 0
So you can test any sequence of brackets and question marks by running through the string, starting with [0,0] and modifying the range according to the above rules for each character. Make sure it never goes empty and includes 0 at the end.
bool checkValidString(string s) {
int l=0, h=0;
for(int i=0;i<s.length();i++) {
switch(s[i]) {
case '(':
++l;++h;
break;
case ')':
if (h<=0) {
return false;
}
--h;
l += (l>0 ? -1:1);
break;
default:
++h;
l += (l>0 ? -1:1);
break;
}
}
return l==0;
}

Pangram String Error On My Hackerrank Code

I found this question on Hackerrank where I have to write a method to say whether or not a given string is a pangram. A sentence is a pangram if it contains all 26 letters of the alphabet. The input will only contain characters that are alphabetical (uppercase or lowercase) and spaces.
Here's the code I've gotten so far, where I use a set to keep track of which letters are present in the string. However, the code just keeps running infinitely in the while loop below.
string pangrams(string s) {
set<char> set{};
int i=0;
while (i!=s.length()) {
if(s[i]!='\0') {
set.insert(tolower(s[i]));
}
}
if (set.size() == 27) {
return "pangram";
} else {
return "not pangram";
}
}
Your function needs a slight modification. Firstly, you aren't incrementing i which makes your function go into infinite loop. Other modification is explained in code below -
string pangrams(string s) {
set<char> set{};
int i=0;
while (i!=s.length()) {
if(s[i]!=' ') { # if character is space, ignore it
set.insert(tolower(s[i]));
}
i++; # Main reason of runtime error - you missed incrementing i
}
if (set.size() == 26) { # 26 and not 27. There may be strings without space that are pangrams. So we wont add space into our set.
return "pangram";
} else {
return "not pangram";
}
}
Also, you don't need to check s[i]!='\0' since a c++ string isn't terminated with \0 character. Only checking i!=s.length() will be enough.
Hope this clears your issue !
You're never incrementing i, so your code will run infinitely. I would recommend a for loop for (int i = 0; i < s.length(); i ++) or a for-each loop for (char c : s)
Instead of using a set, you could also try this, where each character corresponds to an index in a bool[]
bool exists[27];
for (char c : s) {
if ('a' <= c && c <= 'z') {
exists[c - 'a'] = true;
} else if ('A' <= c && c <= 'A') {
exists[c - 'A'] = true;
} else if (c == ' ') {
exists[26] = true;
}
}
for (bool b : exists) {
if (!b) return false;
}
return true;

(C++) How to tell when every value after the first in a string is uppercase or lowercase

I need to take any string like 'Lollipop' and the code needs to see if every single value after the first letter is uppercase or not. If every value is uppercase, I need it to increase an outside variable by 1. I am not sure how to do this as the length of the string can vary. The inputted word has a constraint of 2-10 characters and the first letter must start with a capital letter. I did this by simply doing stringName(0) == Ascii range for uppercase. I just have no clue how to check the rest of the string to see if it is entirely lowercase or not. The code can only use iostream and string.
Thanks
You can use std::isupper() and std::all_of() to make the code more compact:
#include <string>
#include <algorithm>
#include <cctype>
bool isStrUpperCase(const std::string& str) {
const auto start = std::next(str.begin());
// skip first character, you'll have to make sure
// your string has at least two characters!
return std::all_of(start, str.end(),
[](const char c){ return std::isupper(c) != 0; });
}
Taking the answer of #Gokul, which is not complete correct:
bool checkForAllUppercase(std::string str) {
int counter = 0;
for (int i = 0; i < str.size(); i++){
if (isupper(str[i]))
counter++;
else
return false; // you can leave the for-loop if you find the first not upper-case letter
}
if (counter == str.size()) // check if all values where upper case
return true;
else
return false;
return false;
}
int main() {
...
if(checkForAllUppercase(exastr))
variable++;
}
I wrote a function which returns true, if all letters are upper-case and false if not. Example usage is shown also

makeValidWord(std::string word) not working properly

I'm programming a hash table thing in C++, but this specific piece of code will not run properly. It should return a string of alpha characters and ' and -, but I get cases like "t" instead of "art" when I try to input "'aRT-*".
isWordChar() return a bool value depending on whether the input is a valid word character or not using isAlpha()
// Words cannot contain any digits, or special characters EXCEPT for
// hyphens (-) and apostrophes (') that occur in the middle of a
// valid word (the first and last characters of a word must be an alpha
// character). All upper case characters in the word should be convertd
// to lower case.
// For example, "can't" and "good-hearted" are considered valid words.
// "12mOnkEYs-$" will be converted to "monkeys".
// "Pa55ive" will be stripped "paive".
std::string WordCount::makeValidWord(std::string word) {
if (word.size() == 0) {
return word;
}
string r = "";
string in = "";
size_t incr = 0;
size_t decr = word.size() - 1;
while (incr < word.size() && !isWordChar(word.at(incr))) {
incr++;
}
while (0 < decr && !isWordChar(word.at(decr))) {
decr--;
}
if (incr > decr) {
return r;
}
while (incr <= decr) {
if (isWordChar(word.at(incr)) || word.at(incr) == '-' || word.at(incr) == '\'') {
in =+ word.at(incr);
}
incr++;
}
for (size_t i = 0; i < in.size(); i++) {
r += tolower(in.at(i));
}
return r;
}
Assuming you can use standard algorithms its better to rewrite your function using them. This achieves 2 goals:
code is more readable, since using algorithms shows intent along with code itself
there is less chance to make error
So it should be something like this:
std::string WordCount::makeValidWord(std::string word) {
auto first = std::find_if(word.cbegin(), word.cend(), isWordChar);
auto last = std::find_if(word.crbegin(), word.crend(), isWordChar);
std::string i;
std::copy_if(first, std::next(last), std::back_inserter(i), [](char c) {
return isWordChar(c) || c == '-' || c == '\'';
});
std::string r;
std::transform(i.cbegin(), i.cend(), std::back_inserter(r), std::tolower);
return r;
}
I am going to echo #Someprogrammerdude and say: Learn to use a debugger!
I pasted your code into Visual Studio (changed isWordChar() to isalpha()), and stepped it through with the debugger. Then it was pretty trivial to notice this happening:
First loop of while (incr <= decr) {:
Second loop:
Ooh, look at that; the variable in does not update correctly - instead of collecting a string of the correct characters it only holds the last one. How can that be?
in =+ word.at(incr); Hey, that is not right, that operator should be +=.
Many errors are that easy and effortless to find and correct if you use a debugger. Pick one up today. :)

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

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.