简体   繁体   English

如何从第一个开始扫描整数中的奇数位?

[英]How to scan for odd digits in an integer, starting from the first?

I need the user to input an integer with indefinite number of digits, and then I have to show all the odd digits in this integer starting from the first digit.我需要用户输入一个位数不定的整数,然后我必须显示这个整数中从第一位开始的所有奇数位。

long long num, a;
cin >> num;

while (num > 0)
{
    a = num % 10;
    num = num / 10;

    if (a % 2 != 0)
    {
        cout << a;
    }
}

This code shows all the odd digits but from the end of the integer.此代码显示所有奇数,但从整数的末尾开始。

When a 'natural' sequence of events or operations leads you to get the correct results but in reverse order, then a stack is most likely the simplest tool to fix things.当事件或操作的“自然”序列使您获得正确的结果但顺序相反时,堆栈很可能是解决问题的最简单工具。

Simply push each value onto the stack as you generate them;只需在生成每个值时将它们压入堆栈; and then, when done, just run through that stack, and pop (and display) its contents until the stack is empty.然后,完成后,只需运行该堆栈,并弹出(并显示)其内容,直到堆栈为空。

Here's a version of your code using the std::stack container :这是使用std::stack容器的代码版本:

#include <iostream>
#include <stack>

int main()
{
    long long num, a;
    std::cin >> num;
    std::stack<long long> digits;
    while (num > 0) {
        a = num % 10;
        if (a % 2) digits.push(a);
        num = num / 10;
    }
    while (!digits.empty()) {
        std::cout << digits.top();
        digits.pop();
    }
    std::cout << std::endl;
    return 0;
}

There will be more efficient code solutions, for sure, but the above is both easy to implement and clearly understandable.肯定会有更高效的代码解决方案,但上述方案既易于实现又易于理解。


Note that, as pointed out by user4581301 , the above code uses the long long data type, which has a limited size (that solution is based on the code you gave).请注意,正如user4581301所指出的,上面的代码使用long long数据类型,它的大小有限(该解决方案基于您提供的代码)。 However, if you truly want an arbitrary, indefinite number of digits (with no implied size limit), then you can read your input as a string and process that.但是,如果您真的想要任意的、无限数量的数字(没有隐含的大小限制),那么您可以将您的输入读取为字符串并进行处理。

This also makes the solution much simpler, as the 'natural' analysis of that string will produce the results in the correct order, and you only need 'copy' the relevant (ie odd) digits from one string to another:这也使解决方案变得更简单,因为对该字符串的“自然”分析将以正确的顺序产生结果,您只需要将相关(即奇数)数字从一个字符串“复制”到另一个字符串:

#include <iostream>
#include <string>

int main()
{
    // (1) Read "arbitrary length" number as a string ...
    std::string number;
    std::cin >> number;
    // (2) Create a new string and append all odd digits to it ...
    std::string digodd{};
    for (auto c : number) {
        if (!isdigit(c)) {
            // Error handling for bad input ...
            std::cout << "Error: Non-digit found!";
            return -1;
        }
        auto digit = c - '0'; // Guaranteed to work by the Standard
        if (digit % 2) digodd += c;
    }
    // (3) Display the result string... 
    std::cout << digodd << std::endl;
    return 0;
}

I mean, technically, based on how the question is phrased, the answer is this.我的意思是,从技术上讲,根据问题的表述方式,答案是这样的。 Works for an indeterminate number of digits - even more than available RAM:适用于不确定的位数 - 甚至超过可用的 RAM:

#include <iostream>
#include <conio.h>

int main()
{
    while (true)
    {
        auto ch = (const char)_getch();
        if ( (ch == '1') || (ch == '3') || (ch == '5') || (ch == '7') || (ch == '9') )
        {
            std::cout << ch;
        }
    }
}

If you are not considering negative numbers then it makes more sense to declare the variable num as having the unsigned integer type unsigned long long int .如果您不考虑负数,那么将变量num声明为具有无符号整数类型unsigned long long int更有意义。

A simple way to do the task is to write a recursive function.完成这项任务的一个简单方法是编写一个递归函数。

Here is a demonstration program.这是一个演示程序。 As the user input I am using the maximum value of an object of the type unsigned long long int.作为用户输入,我使用了 unsigned long long int 类型的对象的最大值。

#include <iostream>
#include <limits>

std::ostream & output_odd_digits( unsigned long long int num, 
                                  std::ostream &os = std::cout )
{
    const unsigned long long int Base = 10;
    
    unsigned long long int digit = num % Base;
    
    if (  num / Base != 0 )
    {
        output_odd_digits( num / Base, os );
    }

    if ( digit % 2 != 0  ) os << digit;
    
    return os;
}

int main() 
{
    unsigned long long int num = std::numeric_limits<unsigned long long int>::max();
    
    std::cout << num << '\n';
    
    output_odd_digits( num ) << '\n';
    
    return 0;
}

The program output is程序输出是

18446744073709551615
17737955115

A non-recursive function can look the following way非递归函数可以如下所示

#include <iostream>
#include <limits>

std::ostream & output_odd_digits( unsigned long long int num, 
                                  std::ostream &os = std::cout )
{
    const unsigned long long int Base = 10;
    
    unsigned long long int n = 1;
    
    for ( unsigned long long int tmp = num; tmp / Base != 0; tmp /= Base )
    {
        n *= Base;
    }
    
    for ( ; n != 0; n /= Base )
    {
        unsigned long long int digit = num / n;
        
        if ( digit % 2 != 0 ) os << digit;
        
        num %= n;
    }
    
    return os;
}

int main() 
{
    unsigned long long int num = std::numeric_limits<unsigned long long int>::max();
    
    std::cout << num << '\n';
    
    output_odd_digits( num ) << '\n';
    
    return 0;
}

The program output is the same as shown above程序输出与上图相同

18446744073709551615
17737955115

As you can see in the both cases there is no any need to use a standard container that occupies an additional memory.正如您在这两种情况下所看到的,不需要使用占用额外内存的标准容器。

Here is one more demonstrative program where a separate function is not used.下面是一个没有使用单独函数的演示程序。

#include <iostream>

int main() 
{
    const unsigned long long int Base = 10;

    while ( true )
    {
        unsigned int num;
        
        std::cout << "Enter a non-negative number (0 - exit ): ";
        
        if ( !( std::cin >> num ) || ( num == 0 ) ) break;
        
        unsigned long long int n = 1;
    
        for ( unsigned long long int tmp = num; tmp / Base != 0; tmp /= Base )
        {
            n *= Base;
        }
    
        for ( ; n != 0; n /= Base )
        {
            unsigned long long int digit = num / n;
        
            if ( digit % 2 != 0 ) std::cout << digit;
        
            num %= n;
        }
        
        std::cout << '\n';
    }

    return 0;
}

The program output might look like程序输出可能看起来像

Enter a non-negative number (0 - exit ): 1234567890
13579
Enter a non-negative number (0 - exit ): 0

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

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