轻松解决困难的C++解决方案

轻松解决困难的C++解决方案,c++,digits,logarithm,C++,Digits,Logarithm,所以,首先,这似乎是你第一次开始学习编程时在学校接受的练习之一。Weeeell事实证明不仅仅如此 主要练习相当简单,任何人都可以解决: 编辑:我得到了原始的翻译声明: 为一个非递归函数编写两个实现,该函数有一个参数n=一个最多9位的自然数,它返回通过将n的第一位数字重新定位到该数字的末尾而得到的数字。例如,如果n为4273,则函数应返回2734。 C1允许您使用循环。 C2不允许使用循环 好吧,首先很简单 long function(long n) { long

所以,首先,这似乎是你第一次开始学习编程时在学校接受的练习之一。Weeeell事实证明不仅仅如此

主要练习相当简单,任何人都可以解决:

编辑:我得到了原始的翻译声明:

为一个非递归函数编写两个实现,该函数有一个参数n=一个最多9位的自然数,它返回通过将n的第一位数字重新定位到该数字的末尾而得到的数字。例如,如果n为4273,则函数应返回2734。 C1允许您使用循环。 C2不允许使用循环

好吧,首先很简单

    long function(long n)
    {
        long newNumber = 0, p = 1;

        while(n>9)
        {
            newNumber = n%10 * p + newNumber;
            n = n/10;
            p = p*10;
        }

        return newNumber*10+n;
    }
现在做同样的事情,不使用任何循环。你不知道这个数字有多长,可能是3位数,可能是9位数。此外,整个工作必须由一个功能单独完成

现在,当然,一个简单的解决办法,也是一个可怕的办法,就是写

    if(n<100)
        return n%10*10+n/10;
    else
        if(n<1000)
            return n%100*10+n/100;
        else
            if...
    ...
    ...
    ...
但是我不记得我在高中时曾经教过C++中的LN函数,他们也不知道。所以还有其他对初学者友好的方法吗

限制条件清单:

单一功能 无回路 仅接收最多9位数字形式的1个参数 返回通过将第一个数字重新定位到数字末尾而形成的数字 没有字符串,即使这是合法的解决方案 编辑:所以在此期间,我被告知提出这个问题的解决方案是使用对数的解决方案。。。。。这很奇怪,因为他们的学生从来没有在C++中使用过。我的猜测是,他们把声明搞砸了,这是他们拯救的借口。

使用。以下是一些未经测试的代码:

long f(long n, long base) 
{
    if(n <= 9)
        return n;    // last 'iteration'
    else
        return (base * (n % 10)) + f(n / 10, 10 * base);
}

....
f(1234, 10);
使用。以下是一些未经测试的代码:

long f(long n, long base) 
{
    if(n <= 9)
        return n;    // last 'iteration'
    else
        return (base * (n % 10)) + f(n / 10, 10 * base);
}

....
f(1234, 10);
编辑1:更改为不使用循环。 编辑2:此解决方案不再满足OP设置的要求。不过,我将把我的答案留在这里,供将来有这个问题的读者参考,他们可能会在解决方案中使用字符串

#include <iostream>
#include <string>

int main() {
    long testNum = 0;
    long newNum;
    std::cout << "Enter a number: ";
    std::cin >> testNum;

    std::string stringFromLong;

    stringFromLong = std::to_string(testNum);
    char tempChar = stringFromLong[0];

    std::string newString = stringFromLong.substr(1, stringFromLong.length() - 1) + tempChar;

    newNum = std::stol(newString);
    std::cout << newNum << std::endl;
    return 0;
}
这将接收一个数字并将其转换为字符串。它将保存temp变量中字符串的第一个字符。从第二个字符开始,到最后一个字符,再加上放在末尾的临时字符,将生成一个新字符串。然后它使用std::stol将字符串转换为long for输出。

编辑1:更改为不使用循环。 编辑2:此解决方案不再满足OP设置的要求。不过,我将把我的答案留在这里,供将来有这个问题的读者参考,他们可能会在解决方案中使用字符串

#include <iostream>
#include <string>

int main() {
    long testNum = 0;
    long newNum;
    std::cout << "Enter a number: ";
    std::cin >> testNum;

    std::string stringFromLong;

    stringFromLong = std::to_string(testNum);
    char tempChar = stringFromLong[0];

    std::string newString = stringFromLong.substr(1, stringFromLong.length() - 1) + tempChar;

    newNum = std::stol(newString);
    std::cout << newNum << std::endl;
    return 0;
}

这将接收一个数字并将其转换为字符串。它将保存temp变量中字符串的第一个字符。从第二个字符开始,到最后一个字符,再加上放在末尾的临时字符,将生成一个新字符串。然后,它使用std::stol将字符串转换为long for输出。

如果允许您使用字符串,您将能够执行类似的操作。它使用一个字符串基本上将数字视为一个向量,使此任务变得简单

然而,就目前的情况而言,从问题的编辑3开始,这是不允许的,我在编写和测试此解决方案时没有看到这一点。不过,我会把它贴在这里,以防将来有人直接问这个问题,而且不限于不使用字符串

#include <string>
#include <cstdlib>

long firstDigitToEnd(long n) {
    bool neg = (n < 0);                  // Preserve signed-ness.
    if (neg) { n = labs(n); }            // Obtain absolute value, for convenience.

    std::string num = std::to_string(n); // Convert number to string.

    char first = num[0];                 // Obtain first digit.
    num.erase(0, 1);                     // Erase first digit, shift rest forwards.
    num.push_back(first);                // Append first digit to end.

    // And we're done.  Convert string back to number, restore signed-ness.
    return (neg ? -(std::stol(num)) : std::stol(num));
}

// -----

// Testing code.

#include <iostream>
#include <limits>

void readCin(long& l);

int main() {
    long n = 0;

    do {
        if (n) {
            std::cout << "Result: " << firstDigitToEnd(n) << std::endl;
        }

        std::cout << "Input number, or 0 to exit: ";
        readCin(n);
    } while (n);

    std::cout << "...And we're gone." << std::endl;
}

// Read a number, or clear the buffer if non-number is entered.
void readCin(long& l) {
    using std::cin;

    cin >> l;
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    if (cin.fail()) {
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        l = 0;
    }
}

查看它的实际操作。

如果允许您使用字符串,您将能够执行类似的操作。它使用一个字符串基本上将数字视为一个向量,使此任务变得简单

然而,就目前的情况而言,从问题的编辑3开始,这是不允许的,我在编写和测试此解决方案时没有看到这一点。不过,我会把它贴在这里,以防将来有人直接问这个问题,而且不限于不使用字符串

#include <string>
#include <cstdlib>

long firstDigitToEnd(long n) {
    bool neg = (n < 0);                  // Preserve signed-ness.
    if (neg) { n = labs(n); }            // Obtain absolute value, for convenience.

    std::string num = std::to_string(n); // Convert number to string.

    char first = num[0];                 // Obtain first digit.
    num.erase(0, 1);                     // Erase first digit, shift rest forwards.
    num.push_back(first);                // Append first digit to end.

    // And we're done.  Convert string back to number, restore signed-ness.
    return (neg ? -(std::stol(num)) : std::stol(num));
}

// -----

// Testing code.

#include <iostream>
#include <limits>

void readCin(long& l);

int main() {
    long n = 0;

    do {
        if (n) {
            std::cout << "Result: " << firstDigitToEnd(n) << std::endl;
        }

        std::cout << "Input number, or 0 to exit: ";
        readCin(n);
    } while (n);

    std::cout << "...And we're gone." << std::endl;
}

// Read a number, or clear the buffer if non-number is entered.
void readCin(long& l) {
    using std::cin;

    cin >> l;
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    if (cin.fail()) {
        cin.clear();
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        l = 0;
    }
}

查看它的实际操作。

这里有一个使用std::log10和std::pow的解决方案需要包含


这里有一个使用std::log10和std::pow的解决方案需要include


有了我们在编译时知道的INT_MAX的约束,即使很难看,也很简单

if(x > 999999999)
   ndigits =  9;
else if(x > 99999999)
   ndigits = 8;
等等,; 然后可以使用ndigit和乘法。除法和模结合十的幂得到你想要的结果


然而,如果x是无界的,那么如果不使用某种形式的循环,就无法知道它的大小

有了我们在编译时知道的INT_MAX的约束,即使很难看,也很简单

if(x > 999999999)
   ndigits =  9;
else if(x > 99999999)
   ndigits = 8;
等等,; 然后可以使用ndigit和乘法。除法和模结合十的幂得到你想要的结果


然而,如果x是无界的,那么如果不使用某种形式的循环,就无法知道它的大小

你考虑过使用递归函数吗?你必须使用数字吗?这对于字符串来说是微不足道的。当在std之前讨论递归之类的东西时,我总是很恼火

::string。转换为字符串涉及一个循环。递归本质上是一个while循环,因为必须有停止递归的测试。当有人说我们没有想过如何在编程中使用数学时,我觉得很有趣。你有没有考虑过使用递归函数?你必须使用数字吗?这对于字符串来说是微不足道的。当在std::string之前涉及递归之类的内容时,我总是感到恼火。转换为字符串涉及到一个循环。递归本质上是一个while循环,因为必须有停止递归的测试。当有人说我们没有想过如何在编程中使用数学时,我觉得很有趣。在这一点上,函数的参数数量不再与OP给出的参数数量相同,因此这是否算作解决方案值得怀疑。@FrerichRaabe-好的观点,但是很容易修复-用一个只有一个变量的外部函数来包装它。请注意,OP写了“整个工作必须由一个函数单独完成。”降低参数数量的一个丑陋的修正可能是将base变成一个静态变量,比如。@GabrielEm学习的时间太长了。任何因提前阅读而惩罚学生的讲师都应该被开除。在这一点上,函数的参数数量不再与OP给出的参数数量相同,因此这是否算作解决方案值得怀疑。@FrerichRaabe-好的观点,但是很容易修复-用一个只有一个变量的外部函数来包装它。请注意,OP写了“整个工作必须由一个函数单独完成。”降低参数数量的一个丑陋的修正可能是将base变成一个静态变量,比如。@GabrielEm学习的时间太长了。任何因学生提前阅读而惩罚学生的老师都应该被开除。如果你要做的只是输入并输入数字,为什么还要费心输入数字呢?一路上都要系好绳子。也就是说,您如何知道字符串的内容是一个数字?但你还是有这个问题。建议使用if std::cin>>testNum以防止使用未经检查的输入的未定义行为。我使用cin和cout将输入作为long,并输出long,因为这是要求。最多使用9位数字的函数未定义该数字的存储格式和表示形式。在现实世界中,一个写得不好的需求文档可能会花费很多钱。@user4581301:是的。我假设这是一项要求,因为OP就是这么用的。OP只是澄清了规则。字符串现在已完全从表中删除。字符串在CompSci中不受欢迎。如果你要做的只是输入并输出数字,为什么还要为数字而烦恼呢?一路上都要系好绳子。也就是说,您如何知道字符串的内容是一个数字?但你还是有这个问题。建议使用if std::cin>>testNum以防止使用未经检查的输入的未定义行为。我使用cin和cout将输入作为long,并输出long,因为这是要求。最多使用9位数字的函数未定义该数字的存储格式和表示形式。在现实世界中,一个写得不好的需求文档可能会花费很多钱。@user4581301:是的。我假设这是一项要求,因为OP就是这么用的。OP只是澄清了规则。字符串现在已完全从表中删除。字符串在CompSci中不受欢迎。这一个最接近于我听到的那句话的预期,因此我将其标记为可接受的解决方案,尽管在这一线程中有很多创造性的解决方案或多或少地遵循了约束。这一个最接近于我听到的那句话的预期,因此,我将此标记为可接受的解决方案,尽管在这个线程中或多或少有许多创造性的解决方案遵循约束。