问题描述
数字黑洞是指将输入的数字的各个位置按照从小打到的顺序进行排列,得到最小的数。然后再从大到小排列得到最大的数。大数-小数得到的差依然作上述操作,知道结果等于6174。即进入了数字黑洞模式。
题目分析
如果要多输入的数字的各个位置进行排序,显然不能输入整数类型的数据,所以我们要输入一个字符串,字符串的形式对数字进排序。
但是字符串需要再转换为int类型的数字才能做差。所以我们还应该单独写两个函数,完成int转化为string和string转化为int.此处用到的主要是sstream的标准库。
此外我们还应该找到最大值和最小值,这里我们单独写出两个函数,对字符串进行排序找出最值。如果计算得到的差<4位,就在数字的前面补0。
这道题还有一个坑,那就是我们在主函数中不能单纯地用循环一直计算到6174,而应该用do-while结构,先计算了再判断。具体原因,大家可以先停在这里思考一下再继续看代码。
代码
#include <iostream>
#include <sstream>
using namespace std;
/*
1、有一个坑点,输入本身是6174,应该输出7641 - 1467 = 6174,因此必须用do while循环,
如果用while循环,此处直接就输出了,有一个case错误!
2、本题学到的语法:
(1)int与string的互相转换,利用stringstream作桥。
(2)string中按字节排序,类似于java中的Arrays.sort(char[]),
本代码里采用的是选择法排序,同样也可用冒泡法或其他排序方法
*/
string intToString(int t) {
stringstream ss;
ss<<t;
string tmp;
ss>>tmp;
//如果不足4位,在前面补0
while(tmp.length()<4) {
tmp = "0" + tmp;
}
return tmp;
}
int stringToInt(string t) {
//字符串变数字
stringstream ss;
ss<<t;
int tmp;
ss>>tmp;
return tmp;
}
//选择排序找最小
string findMin(string s) {
for(int i=0; i<s.length(); i++) {
for(int j=i+1; j<s.length(); j++) {
if(s[i]>s[j]) {
char c = s[j];
s[j] = s[i];
s[i] = c;
}
}
}
return s;
}
//选择排序找最大
string findMax(string s) {
for(int i=0; i<s.length(); i++) {
for(int j=i+1; j<s.length(); j++) {
//s.at(i)与s[i]作用相同
if(s.at(i)<s.at(j)) {
char c = s.at(j);
s[j] = s[i];
s[i] = c;
}
}
}
return s;
}
int main() {
int n;
cin>>n;
string str = intToString(n);
//这里要注意,如果刚上来差就是6174的话就没得循环了
do{
string min = findMin(str);
string max = findMax(str);
str = intToString(stringToInt(max)-stringToInt(min));
cout<<max<<" - "<<min<<" = "<<str<<endl;
}while(str.compare("6174")!=0 && str.compare("0000")!=0);
return 0;
}
总结
答题用时19min
Q19——finish√