Как найти, если целое число имеет буквы в шестнадцатеричном представлении - PullRequest
1 голос
/ 23 ноября 2011

Я пытаюсь написать метод на C ++, который определяет, есть ли у целого числа буквы в его шестнадцатеричном представлении, используя потоковые манипуляторы без использования цикла for. Одним из способов может быть использование getline и математика. Может ли кто-нибудь дать подсказки о необходимых вычислениях?

Я ценю вашу помощь или использование круговой арифметики, но я ищу что-то, что не перебирает строку

Ответы [ 10 ]

6 голосов
/ 23 ноября 2011

Использование C ++ ostringstream и string:

bool hasHexDigits(int number)
{
    std::ostringstream output;
    output << std::hex << number;
    return output.str().find_first_of("abcdefABCDEF") != string::npos;
}

EDIT: другое решение, без использования потоков.Это лучшая производительность (без веток) и память (без выделения ресурсов), но может быть слишком сложной для вашей «домашней работы»:

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)>());
}
5 голосов
/ 23 ноября 2011

делите int на 16, пока не достигнете нуля. Каждый раз проверяйте остаток, если он> 9, содержит шестнадцатеричные буквы.

2 голосов
/ 23 ноября 2011

Ваши требования очень странные, поэтому сложно дать правильный ответ.Кажется, что все решения до сих пор либо повторяются (хотя некоторые внутри std-функций), либо работают с прямым целым числом, что, кажется, идет вразрез с вашими требованиями?«шестнадцатеричное представление» подсказывает мне, что у вас есть число в виде строки.Если это так, то отсутствие использования циклов for (?) И принуждение нас к использованию потоковых манипуляторов делает это бесполезным.Если представление представлено в форме строки ascii, и нам не разрешено выполнять итерацию, тогда одно решение, которое не требует ни итерации, ни преобразования (которое, вероятно, будет повторяться само по себе), может использовать тот факт, что все буквенно-цифровые числау символов есть хотя бы один из 2 наборов MSB:

#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;
}
2 голосов
/ 23 ноября 2011
// 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);
}
2 голосов
/ 23 ноября 2011
sprintf(string,"%x",<your integer>);

выдаст ваше шестнадцатеричное десятичное число.

, поэтому после этого проверьте, есть ли в вашей строке алфавиты, используя некоторые доступные строковые функции.

a,b,c,d,e,f
1 голос
/ 23 ноября 2011

Используя потоковые манипуляторы, что-то вроде:

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 ));
}

: -)

1 голос
/ 23 ноября 2011

Другой метод с использованием 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;
}
1 голос
/ 23 ноября 2011
bool func(int num) {
    while ( num > 0 ) {
         if ( num % 16 > 9 ) return true;
         num /= 16;
    }
    return false;
}
1 голос
/ 23 ноября 2011

Возможно, использовать регулярные выражения?

regex rgx("[A-Za-z]+");
smatch result;    
if(regex_search(integer_string, result, rgx)) { 
  cout << "There is alpha chars in the integer string" << endl;
}
0 голосов
/ 23 ноября 2011

Вы можете сделать что-то вроде (только логическая операция и одно вычитание)

 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;
 }

Хитрость в том, что двоичное представление строки уже шестнадцатеричное (почти), вам просто нужно проверять каждый клев

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...