如何在 c++ 中将第一个数字移动到数字的末尾

How to move the first digit to the end of a number in c++?

本文关键字:数字 移动 第一个 c++      更新时间:2023-10-16

这是代码:

#include <iostream>
using namespace std;
int main ()
{
int n;
cin >> n;
int first = n;
while (first>=10)
{
first/=10;
}
cout << first << endl;
}

在上面的代码中,我试图获取正数的第一个数字,我想做的是像这样把它放在最后一个数字之后,例如:1934 -> 9341.

使用 std::to_string 将数字转换为字符串,使用 std::rotate 执行左旋转,并使用 std::stoull 函数转换回数字:

std::string s = std::to_string(n);
std::rotate(s.begin(), s.begin() + 1, s.end());
n = std::stoull(s);

包含所有标头:

#include <iostream>
#include <string>
#include <algorithm>
int main() {
unsigned long long n = 1934;
std::string s = std::to_string(n);
std::rotate(s.begin(), s.begin() + 1, s.end()); // left rotation
n = std::stoull(s);
std::cout << n; // 9341
}

这是一个不使用字符串或浮点函数/算术的简单解决方案。 使用pow()等函数可能会遇到此问题中概述的问题。

#include <iostream>
int main()
{
unsigned long long n = 1934L;
// save the original
unsigned long long final_number = n;
// multiplying factor
unsigned long long mult = 1;
// start by making sure we do not loop one too many times to 
// calculate the multiplier
n /= 10;
while (n > 0)
{
// determines the multiplication factor after the loop 
mult *= 10; 
// strip off digit from number
n /= 10;
}
// create the final number from the original and the multiplication factor
final_number = (final_number % mult) * 10 + final_number / mult;
std::cout << final_number << "n";
}

现场示例

基本上我们通过循环计算多少位数,同时将乘法因子增加 10。 然后在循环之后,使用模、乘、除和加法构造数字。

例如,在循环之后,final_number将是

(1934 % 1000) * 10 + 1934 / 1000 =
934 * 10 + 1934 / 1000 = 
9340 + 1934 / 1000 =
9340 + 1 =
9341

注意:我在这里查看了生成的汇编语言,并惊讶于编译器能够找出代码的意图,并在编译时计算了 9341。 我怀疑pow解决方案或浮点方法会产生这些结果。

您可以修改循环,使其不仅获取第一个数字,还可以同时计算位数(这是循环迭代的次数)。然后,根据需要使用%* 10来修改n

假设我们有正整数作为输入。

  1. 获取最高有效数字

    MSD=floor(X/pow(10,floor(log10(X))));
    
  2. 获取数字的其余部分

    Rest=X%pow(10,floor(log10(X)));
    
  3. 将其余部分提高到适当的值

    Rest=Rest*10;
    
  4. 添加前一个最高有效数字

    Y=Rest+MSD.
    

分解示例:

X=54321;                             // 54321
log10(X)    // 4.734...
floor(...     )   // 4
pow(10,...            )  // 10000
X/...                      // 5.4321
MSD=floor(...                      );// 5
pow(10,floor(log10(X))    // 10000
X%...                       // 4321
10*...                         // 43210
Y=MSD+...                        ;   // 43215

我首先要说我不是 c++ 程序员;所以我并不是说这段代码很好,只是它有效并且遵循您的方法!

在我向您展示对代码进行最小编辑以获得所需内容之前,我将向您介绍如何操作,并举一个示例:我们假设您要将2345转换为3452

  • 您首先要找到输入(n)的最有效数字(first
  • )
  • 您现在需要从前面删除该数字。这很简单:
    • 我们已经有一个循环,我们将first除以 10,所以让我们重用它
    • 创建一个从 1 开始的数字(我们称之为bigness),每个循环都乘以 10。
  • 您现在有 3 个数字:
    • n=2345
    • first=2
    • bigness=1000

这就是你所需要的!

您可以从n中减去first * bigness以从前面删除数字 -345

您可以将其乘以10并加上first将数字放在末尾 -3452

这是结束代码:

#include <iostream>
using namespace std;
int main ()
{
int n;
cin >> n;
int first = n;
int bigness = 1;
while (first >= 10)
{
first /= 10;
bigness *= 10;
}
n = n - (first * bigness);
n = (n * 10) + first;
cout << n;
}

请注意,这将给像20000这样的数字留下问题 - 它们变成 2,因为我们的代码不知道我们想要00002.使用类似printf的东西来维护位数很容易解决这个问题,但这意味着循环中的另一个变量,从 1 开始,计算我们需要的位数。

由于C++整数最多有十几个数字,代码可以使用简单的递归解决方案:

unsigned reverse_helper(unsigned x) {
if (x < 10) {
return x;
}
unsigned last = reverse_helper(x/10);
cout << x%10;
return last;
}
void reverse(unsigned x) {
cout << reverse_helper(x)) << endl;
}

测试代码

int main(void) {
reverse(0);
reverse(9);
reverse(10);
reverse(1934);
reverse(1234567890);
}
0
9
01
9341
2345678901

不使用字符串的解决方案。它确实使用std::stack,并且可能不会赢得任何效率奖项,但它应该非常简单易懂。

#include <stack>
#include <iostream>
int main()
{
int num = 1934;
std::stack<int> digits;
// Break the number into digits, pushing them onto a stack
while (num)
{
auto digit = num % 10;
digits.push(digit);
num /= 10;
}
// Get the first digit from the top of the stack and save it
auto first = 0;
if (!digits.empty())
{
first = digits.top();
digits.pop();
}
// Pop the remaining digits off the stack and print them
while (!digits.empty())
{
std::cout << digits.top();
digits.pop();
}
// Print the first digit on the end
std::cout << first << 'n';
}

编辑:修复了错误,如果num == 0。请注意,负数未正确处理,但我不确定在这种情况下所需的行为是什么。使用unsigned而不是int可能是一个好主意。

这是一个不使用字符串的版本。

//There's also a builtin log10 function but you can write your own if you want to:
int log10(int nbr) {
return log(n) / log(10);
}
//....
int first_digit = n / (int)pow(10, log10(n));
int everything_else = n % (int)pow(10, log10(n));

确保包含math.h

它利用了float -> int转换始终在C++中四舍五入为零的事实。因此,(int)log10(101)将返回 2,因此pow(10, (log10(n)))会将舍入的每个数字四舍五入为10/100/1000/etc。其余的只是简单的除法和模。

这是编程和数学+编程竞赛的典型元素,所以我不会给出完整的答案,但我会说:

  • 使用字符串几乎肯定不是 CPU 时间效率最高的解决方案。
  • 您已经有了第一个(最重要的)数字。修改问题中的代码,您可以计算 10 的适当幂以从原始数字中减去第一位数字。
  • 请注意,n * 10向左移动数字并留下一个"洞",稍后您可以根据需要填充。(如果这对您来说很明显,请道歉。
  • 你可以只使用整数运算,没有浮点数,没有函数(logexp)来完成所有这些工作。其他解决方案已经显示了完整的算法;我强调你可以没有浮点数和日志。
  • 小心 0 和负数。

因为std::string已经有很多解决方案,我试图在没有它的情况下做到这一点,这是我的结果。 我希望这有所帮助。

#include <iostream>
#include <cmath>
using namespace std;
int removeFirst(int n)
{
int tmp(0);
for (int i(0);; ++i)
{
int m = n % 10;
n /= 10;
if (n != 0)
{
tmp += pow(10, i) * m;
}
else
{
break;
}
}
return tmp;
}
int main()
{
int input, first, withoutFirst;
cin >> input;
withoutFirst = removeFirst(input);
while (input >= 10)
{
input /= 10;
}
first = input;
cout << withoutFirst << first << endl;
}

使用的帮助:尝试删除任何数字的第一个数字

问候。

已经有一些答案string,到目前为止还有一个答案没有string.使用string是最有效的方法。但是,如果 OP 想通过计算方法并使用整数来解决它,这就是我尝试过的。当不使用string时,在这种情况下,我想这种解决方案更有效。

#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
int n, digits, firstDigit, firstDigitToLast;
cin >> n;
digits = (int)log10(n);
firstDigit = (int)(n / pow(10, digits));
firstDigitToLast = n % ((int) pow(10, digits));
firstDigitToLast *= 10;
firstDigitToLast += firstDigit;
cout << firstDigitToLast << endl;
}
std::string s = std::to_string(n);
s += s.front();
s.erase(0, 1);
n = std::stoull(s);

这:

  1. 将数字转换为字符串。
  2. 第一个字符添加到末尾。
  3. 删除第一个字符。
  4. 并将结果转换回unsigned long long.

现场示例

我会使用log10%

int num = 8907;
int num_digits = log10(num); // Value of 3 for 8907
int pwr = pow(10, num_digits); // Value of 1000 for 8907
int ones_place = num % 10; // 7
int bigs_place = num / pwr; // 8
int cur_msd = bigs_place * pwr; // 8000
int new_msd = ones_place * pwr; // 7000
num -= cur_msd;
num += new_msd;
num -= ones_place;
num += bigs_place;
cout << num << endl;

此代码为我输出 7908。


编辑

我误读了帖子。我以为您希望交换LSB和MSB,而不是旋转。

将最后 4 行替换为

num -= cur_msd;
num *= 10;
num += bigs_place;

虽然循环和字符串可能非常有效,但在这种情况下它们是不必要的。
您所需要的只是一些数学知识:

#include <math.h>       // log10, pow, floor
#include <stdio.h>      // printf
int main ()
{
int n = 6945;
int p = pow(10,floor(log10(n)));
int output = (n - ((n/p)%10)*p)*10+((n/p)%10);
printf("%i",output);       // outputs 9456
}

这个想法是首先找到这个数字有多少位(floor(log10(n))),然后通过将输入除以10得到最有效的数字,得到这个幂(pow(10,floor(log10(n))))模10。我们将它存储在一个名为intp.

在这种情况下,这给了我们6.然后,我们从n中减去6p,得到剩余的数字(在我们的例子中945),然后我们乘以十并6相加,得到我们最终的答案9456

这是我是如何做到的

#include<stdio.h>
#include<math.h>
int main()
{
int a,g=10,m=1,c,num;
printf("enter the number : ");
scanf("%d",&a);
c=log10(a);
num=num+((a%10)*pow(10,c));
a=a/10;
c=log10(a);
while(m<=c){
if(m==c){
num=num+((a%10)*g)+a/10;
break;
}
else{
num=num+((a%10)*g);
g=g*10;
a=a/10;
m=m+1;
}
}
printf("%d",num);
}