我想创建一个函数,它将是一个数字和我想要检索的数字的位置,
int getDigit(int value, int positionFromLeft)
说,getDigit(534,2)将返回3.
编写此函数的最简单/最有效的方法是什么?
答案 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
列表项