2013-12-16 4 views
3

당신이 그런 정의가있는 경우 :의 수가 특정 숫자 총

int variable = 253243243; 

는 어떻게 든이 번호에 세 번째 자리에, 예를 들어 참조 할 수 있습니까? 벡터 또는 배열의 선을 따라 무엇인가? 숫자의 특정 숫자가 사용자가 제공 한 다른 숫자와 일치하는지 여부를 비교하려면이 코드가 필요합니다. 심지어 가능할까요?

+2

질문에 아무런 문제가 없습니다. 왜 downvotes? –

+0

Karmic balance restored : – GMasucci

+1

왼쪽 또는 오른쪽에서 세 번째 숫자입니까? 아래의 몇 가지 답변이 오른쪽에서부터 세어 나옵니다. 그냥 문자열에 값을 인쇄하고 문자열을 색인화하지 않으면 왼쪽에서 조금 더 까다 롭습니다. –

답변

2

세 번째 자리를 소요됩니다. 당신이 C++ (11)을 준수 컴파일러를 사용하기에 충분히 운이 좋다면,

std::stringstream ss; 
ss << variable; 
std::string s = ss.str(); 
unsigned char first = s[0] - '0'; // this is the first digit (from left) 
unsigned char second = s[1] - '0'; // this is the second digit (from left) 

다른 방법을 :

다른 방법으로는 문자열에서 문자로 stringstream 및 추출물 숫자를 사용하여 string에 번호를 인쇄 할 수 있습니다 std::stringstream 대신 std::string::to_string 함수를 사용할 수 있습니다.

+1

이 방법을 사용할 때 숫자가 직관적으로 뒤집어 질 것이라고 지적하고 싶습니다. 'ss.c_str() [0]'은 맨 왼쪽 숫자입니다. – Casey

+2

'c_str()'호출이 필요하지 않습니다.'s [0]'도 작동합니다. – Blastfurnace

+0

또는 ['std :: to_string'] (http : //www.cplusplus. –

4

variable % 1000/100 당신은 %/ 작업의 조합으로 숫자를 추출 할 수 있습니다

+0

@ JoachimPileborg : 저는 (x % 100)/100이 제로가 될 것이라고 확신합니다 ... –

3

일반적인 공식은 다음과 같습니다

(number % pow(base, the_digit_you_want))/pow(base, the_digit_you_want - 1) 

당신은 또한 int로/캐스트를 TRUNC하는데주의를 기울여야한다.

+0

좋아, 빠른 도움에 감사드립니다. – Jake

1

당신이 C++ (11)를 사용하는 경우, 당신은이 방법을 수행 할 수도 있습니다 :

int variable = 253243243; 
std::string s = std::to_string(variable); 
int x = 3; // the position you want 
char digit = s[s.size() - 1 - x]; // x position from the right 
char otherDigit = s[x - 1]; // x position from the left (1-based) 

모듈로 분할 패턴 (CPU 시간과 메모리의 측면에서) 더 효율적입니다.

+0

왼쪽부터'x' 번째 문자를 추출하는 줄이 옳지 않다고 생각합니다. 즉, 오른쪽에서'x' 번째 문자를 추출하는 것입니다. 다음 줄과 유사한 문제 - '왼쪽'과 '오른쪽'을 바꿔야한다고 생각합니다 .-) – piokuc

+0

@piokuc 죄송합니다. 결정된. :) –

0

이 질문은 나를 위해 작은 "STLish"컨테이너를 만들었습니다 ... 실생활 사용보다 재미 있습니다. 그러나 그럼에도 불구하고, 여기있다 :

#ifndef __DIGITS_H__ 
# define __DIGITS_H__ 

# include <type_traits> 
# include <cmath> 
# include <cassert> 
# include <iterator> 
# include <sstream> 
# include <algorithm> 

namespace digits 
{ 
    // Default base type traits, infer base size from the number of character 
    template <char... Chars> 
    struct base_char_traits 
    { 
     // Mandatory for the digits container, maybe someone want to make 
     // another traits with wchar ? 
     typedef char value_type; 

     // Size of the base, computed from the number of characters passed 
     static constexpr size_t size = sizeof...(Chars); 

     // Array of characters use to print the output 
     static constexpr value_type characters[sizeof...(Chars)] = { Chars... }; 
    }; 

    // **sigh** 
    // Instantiation of the array of character; otherwise there will be a link 
    // error 
    template <char... Chars> 
    constexpr typename base_char_traits<Chars...>::value_type base_char_traits<Chars...>::characters[sizeof...(Chars)]; 

    // All your bases are belong to us ! 
    struct base2_traits : public base_char_traits<'0', '1'> { }; 
    struct base8_traits : public base_char_traits<'0', '1', '2', '3', '4', '5', '6', '7'> { }; 
    struct base10_traits : public base_char_traits<'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'> { }; 
    struct base12_traits : public base_char_traits<'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b'> { }; 
    struct base16_traits : public base_char_traits<'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'> { }; 


    // The digit container with the base traits and the type as template 
    // parameter. 
    //  
    // It is a read only container that allows you to iterate on the digit in 
    // the base given as template parameter. 
    template <typename BaseTraits, typename T = unsigned long> 
    class digits 
    { 
    public: 

     // Assert that T fullfil our criteria 
     static_assert(std::is_integral<T>(), "T must be integral"); 
     static_assert(std::is_unsigned<T>(), "T must be unsigned");   

     // Value type is defined by the base traits to allow the use of more 
     // complicated digit type (here we only handle char) 
     typedef typename BaseTraits::value_type value_type; 

     // Reference type is defined to be the same as value type because this is an immutable container 
     typedef typename BaseTraits::value_type reference; 

     // The size type of the container, i.e. the type that will be used to 
     // express a digit position 
     typedef size_t size_type; 

     // Iterator class allowing one to walk through the number's digit from 
     // the lowest to the highest 
     class iterator 
     { 
     public: 

      // Type used to return iterator substraction result 
      typedef size_t difference_type; 

      // type used by algorithms (e.g. find) 
      typedef typename digits::reference reference; 

      // type used by algorithms (e.g. find) 
      typedef typename digits::reference pointer; 

      // type returned by operator* 
      typedef typename digits::value_type value_type; 

      // Iterator category, here we can randomly walk in the digit 
      typedef std::random_access_iterator_tag iterator_category; 

      // Mandatory default constructor, initialize to an invalid iterator 
      iterator() 
      { 
       _current_digit = 0; 
       _digits = nullptr; 
      } 

      // Build an iterator other a digits container starting at digit 
      iterator(const digits* digits, size_type digit) 
      { 
       _current_digit = digit; 
       _digits = digits; 
      } 

      iterator(const iterator& it) : 
      iterator(it._digits, it._current_digit) 
      { 

      } 

      // Move using swap idiom 
      iterator(iterator&& it) : 
      iterator() 
      { 
       swap(*this, it); 
      } 

      ~iterator() 
      { 
       _digits = nullptr; 
      } 

      // assignment iterator using swap idiom 
      iterator& operator=(iterator it) 
      { 
       swap(*this, it); 
       return *this; 
      } 

      // Comparison operators 
      bool operator==(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit == it._current_digit); 
      } 

      bool operator!=(const iterator& it) const 
      { 
       return !(operator==(it)); 
      } 

      bool operator<(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit < it._current_digit); 
      } 

      bool operator>(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit > it._current_digit); 
      } 

      bool operator<=(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit <= it._current_digit); 
      } 

      bool operator>=(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit >= it._current_digit); 
      } 

      // Moving the iterator 
      iterator& operator++() 
      { 
       ++_current_digit; 
       return *this; 
      } 

      iterator operator++(int) 
      { 
       iterator it(*this); 
       operator++(); 
       return it; 
      } 

      iterator& operator--() 
      { 
       --_current_digit; 
       return *this; 
      } 

      iterator operator--(int) 
      { 
       iterator it(*this); 
       operator--(); 
       return it; 
      } 

      iterator& operator+=(size_type increment) 
      { 
       _current_digit += increment; 
       return *this; 
      } 

      iterator operator+(size_type increment) const 
      { 
       iterator it(*this); 
       return (it += increment); 
      } 

      friend iterator operator+(size_type increment, const iterator& it) 
      { 
       return (it + increment); 
      } 

      iterator& operator-=(size_type decrement) 
      { 
       _current_digit -= decrement; 
       return *this; 
      } 

      iterator operator-(size_type decrement) const 
      { 
       iterator it(*this); 
       return (it - decrement); 
      } 

      difference_type operator-(const iterator& it) const 
      { 
       assert(_digits == it._digits); 
       return (_current_digit - it._current_digit); 
      } 

      value_type operator*() const 
      { 
       assert(nullptr != _digits); 

       return _digits->digit(_current_digit); 
      }   

      friend void swap(iterator& first, iterator& second) 
      { 
       std::swap(first._digits, second._digits); 
       std::swap(first._current_digit, second._current_digit); 
      } 

     private: 

      // The current digit we will be printing when calling operator*(). 
      // From 0 to (digits.size() - 1) 
      size_t _current_digit; 

      // The digit container we're working on. 
      const digits* _digits; 
     };  

     // Define the reverse iterator, that will allow to iterator from the 
     // highest digit to the lowest (more printing friendly) 
     typedef std::reverse_iterator<iterator> reverse_iterator; 

     // Default constructor use 0 as a number 
     digits() 
     { 
      _number = 0; 
     } 

     // Build a container over a number given as parameter 
     digits(T number) 
     { 
      _number = number; 
     } 

     digits(const digits& copy) : 
     digits(copy._number) 
     {    
     } 

     // Move constructor using swap idiom 
     digits(digits&& move) : 
     digits() 
     { 
      swap(*this, move); 
     } 

     ~digits() 
     { 
     } 

     // Retrieve the digit character 
     value_type digit(size_t digit) const 
     { 
      assert(digit < size()); 
      constexpr size_t base = BaseTraits::size; 

      // @warning 
      // llround is mandatory because of a double to unsigned long problem 
      T modul = static_cast<T>(llround(std::pow(base, digit + 1))); 
      T div = static_cast<T>(llround(std::pow(base, digit))); 
      T digit_index = (_number % modul)/div;   

      return BaseTraits::characters[digit_index]; 
     } 

     // Assignment using swap idiom 
     digits& operator=(digits assign) 
     { 
      swap(_number, assign._number); 
     } 

     // Comparison operator 
     bool operator==(const digits& comp) const 
     { 
      return (_number == comp._number); 
     } 

     bool operator!=(const digits& comp) const 
     { 
      return !(operator==(comp)); 
     }  

     // Iterators creation 
     iterator begin() const 
     { 
      return iterator(this, static_cast<size_type>(0)); 
     } 

     iterator cbegin() const 
     { 
      return begin(); 
     } 

     iterator end() const 
     { 
      return iterator(this, size()); 
     } 

     iterator cend() const 
     { 
      return end(); 
     } 

     reverse_iterator rbegin() const 
     { 
      return reverse_iterator(end()); 
     } 

     reverse_iterator crbegin() const 
     { 
      return reverse_iterator(cend()); 
     } 

     reverse_iterator rend() const 
     { 
      return reverse_iterator(begin()); 
     } 

     reverse_iterator crend() const 
     { 
      return reverse_iterator(cbegin()); 
     } 

     // swap function 
     friend void swap(digits& first, digits& second) 
     { 
      std::swap(first._number, second._number); 
     } 

     // cast to string 
     operator std::string() const 
     { 
      std::ostringstream stream; 

      // print from high to low 
      std::copy(rbegin(), rend(), 
         std::ostream_iterator<value_type>(stream, "")); 
      return stream.str(); 
     } 

     // The number of digits of this _number 
     size_type size() const 
     {    
      const double log_number = std::log(_number); 
      constexpr double log_base = std::log(BaseTraits::size); 
      return std::ceil(log_number/log_base); 
     } 

     // The maximum nulber of digits this type can have 
     size_type max_size() const 
     { 
      constexpr double max_number = std::pow(2, sizeof(T) * 8); 
      constexpr double log_max_number = std::log(max_number); 
      constexpr double log_base = std::log(BaseTraits::size); 
      return log_max_number/log_base; 
     } 

    private: 

     // The number we will iterate over the digits 
     T _number; 
    }; 
} 

#endif // __DIGITS_H__ 

기본 사용법있을 법한 :

digits::digits<digits::base10_traits> dig(123456); 

for (auto digit: dig) 
{ 
    std::cout << "Digit: " << digit << std::endl; 
} 

내가 생각하는 불변의 용기 (for_each, find, copy 등)에 STD 알고리즘의 대부분의 것 그 용기와 함께 일해라.

여기 작은 시험 (동일한 파일의 헤더 + 시험) : http://ideone.com/BoMX5Q

좋아, 그것은 꽤 쓸모가 없어요,하지만 할 정말 재미 있었다. :)