所以,首先,这个SEEMS就像你第一次开始学习编程时在学校收到的那些练习之一。 Weeeeell证明不仅如此。
主要练习相当简单,任何人都可以解决:
编辑:我得到了原始(已翻译)声明:
为非递归函数编写两个实现,这个函数有一个参数(n =最多9位的自然数),它返回通过将n的第一个数字重新定位到数字末尾得到的数字。例如,如果n是4273,则函数应返回2734。 C1)你被允许使用循环。 C2)你不允许使用循环。
Aight,首先很容易。
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...
...
...
...
但这不是最理想的代码。有没有其他干净的方式这样做?到目前为止,我没有人问过任何其他方式。
还有另外一件事。这应该是初学者可以解决的(我在帮助我的一个伙伴解决他的一个练习时遇到了这个)所以使用一些花哨的图书馆以某种方式帮助初学者永远不会知道不应该是一个有效的解决方案(但我对所有的想法很好奇。)
此外,我知道您可以使用以下公式找出数字所具有的位数:
|的log(n)| + 1 = ln(n)/ ln(10)+ 1可以在C ++中使用如下:
long function(long n)
{
int k; // number of digits of n
k = (int) (ln(n) / ln(10)) + 1; // applying the formula
long p = pow(10, k-1);
return n%p * 10 + n/p;
}
但是我不记得在高中的时候曾经被C ++中的ln函数教过,他们也不是。那么......有没有其他初学者友好的方式呢?
约束列表:
编辑:所以同时我被告知解决方案提出这个问题的是使用对数的那个......这很奇怪,因为他们的学生从未在c ++中使用过。我的猜测是,他们搞砸了这句话,这是他们的“救恩借口”。
答案 0 :(得分:3)
这是一个使用std :: log10和std :: pow(需要#include <cmath>
)的解决方案。
long func(long in) {
long base = std::pow(10, (int)std::log10(in));
long left_most_num = in / base;
long body = in - left_most_num * base;
return body * 10 + left_most_num;
}
答案 1 :(得分:1)
使用bug。这是一些未经测试的代码:
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);
答案 2 :(得分:1)
如果你被允许使用字符串,你就可以做这样的事情。它使用一个字符串来基本上将数字视为一个向量,使这个任务变得微不足道。
现在看来,这是不允许的(截至问题编辑#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;
}
}
在行动here中查看。
答案 3 :(得分:0)
编辑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输出。
答案 4 :(得分:0)
由于我们在编译时知道INT_MAX的约束,如果丑陋的话,它是微不足道的。
if(x > 999999999)
ndigits = 9;
else if(x > 99999999)
ndigits = 8;
等; 然后你可以使用ndigits和multiplication。除以10和10的相关幂来模拟得到你想要的结果。
然而,如果x是无界的,那么在没有使用某种形式的循环的情况下,本身就无法知道它的大小。