당신이 그런 정의가있는 경우 :의 수가 특정 숫자 총
int variable = 253243243;
는 어떻게 든이 번호에 세 번째 자리에, 예를 들어 참조 할 수 있습니까? 벡터 또는 배열의 선을 따라 무엇인가? 숫자의 특정 숫자가 사용자가 제공 한 다른 숫자와 일치하는지 여부를 비교하려면이 코드가 필요합니다. 심지어 가능할까요?
당신이 그런 정의가있는 경우 :의 수가 특정 숫자 총
int variable = 253243243;
는 어떻게 든이 번호에 세 번째 자리에, 예를 들어 참조 할 수 있습니까? 벡터 또는 배열의 선을 따라 무엇인가? 숫자의 특정 숫자가 사용자가 제공 한 다른 숫자와 일치하는지 여부를 비교하려면이 코드가 필요합니다. 심지어 가능할까요?
세 번째 자리를 소요됩니다. 당신이 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 함수를 사용할 수 있습니다.
이 방법을 사용할 때 숫자가 직관적으로 뒤집어 질 것이라고 지적하고 싶습니다. 'ss.c_str() [0]'은 맨 왼쪽 숫자입니다. – Casey
'c_str()'호출이 필요하지 않습니다.'s [0]'도 작동합니다. – Blastfurnace
또는 ['std :: to_string'] (http : //www.cplusplus. –
variable % 1000/100
당신은 %
및 /
작업의 조합으로 숫자를 추출 할 수 있습니다
@ JoachimPileborg : 저는 (x % 100)/100이 제로가 될 것이라고 확신합니다 ... –
일반적인 공식은 다음과 같습니다
(number % pow(base, the_digit_you_want))/pow(base, the_digit_you_want - 1)
당신은 또한 int로/캐스트를 TRUNC하는데주의를 기울여야한다.
좋아, 빠른 도움에 감사드립니다. – Jake
당신이 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 시간과 메모리의 측면에서) 더 효율적입니다.
왼쪽부터'x' 번째 문자를 추출하는 줄이 옳지 않다고 생각합니다. 즉, 오른쪽에서'x' 번째 문자를 추출하는 것입니다. 다음 줄과 유사한 문제 - '왼쪽'과 '오른쪽'을 바꿔야한다고 생각합니다 .-) – piokuc
@piokuc 죄송합니다. 결정된. :) –
이 질문은 나를 위해 작은 "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
좋아, 그것은 꽤 쓸모가 없어요,하지만 할 정말 재미 있었다. :)
질문에 아무런 문제가 없습니다. 왜 downvotes? –
Karmic balance restored : – GMasucci
왼쪽 또는 오른쪽에서 세 번째 숫자입니까? 아래의 몇 가지 답변이 오른쪽에서부터 세어 나옵니다. 그냥 문자열에 값을 인쇄하고 문자열을 색인화하지 않으면 왼쪽에서 조금 더 까다 롭습니다. –