C++: Comparing individual elements of a string to their ASCII values? [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to write a small program that determines if a string is a palindrome. Naturally, I want to ignore any character that is not a letter. I planned on achieving this by checking each element of the string by comparing their ASCII values to values that I determined: [65,90] U [97,122]
The following code is a segment from a function in which a string, string aStrn, is passed in.
while(aStrn[index] != '\0')
{
if(aStrn[index] > 64 && aStrn[index] < 91 && aStrn[index] > 96 &&
aStrn[index] < 123)
{
ordered.Push(aStrn[index]);
}
index++;
}
I tested this code by explicitly defining parameters such that if(aStrn[index] != ' ' && aStrn[index] != '\''... etc., and it worked perfectly. However, when I try the method shown above, ordered remains empty.
I can't for the life of me figure out why, so all help is greatly appreciated. I also understand that there is probably a better way to go about this but I would still like to understand why this does not work.

Unless you have a specific reason to do otherwise, you want to put your strings into std::string objects, use std::isalpha to determine whether something is a letter, and probably std::copy_if to copy the qualifying data from the source to the destination.
std::string source = "This is 1 non-palindromic string!";
std::string dest;
std::copy_if(source.begin(), source.end(),
std::back_inserter(dest),
[](unsigned char c) { return std::isalpha(c); });
You might also want to convert the string entirely to lower (or upper) case to make comparisons easier (assuming you want to treat upper and lower case letters as equal). That's also pretty trivial:
std::transform(dest.begin(), dest.end(),
dest.begin(),
[](unsigned char c) { return std::toupper(c); });

Missing parentheses and 'OR' operator. Simple mistake.
if((aStrn[index] > 64 && aStrn[index] < 91) || (aStrn[index] > 96 && aStrn[index] < 123)) fixed it.

you're allowed to compare against character literals.
if (aStrn[index] >= 'a' && aStrn[index] <= 'z' /* ... */) // for example
But there are standard library functions that do the work for you.
if (std::isalpha(aStrn[index])) {
//...
}

Related

terminate called after throwing an instance of 'std::out_of_range' and I don't know how to solve it [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I have been working to code, a calculator, that works with recursion.
Input: ! + 1 3
code will do 1+3 and then take the faculity of the sum
output: "24"
I finished writing the basic code( not having filtered out wrong user-input yet),
when I build it shows no warnings, but once I run it I get thrown with the 'std::out_of_range' warning. I tried around and nailed the problem down to one function, but I am unable to identify whats wrong exactly.
//Calculation
string Rechner::berechne(vector <string> t) //Calculator::calculate
{
for (unsigned int i = t.size() - 1; i >= 0; i--) //searches the vector starting from the back
{
if( t.at(i) == "+" || t.at(i) == "*" || t.at(i) == "!") //finds the last operator
{
t.at(i) = differenziere(i, t); //switches out the last operator with
//the result of the operation (differenziere(i, t)
if ( t.at(i) == "!")
{
t.pop_back(); // delets last element of vector and
berechne(t); // searches for the next Operator
}
else
{
t.pop_back(); //delets last two elements
t.pop_back();
berechne(t); //searches for next operator
}
}
}
return t.at(0); //when there is no more operator left, this returns the Result of the whole operation
}
For example
input: 5
the output should be 5, because there is no more operator, but i get the out_of_range warning.
input: + 1 3
has the same output of the warning.
So my best guess is, once the vector consists out of one string, for some reason this falls into the if function, what doesn't make sense to me.
Input is a string, that I convert to a vector. This works all fine, i have tested that.
I am working with code::blocks, c++11 and on a windows laptop.
I hope you can help me.
Also please excuse my english, it's not my native language. I speak fluet normally, but I haven't been around the topic of coding for long, so this is s a little different for me.
i >= 0 will be always true because i is unsigned.
Instead of this
for (unsigned int i = t.size() - 1; i >= 0; i--) //searches the vector starting from the back
{
You can do
for (unsigned int i_loop = t.size(); i_loop > 0; i_loop--) //searches the vector starting from the back
{
unsigned int i = i_loop - 1; // i_loop is positive here thanks to the loop condition

The array index doesnt show the character [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I have this code:
#include <stdio.h>
int main(){
char s1[30] = "This is a sentence";
for(int i = 0; i<sizeof(s1);i++){
if(s1[i] = ' '){
printf("+");
}
}
return 0;
}
When I try to loop the array to find all the spaces this happens:
Output: ++++++++++++++++++++++++++++ //30 pluses.
Why doesnt my program outputs 3 pluses?
EDIT: My problem was a simply typo mistake, If you didn't understand what is wrong here take a look at accepted answer.
Change = to == in your if statement.
In your conditional statement, you're assigning space to s[ i ] (operator =). You want to compare them (operator ==).
Try
if (s[ i ] == ' ')
s[ i ] = ' ' is always true because the result of an assignment is the value assigned (space). This value is implicitly converted to a bool (0 = false, anything else = true). Since a space is 32 in ASCII, it will always be true.
References - Assignment Operator, Comparison Operators, ASCII Table
Do this:
if(s1[i] == ' '){
printf("+");
}
= is an assignment operator. To compare two value you need to use == operator. You have used = that that assignment operator always return true so + is being printed out all the time.

Can someone explain this program to check unique chars in string c++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Hi I used to solve string char uniqueness using map in C++. I found this solution somewhere and working fine. But I can not understand how it is working. Please some one explain.
bool isUnique(string s){
int check = 0;
for(int i=0;i<s.length();++i){
if(s[i] != ' '){
int val = s[i]-'a';
if( (check & ( 1 << val)) > 0) return false;
check = check | (1 << val);
}
}
return true;
}
It returns true if string has no repeated character excluding spaces otherwise returns false.
It is using an int as if it were a bitmap. A bitmap is certainly a better data structure for a character uniqueness test than a map. An int is a crude and questionable (in this case) substitute for a bitmap.
Assume an int has 32 bits. Those bits are allocated in this code for the first 32 characters beginning with lower case 'a'. So the upper case letters and most special characters have no bit positions and are treated as unique by this code even if they are not unique.
If you only care about uniqueness for lower case letters, and you are sure the code is only used in architectures that have at least 32 bits in an int, then this is a decent approach. Otherwise, when you want an array of bits, use some actual array of bits.

Comparing two strings without using strcmp [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
This is my question:
Write a function name compareStrings(char * str1, char * str1, int i=0), which returns decides whether
the two received string are equal or not. The third parameter decides whether to take case
sensitiveness while comparing strings: 0 means case sensitive, otherwise case sensitive.
The function returns 0 if two strings are equal
Returns 1 if str1 > str2
Returns -1 if str1 < str2.
Example:
compareStrings( “apple”, “Apple” ) returns 1
compareStrings( “apple a day keeps the doctor away”, “apple are good for health” ) returns -1
This code I have done yet but it is not comparing all Ascii's. According to me I must put all Ascii's checks but it would be so long
Please tell me any other logic regarding this Question.
#include<iostream>
using namespace std;
int compareStrings(char * str1, char * str2);
int main()
{
char str1[]="apple";
char str2[]="Apple";
int ret;
ret=compareStrings(str1,str2);
if(ret==0)
cout<<"Both strings are equal"<<endl;
else if(ret==1)
cout<<"string 1 is bigger than 2"<<endl;
else
cout<<"string 1 is lower than 2"<<endl;
return 0;
}
int compareStrings(char * str1, char * str2)
{
for(int i=0;i<20;i++)
{
if(str1[i]==str2[i])
return 0;
else if(str1[i] >= 'A' && str1[i] <= 'Z' &&str2[i] <='a' && str2[i]<='z')
return -1;
else if(str2[i] >= 'A' && str2[i] <= 'Z' &&str1[i] <='a' && str1[i]<='z')
return 1;
}
}
There are multiple problems with the code as shown. I'm ignoring the fact that you aren't using C++ std::string type, though that is another issue.
You only compare the first twenty characters of the strings.
What happens if the strings are longer?
What is the return value from the function if the loop ends?
You compare the first twenty characters of the strings even if the strings are shorter.
You return 0 on the first character that's the same.
You return -1 if the current character in the first string is upper-case and the current character in the second is lower-case, regardless of whether the case-sensitivity flag is set or whether the letters are equivalent.
Similarly you return +1 for the converse condition.
You don't use the isalpha(), isupper(), islower() macros (prefixed with std:: from <cctype> or equivalent functions.
You don't recognize that if one string contains a 7 and the other a 9, you should come to a decision.
Since the comparison function is not supposed to modify either string, the function prototype should use const char * arguments.
Etc.
You will need to rethink your code rather carefully. Ignore case-insensitivity until you have case-sensitive comparisons working correctly. Then you can modify it to handle case-insensitive comparisons too.

c++ string compare algorithm [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
what is your best string comparison algorithm?
i find O(n)
#include <string>
bool str_cpmr(char* str1, char* str2)
{
int l1 = strlen(str1), l2 = strlen(str2) ;
if(l1 != l2)
return false;
for(int i = 0 ; i < l1 ; i++)
if(str1[i] != str2[i])
return false ;
return true ;
}
and i wonder if there is any other / better solution.
also, how to test that accurately?
i propose to compare
100 matches
100 strings differing by one char swap
is there more to test string compare ?
how is it in stl c++ (slt string::compare) ?
thanks!!!!!
You function is O(n), but still takes roughly double the time necessary -- strlen walks through the string to find the length, then (assuming they're the same length) you walk through the strings again comparing the characters.
Instead of that, I'd walk through the strings until you reach a mismatch or the end of both strings. If you reach a mismatch, you return false. You return true if and only if you reach the end of both strings (simultaneously) without any mismatches first.
Logically it's hard to see how you can check all the values in a string for a single char mismatch in less than O(n) time - assuming you have no other info about the string.
If this is a real application and you have some knowledge of the strngs and the type of differences you could do better on average by checking every Nth char first if you know that it contains sequences of length 'N' eg part or phone numbers.
edit: Note this is still O(n), O() only describes the power of the scaling, it would just be O(n/N) which is still O(n). If you make the string 10x longer checking every Nth entry still takes 10x as long.
what is your best string comparison algorithm?
template< class T, class Alloc >
bool operator==( basic_string<T,Alloc>& lhs, basic_string<T,Alloc>& rhs );.
It compares two strings using only two characters of source code:
a==b;
Here's a non-smartalec answer, written in C:
bool str_cpmr(char* str1, char* str2)
{
while( *str1 && *str2 && *str1++ == *str2++ )
;
return *str1 == *str2;
}
It is exactly one loop, so it is obviously O(n), where n goes as length of the shorter string. Also, it is likely to compile to exactly 2n memory fetches. You can go faster with specialized string instructions (so calling strcmp() will probably go faster than this), but you probably won't go faster in straight C.
Your improved function might look like this:
bool str_cpmr(char* str1, char* str2)
{
if (NULL == str1 || NULL == str2) return false;
while (*str1 && *str2) {
if (*str1++ != *str2++) {
return false;
}
}
return *str1 || *str2 ? false : true;
}
If there is no additional information on the nature of the strings, there is nothing that can be better than O(n), where n is the length of the (shorter) string.
You cannot do with less than n comparisons! Give me an algorithm that can do it with n-1 comparisons. Then there must be a position in the string where the algorithm cannot tell if the characters are different or not. That way I can give you an example where you algorithm with n-1 comparisons fails.
You can only improve this by a constant factor. This will also take into account additional information, e.g. if you know that the underlying hardware compares 32-bit values faster than 8-bit values, then it will better to compare chunks of four characters instead of comparing character by character. You will not do much better.