Reputation: 65
I am trying to write a method in C++ which determines if an integer has letters in its hex representation using stream manipulators without using any for loop.
One way could be to use getline
and do some math. Can someone provide hints on the kind of computation required?
I appreciate your helps or using the Circular Arithmetic , But I am looking for something which does not iterate over the string
Upvotes: 1
Views: 607
Reputation: 1
You can first store a hex representation in the stringstream and try to convert it to a decimal representation. If it fails to convert, then we can say that letters are present in the given integer
stringstream myStream;
int myInt;
cin>>myInt;
myStream<<hex<<myInt;
myStream>>dec>>myInt;
cout<<myStream.fail()<<endl;
Upvotes: 0
Reputation: 4291
Your requirements are very weird, so it's hard to give a correct answer. All the solutions so far seems to either iterate ( although some inside std functions ), or work with a straight up integer, which seems to go against your requirements? "hex representation" suggests to me that you have the number in the form of a string. If this is the fact then not using for loops(?) & forcing us to use stream manipulators makes it a no go. If the representation is in form of a ascii string, and we're not allowed to iterate, then one solution which doesn't require neither iteration nor conversion ( which likely will iterate in itself ) can make use of the fact that all alpha numeric chars have at least one of the 2 MSBs set:
#include <iostream>
#include <string>
#include <cassert>
#include "boost\cstdint.hpp"
union StrInt
{
boost::uint64_t val;
char str[ sizeof( boost::uint64_t ) ];
};
int main()
{
std::string someString("A9999999" );
StrInt tmp;
assert( someString.size() <= sizeof( tmp.str ) );
memcpy( tmp.str, &someString[0], someString.size() );
std::cout << !!( tmp.val & 0xC0C0C0C0C0C0C0C0ul ) << std::endl;
}
Upvotes: 2
Reputation: 153909
Using the stream manipulators, something like:
bool
hasAlphaInRepresentation( unsigned number )
{
std::ostringstream s;
s << std::hex << number;
std::string str = s.str();
return std::find( str.begin(), str.end(), IsAlpha()) != str.end();
}
would do the trick. (I'm assuming that you have an IsAlpha functional object in your toolbox. If not, it's fairly straightforward to implement, and it's always useful.)
Of course, if the only requirement were no loop:
bool
hasAlphaInRepresentation( unsigned number )
{
return number != 0
&& (number % 16 > 9 || hasAlphaInRepresentation( number / 16 ));
}
:-)
Upvotes: 1
Reputation: 6329
Using C++ ostringstream
and string
:
bool hasHexDigits(int number)
{
std::ostringstream output;
output << std::hex << number;
return output.str().find_first_of("abcdefABCDEF") != string::npos;
}
EDIT: other solution, without using streams. It's better performance (no branches) and memory wise (no allocations), but may be too advanced for your "homework":
template<int I> struct int_to_type
{
static const int value = I;
};
inline bool __hasHexCharacters(int number, int_to_type<0>)
{
return false;
}
template <int digitsLeft>
inline bool __hasHexCharacters(int number, int_to_type<digitsLeft>)
{
return ((number & 0xF) > 9) | __hasHexCharacters(number >> 4, int_to_type<digitsLeft-1>());
}
inline bool hasHexCharacters(int number)
{
return __hasHexCharacters(number, int_to_type<2 * sizeof(int)>());
}
Upvotes: 6
Reputation: 10447
You can do someting like (only logic operation and one substraction)
bool has_letters(int num)
{
if(num < 0) num = 0- num; //abs value
unsigned char * c;
c = (unsigned char * )(& num)
for(int i=0;i<sizeof(int),i++)
{
if(((c[i] & 0xf) > 0x9) || ((((c[i]>>4) & 0xf) > 0x9) )
return true;
//or you can use precomputed table
//if(table[c[i]])
// return true;
}
return false;
}
Trick is that binary representaion of string is allready hex (almost) you just need to chek each nibble
Upvotes: 0
Reputation: 1054
Another method using stringstream:
std::stringstream ss;
std::string str;
std::string::iterator it;
bool hasChar = false;
// Use the hex modifier to place the hex representation of 75 into the
// stream and then spit the hex representation into a string.
ss << std::hex << 75;
str = ss.str(); // str contains "4b"
it = str.begin();
// Check for characters in hex representation.
while (!hasChar && it != str.end())
{
if (isalpha(*it))
hasChar = true;
++it;
}
Upvotes: 1
Reputation: 231113
// Assumes 32-bit int. Computing the mask based on UINT_MAX is left as an
// exercise for the reader.
int has_hex_alpha(unsigned int num) {
return !!((num & (num << 1 | num << 2)) & 2290649224);
}
Upvotes: 2
Reputation: 5914
bool func(int num) {
while ( num > 0 ) {
if ( num % 16 > 9 ) return true;
num /= 16;
}
return false;
}
Upvotes: 1
Reputation: 67221
sprintf(string,"%x",<your integer>);
will give your hexa decimal number.
so after this,check if your string has any alphabets below using some string functions available.
a,b,c,d,e,f
Upvotes: 2
Reputation: 33252
divide the int by 16 until you reach zero. Each time check the remainder, if it is > 9 hex contains letters.
Upvotes: 5
Reputation: 5348
Perhaps use regex?
regex rgx("[A-Za-z]+");
smatch result;
if(regex_search(integer_string, result, rgx)) {
cout << "There is alpha chars in the integer string" << endl;
}
Upvotes: 1