简体   繁体   English

使用ONLY整数运算查找数字的第一个数字

[英]Find first digit of a number using ONLY integer operations

I can't understand how to solve the problem that the teacher gave me. 我无法理解如何解决老师给我的问题。

Given a number N (0 <= N <= 100), find its first digit. 给定数字N(0 <= N <= 100),找到它的第一个数字。

For example: 例如:

input: 100
result: 1

input: 46
result: 4

input: 3
result: 3

It seemed easy at first, but (as the teacher said) it should be done using ONLY integer data types (in other words, using + , - , * , / and % operators). 起初看起来很容易,但(正如老师所说)应该使用ONLY整数数据类型(换句话说,使用+-*/%运算符)。 Is it even possible to do it this way? 甚至可以这样做吗?

I just can't realize how to extract the first digit from a variable-length number without using things like log10, conditions, "while" loop or string conversion. 我只是无法实现如何从可变长度数字中提取第一个数字而不使用log10,条件,“while”循环或字符串转换等内容。

Without any conditionals: 没有任何条件:

int H= N / 100;       // Hundreds digit
int T= (N / 10) % 10; // Tens digit
int U= N % 10;        // Units digit

int h= H;                      // Hundreds flag
int t= (T + 9) / 10 * (1 - h); // Tens flag
int u= (1 - t) * (1 - h);      // Units flag

int Answer= u * U + t * T + h * H; // Combination

Edit: Now tested for 0 and 100: 编辑:现在测试0和100:

var result = n / 10 * (1 - n / 100) + n / 100 + (109 - n) / 100 * n;

How it works: 这个怎么运作:

n        | n / 10 * (1 - n / 100) | n / 100 | (109 - n) / 100 * n
-----------------------------------------------------------------
10 - 99  | 1 - 9                  | 0       | 0
-----------------------------------------------------------------
100      | 0                      | 1       | 0
-----------------------------------------------------------------
0 - 9    | 0                      | 0       | 0 - 9

Use a while loop, and keep dividing the input number by 10, so long as we are starting with a value which is greater than or equal to 10. When the modified input is less than ten, then it means we have stripped off all digits to the right, except for the "first" digit. 使用while循环,并将输入数字除以10,只要我们从一个大于或等于10的值开始。当修改后的输入小于10时,则表示我们已经删除了所有数字在右边,除了“第一”数字。

int input = 100;

while (input >= 10)
{
    input /= 10;
}

Console.WriteLine("First digit is: {0}", input);

Demo 演示

This is a non-generic response, and only works because the domain is limited. 这是一种非通用的响应,只有在域有限的情况下才有效。 The idea is to return all the digits (hundred's, ten's, and one's) smooshed together." Some thoughts on specific ranges of numbers: 我们的想法是将所有数字(百分之一,十分之一和一分之一)压缩在一起。“对特定数字范围的一些想法:

100 is easy because the ten's and one's units are both zero. 100很容易,因为十和一个单位都是零。 There are no other three digit numbers, which is good, because anything with a non-zero one's or ten's place will cause problems below. 没有其他三位数字,这是好的,因为任何非零或十位的东西都会导致下面的问题。

All numbers less than 100 can include the hundred's digit in the response because it will always be zero. 所有小于100的数字都可以包含响应中的百位数,因为它总是为零。

Any multiple of 10 is easy, just include the each hundred's ten's and one's value, because the other digits are zero. 任何10的倍数都很容易,只包括每一百的十和一的值,因为其他数字为零。

The tricky part is the one's place. 棘手的部分是一个人的位置。 There needs to be a way to "cancel out" this value if a larger digit is supposed to be returned. 如果应该返回更大的数字,则需要有一种“取消”该值的方法。 For example, 87, we want the 8 but want to cancel out the 7. 例如,87,我们想要8,但想要取消7。

This leads to the idea 这导致了这个想法

(ten - 9)*(ten - 8)*(ten - 7)*(ten - 6)*(ten - 5)*(ten - 4)*(ten - 3)*(ten - 2)*(ten - 1)

What happens is that any time the ten's place is non-zero, the above will evaluate to zero. 会发生的是,当十点的位置非零时,上面将评估为零。 So we can multiply the one's place by this to zero out the one's place when the ten's place is non-zero. 因此,当十位的非零时,我们可以将这个位置乘以这个位置。 However, there's a problem when the ten's place is zero. 但是,十点的位置为零时会出现问题。 In that case, we're off by a factor of 9! 在那种情况下,我们减少了9倍! (nine factorial = 362880) and the wrong sign. (九阶因子= 362880)和错误的符号。 This is why an extra minus sign is included, and divide out by 362880 to get the right answer when ten's place is zero. 这就是为什么包含一个额外的减号,并除以362880,以便在十位为零时得到正确的答案。

public int GetFirstDigit(int n)
{
    var hundred = (n % 1000) / 100;
    var ten = (n % 100) / 10;
    var one = n % 10;

    return hundred + ten + one*
    (
    -(ten - 9)*(ten - 8)*(ten - 7)*(ten - 6)*(ten - 5)*(ten - 4)*(ten - 3)*(ten - 2)*(ten - 1)
    ) / 362880
    ;
}

check with 检查

Enumerable.Range(0, 101).ToList().ForEach(x => Console.WriteLine(x + ": " + GetFirstDigit(x)));
static int Result(int input)
{
    return input/100 + (input%100/input)*input/10 + (input%10/input)*input;
}
  • input/100 will return 1 if and only if input equals 100, else 0 当且仅当input等于100时, input/100将返回1,否则返回0
  • (input%100/input) will return 1 if and only if input < 100 , else 0 (input%100/input)input < 100(input%100/input)将返回1,否则为0
    • if input is lower than 10, input/10 will be 0 如果input低于10,则input/10将为0
  • (input%10/input) will return 1 if and only if input < 10 , else 0 (input%10/input)input < 10(input%10/input)将返回1,否则为0

Caution 警告

This would break if input == 0 , see @quanik's answer to handle 0. 如果input == 0 ,这会破坏,请参阅@quanik的处理0 的答案

However, it will work for 1-999. 但是,它将适用于1-999。

I tried to solve the case but without success, I can only achieve finding the first digit if the N is 1 - 100. Here is my source code for it. 我试图解决这个案子,但没有成功,我只能找到第一个数字,如果N是1 - 100.这是我的源代码。 Hope it helps https://dotnetfiddle.net/6XyOfd 希望它有助于https://dotnetfiddle.net/6XyOfd

if (N < 10)
  Output(N)
else if (N < 100)
  Output(N / 10)
else
  Output(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM