【问题标题】:Extracting numbers from 3 digit number in C++ is it possible w/o using arrays?从 C++ 中的 3 位数字中提取数字是否可以不使用数组?
【发布时间】:2019-11-18 09:20:27
【问题描述】:

问题是: 编写一个函数,作为输入参数接收一个三位数的正数,结果必须得到相同的 3 位数除以中位数得到的最大和最小数之和。 示例:函数 438 的输入参数 相同位数最大的是843,最小的是348,所以应该计算(843 + 348)/4。

我试过了,结果没问题,但我的代码似乎很复杂,所以我想问有没有更好的方法?

提前致谢

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int check(int x) {

    int a, b, c, biggestNum, smallestNum, medianNum;

    a = x / 100;
    b = (x / 10) % 10;
    c = x % 10;

    if (a > b && a > c && b > c) {

        biggestNum= a * 100 + b * 10 + c;
        smallestNum= c * 100 + b * 10 + a;
        medianNum= b;

    }
    else if (a > b && a > c && b < c) {

        biggestNum= a * 100 + c * 10 + b;
        smallestNum= b * 100 + c * 10 + a;
        medianNum= c;

    }
    else if (b > a && b > c && a < c) {

        biggestNum= b * 100 + c * 10 + a;
        smallestNum= a * 100 + c * 10 + b;
        medianNum= c;

    }
    else if (b > a && b > c && a > c) {

        biggestNum= b * 100 + a * 10 + c;
        smallestNum= c * 100 + a * 10 + b;
        medianNum= a;

    }
    else if (c > a && c > b && a > b) {

        biggestNum= c * 100 + a * 10 + b;
        smallestNum= b * 100 + a * 10 + c;
        medianNum= a;

    }
    else if (c > a && c > b && a < b) {

        biggestNum= c * 100 + b * 10 + a;
        smallestNum= a * 100 + b * 10 + c;
        medianNum= b;

    }   

    cout << "Smallest number is: " << smallestNum<< " ,biggest is: " << biggestNum << " and median is: " << medianNum<< "." << endl;

    return (biggestNum + smallestNum) / medianNum;
}


int main() {

    cout << "Enter one 3 digit positive number: ";
    int x;
    cin >> x;

    float result = check(x);
    cout << "The result is: " << result << "." << endl;

    system("pause");
    return 0;
}

【问题讨论】:

  • 我会考虑重新排列 abc 中的值,以便 a 具有最大的数字,b 具有下一个最大的数字,@987654327 @ 有最小的数字。然后可以直接计算出最终的三个值。

标签: c++


【解决方案1】:

考虑到结果是用整数算术计算的,发布的代码不能真正产生正确的答案:

int check(int x)  // <- note the type of the returned value
{
    int biggestNum, smallestNum, medianNum;
    // ...
    return (biggestNum + smallestNum) / medianNum;  // <- This is an integer division
}

int main()
{
    int x; 
    // ...   
    float result = check(x);  // Now it's too late to get the right result
}

逻辑也没有考虑所有可能的情况,事实上它忽略了重复的数字和大的if else if 构造,缺少默认分支(最终无条件else),使那些未初始化的变量未确定这样下面的操作就给出了无意义的结果。

鉴于分配限制,我会写如下内容

#include <utility>

// The assignment is about 3-digit numbers, you should check that x is actually in
// the range [100, 999]. Note that one of the extremes is a special case.
// Well, both, actually.
double I_ve_no_idea_how_to_name_this(int x)
{
    constexpr int base = 10;
    int smallest = x % base;
    x /= base;
    int median = x % base;
    x /= base; 
    // Note that this "works" (extracting the third digit) even if
    // x isn't a 3-digit number. If you can assure the input is well
    // defined, you can simplify this.
    int biggest = x % base; 

    // Now we can sort the previous variables.
    using std::swap;
    if ( median < smallest ) {
        swap(median, smallest);
    }
    // Now I know that smallest <= median
    if ( biggest < median ) {
        swap(biggest, median);
    }
    // Now I know that median <= biggest
    // ...
    // Is that enough or am I missing something here?
    // Please think about it before running the code and test it.

    // Once the variables are sorted, the result is easily calculated
    return (biggest + smallest + base * (2 * median + base * (biggest + smallest)))
           / static_cast<double>(median);
}

【讨论】:

  • 谢谢,我今年开始是一名兼职 CS 学生,我们开始学习的第一门编程语言是 C++ 和 html,这在其他大学是正常的还是 .. 我觉得我们更好不学习 JS 或 Python 作为第一语言,但这只是我的看法 :)
【解决方案2】:

首先,您应该使用更具描述性的变量名称,并且应该在定义时初始化每个变量。这两个步骤极大地有助于消除复杂程序中的错误。我知道这并不复杂,但这是一个好习惯。其次,标准库可以帮助找到最大和最小的数字,从而使其余的变得简单。所以这是一个没有任何if 语句的示例。

最后,using namespace std; is a bad practice 应该避免。

double check(int x)
{
    int a = x / 100;
    int b = (x / 10) % 10;
    int c = x % 10;
    int bigdigit = std::max({ a, b, c }); // find largest
    int smalldigit = std::min({ a, b, c }); //find smallest
    int middledigit = a + b + c - bigdigit - smalldigit; // sum of all digits minus largest and smallest gives the remaining one
    int biggest = smalldigit + middledigit * 10 + bigdigit * 100;
    int smallest = smalldigit * 100 + middledigit * 10 + bigdigit;
    std::cout << "biggest: " << biggest << '\n';
    std::cout << "smallest: " << smallest << '\n';
    std::cout << "median: " << middledigit << '\n';
    return (1.0 * biggest + 1.0 * smallest) / (1.0 * middledigit); --using double instead of int, as result could be fractional
}

【讨论】:

    【解决方案3】:

    试试这个...

    int check(int x) {
        int a,b,c,temp;
        a = x/100;
        b = (x/10)%10;
        c = x%10;
        if(b>a){
            temp=a;
            a=b;
            b=temp;
        }
        if(c>b){
            temp=b;
            b=c;
            c=temp;
        }
        if(b>a){
            temp=a;
            a=b;
            b=temp;
        }
        cout << "smallest: " << a+(b*10)+(c*100) << "\n";
        cout << "biggest: " << (a*100)+(b*10)+c << "\n";
        cout << "median: " << b << "\n";
        return (((a+c)*100)+(2*b*10)+(a+c))/b;
    }
    

    【讨论】:

    • 使用更少的变量(内存空间),更简洁。
    【解决方案4】:

    检查此检查功能。

    int check(int x) {
    
        if(x >= 1000) x %= 1000;  //or return -1;
    
        //get digits
        int M = x/100;
        int C = (x/10)%10;
        int m = x%10;
    
        //unrolled bubble sort.
        if(M < C) swap(M,C);
        if(C < m) swap(C,m);
        if(M < C) swap(M,C);
    
        //simplified formula
        return ((m+M)*(101))/C + 20;
    
    }
    
    //derivation of formula
    B = M*100 + C*10 + m;
    s = m*100 + C*10 + M;
    B+s = (m+M)*100 + C*20 + (m+M)
        = (m+M)*(100 + 1) + C*20
    (B+s)/C = ((m+M)*(100 + 1) + C*20)/C
            = ((m+M)*(101))/C + 20
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 2017-03-02
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多