返回数字内的数字的函数

时间:2011-05-10 23:26:04

标签: c++ c

我想创建一个函数,它将是一个数字和我想要检索的数字的位置,

int getDigit(int value, int positionFromLeft)

说,getDigit(534,2)将返回3.

编写此函数的最简单/最有效的方法是什么?

12 个答案:

答案 0 :(得分:6)

首先,如果您愿意为正确而不是向左(即从最低有效数字)工作,那么它将更容易很多

给定输入N,N%10将给出最低有效数字。 X / 10将X向右移一位,x / 100将向右移两位数等。

如果你真的需要从左边开始,log10应该会得到你的总位数。

答案 1 :(得分:4)

所有这些基于字符串的解决方案都吓到我了......真的是谁? : - /

int getDigit(int value, int positionFromLeft)
{
    int posFromRight = 1;
    {
        int v = value;
        while (v /= 10)
            ++posFromRight;
    }
    posFromRight -= positionFromLeft - 1;
    while (--posFromRight)
        value /= 10;
    value %= 10;
    return value > 0 ? value : -value;
}

请注意,传递positionFromLeft的越界值不会按原样返回任何感知值。

答案 2 :(得分:2)

最简单的方法是转换为字符串并进行查找。这个例子使用C ++,但这个想法可以很容易地转换为C。

int getDigit(int value, int positionFromLeft) {
    if (value < 0) positionFromLeft++;

    std::stringstream ss;
    ss << value;

    std::string s = ss.str();
    if (positionFromLeft >= 1 && positionFromLeft <= s.length())
        return s[positionFromLeft-1] - '0';
    else
        throw std::runtime_error("invalid digit position");
}

事实证明,这里有一些需要考虑的问题。

  • 如果value为否定,会怎样?我选择忽略第一个数字的符号和计数。
  • 如果这个位置超出界限怎么办?我选择了抛出异常。
  • value也有INT_MIN的可能性,因此仅使用绝对值将无效。

答案 3 :(得分:1)

针对这个旧问题的不同递归解决方案(我将positionFromLeft的类型更改为unsigned

int getDigit(int value, unsigned positionFromLeft) {
    assert(positionFromLeft > 0);
    if (positionFromLeft == 1) return abs(value) % 10;
    if (value == 0) return 0; // optimization: break out of recursion if 0 is reached
    return getDigit(value / 10, positionFromLeft - 1);
}

请参见ideone

答案 4 :(得分:0)

最简单但不一定是最好的:

int getDigit(int value, int positionFromLeft)
{
    char buf[sizeof(int)*3+2];
    if (sprintf(buf, "%d", value)-1U < positionFromLeft-1U) return -1;
    return buf[positionFromLeft-1U]-'0';
}

注意:编辑,因为有人(显然)反对snprintf不在C ++中,并且考虑到越界和一个基础的位置。现在它稍微不那么简单......

答案 5 :(得分:0)

function getDigit(original,nonZeroIndexedIndex)
{
    return ((int)floor(original / pow(10, nonZeroIndexedIndex))) % 10;
}

与@R ..的建议:

function getDigit(original,nonZeroIndexedIndex)
{
    int tens [5] = { 1, 10, 100, 1000, 10000 };
    return ((int)floor(original / tens[nonZeroIndexedIndex - 1])) % 10;
}

希望这有帮助!这对我来说是一个不错的小C ++复习:)

答案 6 :(得分:0)

int getDigit(int value, int positionFromLeft)
{
    char buffer[20];
    if (value > 0)
        value = -value;
    int len = snprintf(buffer, sizeof(buffer), "%d", value);
    int digit = 0;
    if (len > positionFromLeft && positionFromLeft > 0)
        digit = buffer[positionFromLeft] - '0';
    return digit;
}

如果要求超出数字RHS的数字,则返回零。否定技巧确保值始终为负(并且永远不会遇到否定INT_MIN的问题),然后有一个减号,因此positionFromLeft是正确的而不用一个调整。此代码假设使用C99或C ++(但有一点需要注意:snprintf()并非C ++ 98强制要求,但可能作为扩展提供;纯C ++ 98和C99解决方案必须使用{{ 1}}相反,在上下文中足够安全)。

抗议一次选择正确的解决方案!

考虑测试工具:

sprintf()

此解决方案为#include <stdio.h> int getDigit1(int value, int positionFromLeft) { while (--positionFromLeft) value /= 10; return value % 10; } int getDigit2(int value, int positionFromLeft) { char buffer[20]; if (value > 0) value = -value; int len = snprintf(buffer, sizeof(buffer), "%d", value); int digit = 0; if (len > positionFromLeft && positionFromLeft > 0) digit = buffer[positionFromLeft] - '0'; return digit; } int main(void) { int values[] = { 534, 1234567, -1234567 }; for (int i = 0; i < 3; i++) { for (int j = 1; j <= 7; j++) printf("getDigit(%d, %d) = (v1) %d, (v2) %d\n", values[i], j, getDigit1(values[i], j), getDigit2(values[i], j)); putchar('\n'); } return 0; } getDigit(534, 2)(通常是具有奇数位数的数字的中间数字)生成正确的值,但不正确:

getDigit(1234567, 4)

该问题明确要求从数字的左边开始的第N个数字,从1开始计算。

答案 7 :(得分:0)

如果你真的需要从左计算,你可以这样做:

uint8_t getDigitR(uint16_t value, uint8_t i) {
  uint32_t digit = 1;
  while (digit <= value)
    digit *= 10;
  while (i--) // if you start counting at 1
    digit /= 10;
  return (value / digit) % 10;
}

但这可能不比字符串解决方案更有效或更容易,但由于它是作业,如果没有使用字符串,可能会有一些代数的东西需要学习:)

但是,您需要更少的堆栈空间。

答案 8 :(得分:0)

只是变得与众不同,一个不需要#include

int getDigit(unsigned int original, unsigned int positionFromLeft)
{
    if (original==0 && positionFromLeft==1) {
        /* In a more mathematical world, zero has no digits. */
        return 0;
    }
    unsigned int expon=0;
    unsigned int power=1;
    for (unsigned int quotient=original; quotient; quotient/=10, ++expon) {
        if (expon >= positionFromLeft) {
            power *= 10;
        }
    }
    if (positionFromLeft > expon) {
        /* Not enough digits in number. */
        return -1;
    }
    return (original / power) % 10;
}

答案 9 :(得分:0)

如果我错了,请纠正我。

您可以尝试使用sprintf将int强制转换为字符串表示形式。 然后让指针(比如说* ptr)指向第一个位置。

让positionFromLeft成为你想要提取的角色的位置。

使用,

* (ptr + positionFromLeft)

会给你所需的数字。 希望有所帮助。

答案 10 :(得分:0)

我认为这是最简单的解决方案:

   int valuePosition(int value, int position) {
     int r;
     for(int i=0; i<=position; i++){
       r = value % 10;
       value = value / 10;
     }
     return r;
   }

第一个位置是0,如果你想要从1开始改变i&lt; = position with 1

答案 11 :(得分:0)

向 Number 类添加一个名为 getDigit 的实例方法,其签名如下: int getDigit (int digitNum) 当 digitNum 变量为统一级数指定数字编号 (0) 时,为十位数字指定 1 等等。如果存在这样的数字,该方法将返回适当的数字。否则该方法将返回 .-1 .-1 将返回 digitNum = 6 并且对于 4 返回 digitNN = 3 方法: value = 124571 if, to

列表项