看D.S.Malik写的C++编程——数据结构与程序设计方法一书,在第5章结尾的编程练习时,看到两道题:
题1:如果一个整数各位的数字之后可以被9整除,那么该整数就可以被9整除,编写一个程序提示用户输入一个整数。然后程序输出该整数并告知用户该整数是否可以被9整除。程序通过判断输入整数各位数字之和是否为9的倍数来判断该数是否可以被9整除。
题2:编写一个程序提示用户输入一个整数。程序将分别输出该整数每个位上的数字,并且输出这些数字的和。例如,程序输出整数3456每个位上的数字3 4 5 6;输出整数8030每个位上的数字8 0 3 0;输出整数2345526每个位上的数字2 3 4 5 5 2 6;输出整数4000每个位上的数字4 0 0 0;输出整数 -2345每个位上的数字2 3 4 5。
只用到前1-5章的学习内容来做这两道题的话,难点有2个:
1:如果把输入的整数变成一个个数位上的数字(默认用户输入的数字可以为十位整数或者只有百位的整数);
2:如何将转换完的一个个数位上的数字按正序输出出来(取余的方法默认是从个位开始输出,所以输出顺序和输入顺序是相反的,即123456输出的结果是654321);
因为两道题类似,就用一个程序合并执行了:
#if 1 // 用if控制下面这堆代码是否运行;(#if 0是关闭,#if 1是打开);
#include <iostream> // 调用iostream头文件,用来使用cin和cout;
#include <string> // 调用string头文件,用来使用自定义的字符串函数;
#include <iomanip> // 调用iomanip头文件,用来使用setw控制符;
using namespace std; // 使用std命名空间,用来在cout文件时不需要输入std::;
const int Divisor = 9; // 命名int型常量,并将数值9赋予该变量;
int main()
{
int InputNumber; // 用于存储输入值的变量;
int Counter; /* 用于计算的变量(用于循环计数以及作为输入数
值第一顺位的存储变量)*/
int Temporary = 0; // 用与存储余数的变量;
int Sum = 0; // 用于计算总和的变量;
int Counter_a; /* 这个变量用于计算并存储取余计算对应的次数,即几次取余
(将次数对应switch中的case数)*/
string Result; /* 字符串类型变量Result用于显示计算结果为true还是flase,
(用bool函数,结果显示只有1或0);*/
int Var0 = 10; /* 将值设定为10是作为开关只用,,被取余后存储的变量值
必然< 10,而为被使用到的变量则为初始值10不变,
即实现开关的作用;*/
int Var1 = 10;
int Var2 = 10;
int Var3 = 10;
int Var4 = 10;
int Var5 = 10;
int Var6 = 10;
int Var7 = 10;
int Var8 = 10;
int Var9 = 10;
cout << "Please enter an integer, the program will split"
<< "\n the digits of each digit and output it, and calculate "
<< "\nthe sum of these numbers, as well as whether this integer "
<< "can be divisible by 9(\nThe input number range "
<< "cannot exceed the range of int type): " << flush;
/* "请输入一个整数,程序将拆分每个数字并输出, "
"并计算这些数字的和,以及这个整数是否可以被9整除: "
"(输入数字范围不能超过int类型的范围)": flush的作用是
立即输出""号中的文字,并且不换行;*/
cin >> InputNumber; // 输入要计算的数值;
if(InputNumber < 0)
InputNumber = 0 - InputNumber; /* 如果输入的为负数,则用0 - 负数,即
得到正数的数值以便后面的计算;*/
Counter = InputNumber; /* 此时将InputNumber的值赋予Counter的,
即用Counter变量复制 InputNumber的值,
作为备用;*/
while (Counter > 9) /* 循环1:将循环1的条件设定为Counter > 9 ,
是为了保证在Counter <= 9的时候退出循环1;*/
{
Counter = Counter / 10; /* 在每次执行循环1的时候,都将Counter / 10,
即Counter / 10作为退出循环1的出口;*/
for(Counter_a = 0; InputNumber > 9; Counter_a ++)
/*循环2:将Counter_a的值初始化为0;
执行循环的条件为InputNumber > 9, 即InputNumber的值 <= 9 时退出循环2;
每次循环将Counter_a的值加1*/
{
Temporary = InputNumber % 10;
// 将InputNumber / 10的余数存储到变量Temporary中;
Sum = Sum + Temporary;
// Sum变量的值 = Sum变量的值(初始为 0)加上Temporary存储的余数;
InputNumber = InputNumber / 10;
/* 在每次执行循环2的时候,都将InputNumber / 10,
即使用InputNumber / 10作为循环2出口;*/
switch(Counter_a)
/*switch结构以Counter_a的值作为参数(将取余的次数作为数值排列,
即:第一次取余运算对应case 0, 第二次取余运算 对应case 1,
第三次取余运算对应case 2...*/
{
case 9: Var9 = Temporary; break;
/*将取余次数Counter_a对应的取余的数值Temporary存放到
Var0-9变量中,为后面排序输出做准备;*/
case 8: Var8 = Temporary; break;
case 7: Var7 = Temporary; break;
case 6: Var6 = Temporary; break;
case 5: Var5 = Temporary; break;
case 4: Var4 = Temporary; break;
case 3: Var3 = Temporary; break;
case 2: Var2 = Temporary; break;
case 1: Var1 = Temporary; break;
case 0: Var0 = Temporary; break;
}
}
}
cout << Counter;
/*输出已经被多次除以10,只剩个位数的Counter变量(即输入数
字的第一顺位数字),并跟上" "以分隔后面的输出结果;*/
if(Var9 < 10)
cout << setw(2) << Var9
/*setw(2)的作用是给输出结果2个数列的列宽,因为Var0-9值都是个位数字,
只会占用1个数列的列宽,另1个列宽显示为空格,即用来当作后面输出结果
的分隔符使用,可以用<< " " 来代替setw控制符;*/
if(Var8 < 10)
cout << setw(2) << Var8;
/*如果Var0-9的值没有被Temporary存放过,则其的值 = 10,即不输出;
如果Var0-9的值被存放过,则将其输出,并跟上" "以分隔后面的输出结果;*/
if(Var7 < 10)
cout << setw(2) << Var7;
if(Var6 < 10)
cout << setw(2) << Var6;
if(Var5 < 10)
cout << setw(2) << Var5;
if(Var4 < 10)
cout << setw(2) << Var4;
if(Var3 < 10)
cout << setw(2) << Var3;
if(Var2 < 10)
cout << setw(2) << Var2;
if(Var1 < 10)
cout << setw(2) << Var1;
if(Var0 < 10)
cout << setw(2) << Var0;
//以上的Var0-Var9的排序为输出时的顺序排序;
cout << "\nThe sum of these numbers is: " << Sum + Counter;
// "这些数字的和为:"Sum + 最后被除到只剩个位数的Counter;
cout << endl; // 将光标移动到下一行的开始处;
if ((Sum + Counter) % Divisor == 0)
// 如果数字的总和除以Divisor的值以后余数为0(此处已设定命名常量Divisor的值为9);
Result = "true"; //则字符串变量的值为"true";
else
Result = "false"; //否则值为"false";
cout << "The judgment result of whether this"
<<" number can be divided by 9 is: " << Result << endl;
// "此数字是否可以被9整除的判断结果为:"字符串变量Result的值;
return 0;
}
#endif
//和#if对应,用于控制被#if和#endif所包裹的程序是否显示;
有一些需要注意的地方:
1.程序编写和运行的环境为32位系统,所以当输入数值超过32位系统下的int类型数值范围(即-2147483648和2147483647之间),输入的数字会截止到int类型所能接受的最大数值进行计算;
2.因为上面的原因,所以程序里只设定了10个用来存储位数数字的变量,如果是64位系统的运行环境,可以将变量的数量写成19个,即Var0-Var18;
3.此程序肯定是笨方法,只是用现有知识进行编写,勿喷,只是给共同学习的小伙伴们一些思路;
4.输出语句里的英文全是机翻,看看就好,因为不同的编译环境输出后中文有可能会变成乱码;
5.关于第1题,不用取余运算编写方法也有笨方法,如下:
#if 1
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
const int Divisor = 9; //Divisor 除数;
int main()
{
int InputNumber; // 输入数字;
int Temporary = 0; // 计算数字;
int InputNumberCopy = 0; // 复制InputNumber值,用于计算循环次数;
string Result;
int counter = 0; // 计数器,用于计算幂;
int Sum = 0; // 位数数字的和;
cout << "Please enter a number, and the program will determine"
<< " \nwhether this number can be evenly divided by 9: " << flush;
// "请输入一个数字,程序将判断此数字是否可以被9整除:"
cin >> InputNumber;
InputNumberCopy = InputNumber;
if(InputNumber < 0)
InputNumber = 0 -InputNumber;
if(InputNumber < 10)
Sum = InputNumber;
else
{
do
{
if(Temporary != 0)
cout << Temporary << " ";
Sum = Sum + Temporary;
Temporary = Temporary * pow(10, counter);
counter = 0;
InputNumber = InputNumber - Temporary;
InputNumberCopy = InputNumber;
do
{
if (InputNumberCopy < 10)
Temporary = InputNumber;
else
{
InputNumberCopy = InputNumberCopy / 10;
Temporary = InputNumberCopy;
counter++;
}
}
while ((InputNumberCopy / 10) >= 1);
}
while ((InputNumber / 10) >= 1);
}
cout << Temporary;
Sum = Sum + Temporary;
cout << "\nThe sum of these numbers is: " << Sum + Temporary;
if (Sum % Divisor == 0)
Result = "true";
else
Result = "false";
cout << "\nThe judgment result of whether this"
<<" number can be divided by 9 is: " << Result << endl;
// "此数字是否可以被9整除的判断结果为:"
return 0;
}
#endif
这个程序实际上相当于是把取余运算拆开成表达式了,优点有:
1.行数少,代码比第一种少;
2.纯计算,逻辑步骤比较清晰;
缺点目前感觉就一个,还很致命:
不能在输入数字中间穿插0,即:123456789这种没问题,如果输入123000789,显示输出的位数数字则为:123789,中间的0都被忽略掉了;
这个程序实际上未将位数存入到对应的变量中,所以并不适用于第二题,程序的形式和第一种程序的形式类似,所以就不做备注了;
顺便提一句,我看的书是2003年经过翻译的第1版(中文版好像只有第1版),英文的第8版的教材里已经把第1题取消了,只剩下第2题,大概是因为这两道题太相似了;