我试图在c++中编写一个方法,该方法确定整数是否在其十六进制表示中使用流操纵符而不使用任何for循环。一种方法是用getline
做一些数学运算。有人能提供一些关于所需计算的提示吗?
我很感激你的帮助或使用循环算术,但我正在寻找的东西不迭代字符串
使用c++ ostringstream
和string
:
bool hasHexDigits(int number)
{
std::ostringstream output;
output << std::hex << number;
return output.str().find_first_of("abcdefABCDEF") != string::npos;
}
编辑:其他解决方案,不使用流。它有更好的性能(没有分支)和内存(没有分配),但是对于你的"作业"来说可能太高级了:
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)>());
}
将整型除以16直到得到零。每次检查余数,如果它> 9十六进制包含字母。
sprintf(string,"%x",<your integer>);
将给出您的十六进制数。
因此,在此之后,检查您的字符串是否有以下字母使用一些可用的字符串函数。
a,b,c,d,e,f
// 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);
}
你的要求很奇怪,所以很难给出一个正确的答案。到目前为止,所有的解决方案似乎都是迭代的(尽管有些是在std函数中),或者直接使用整数,这似乎违背了您的要求?"十六进制表示法"向我暗示,你有一个字符串形式的数字。如果这是事实,那么不使用for循环(?)&强迫我们使用流操纵符是不允许的。如果表示形式是ascii字符串,并且不允许迭代,那么一种既不需要迭代也不需要转换(可能会自行迭代)的解决方案可以利用所有alpha数字字符至少具有2个msb集合中的一个的事实:
#include <iostream>
#include <string>
#include <cassert>
#include "boostcstdint.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;
}
也许使用正则表达式?
regex rgx("[A-Za-z]+");
smatch result;
if(regex_search(integer_string, result, rgx)) {
cout << "There is alpha chars in the integer string" << endl;
}
bool func(int num) {
while ( num > 0 ) {
if ( num % 16 > 9 ) return true;
num /= 16;
}
return false;
}
另一个使用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;
}
使用流操纵符,如:
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();
}
就可以了。(我假设你有一个IsAlpha函数对象。如果没有,那么很简单实现,它总是有用的。)
当然,如果唯一的要求是没有循环:
bool
hasAlphaInRepresentation( unsigned number )
{
return number != 0
&& (number % 16 > 9 || hasAlphaInRepresentation( number / 16 ));
}
: -)
您可以这样做(只有逻辑运算和一个减法)
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;
}
的技巧是字符串的二进制表示已经是十六进制(几乎),你只需要检查每一小块
您可以首先在stringstream中存储十六进制表示,然后尝试将其转换为十进制表示。如果转换失败,那么我们可以说字母存在于给定的整数
中。 stringstream myStream;
int myInt;
cin>>myInt;
myStream<<hex<<myInt;
myStream>>dec>>myInt;
cout<<myStream.fail()<<endl;