不使用字符串也不除以 10 的数字到数字
Number to digits without using strings nor division by 10
所以有一个挑战,你必须编写一个代码,在不使用字符串或除以 10 的情况下将 0-999 之间的数字拆分成数字。我已经很努力了,但无法想出完美的算法。我的代码用于拆分数字 1-99,但我真的认为有一些更好的选择而不使用 111 if 语句。好的,这就是我得到的:
#include <iostream>
int main() {
std::cout << "Enter a number ";
int number;
std::cin >> number;
int cycles;
if (number > 100) {
cycles = 3;
}
else if (number > 10) {
cycles = 2;
}
else {
cycles = 1;
}
int digit[] = { -1, -1, -1 };
for (int i = 0; i < cycles; i++) {
if (number < 10) {
digit[0] = number;
}
else if (number < 100) {
if (number < 20) {
digit[1] = number - 10;
number = 1;
}
else if (number < 30) {
digit[1] = number - 20;
number = 2;
}
else if (number < 40) {
digit[1] = number - 30;
number = 3;
}
else if (number < 50) {
digit[1] = number - 40;
number = 4;
}
else if (number < 60) {
digit[1] = number - 50;
number = 5;
}
else if (number < 70) {
digit[1] = number - 60;
number = 6;
}
else if (number < 80) {
digit[1] = number - 70;
number = 7;
}
else if (number < 90) {
digit[1] = number - 80;
number = 8;
}
else {
digit[1] = number - 90;
number = 9;
}
}
else if (number < 1000) {
if (number < 200) {
number -= 100;
}
else if (number < 300) {
number -= 200;
}
else if (number < 400) {
number -= 300;
}
else if (number < 500) {
number -= 400;
}
else if (number < 600) {
number -= 500;
}
else if (number < 700) {
number -= 600;
}
else if (number < 800) {
number -= 700;
}
else if (number < 900) {
number -= 800;
}
else {
number -= 900;
}
}
}
for (int i = 0; i < 3; i++) {
if (digit[i] != -1) {
std::cout << digit[i] << " ";
}
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}
我被卡住了,所以如果有人能帮助我,我将不胜感激!
基本上问题归结为,如何在不使用除法运算符的情况下实现除法运算符。由于可能性非常有限,即当测试每个数字时,只有 10 种可能的结果 0-9,一个简单的解决方案是遍历所有这些结果。您可以对每个都使用乘法,但稍微快一点的方法是迭代可能的答案。因此,一个以基数(1,10 或 100)为基础的简单函数和您要拆分的数字将是
int getDigit(int base, int number) {
int digit = 0;
for (int i = base;i <= number;i += base) ++digit;
return digit;
}
此函数仅在数字 < 10*base 时有效。所以你需要从最大的数字开始。然后从数字中减去 base*digit 并重复,直到你遍历所有数字。
由于不能除以 10,因此可以使用等同于除以 10 的移位运算符,请参阅 here:
使用移位运算符除以 10:
A:我们的整数
Q:quotient
Q = ((A >> 1) + A) >> 1;
Q = ((Q >> 4) + Q) ;
Q = ((Q >> 8) + Q) ;
Q = ((Q >> 16) + Q) >> 3;
/* either Q = A/10 or Q+1 = A/10 for all 32-bit unsigned A */
余数:
R=A-10*Q;
我们可以使用 while 循环扩展此方法,因为我们知道我们的整数小于 999,所以我们可以采用数组 [3]:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int A=123;
int R=A;
int Q=123; /* the quotient */
Q = ((A >> 1) + A) >> 1;
int ar[3]={0},i=2;
//loop for getting all digits
while(Q>10)
{
Q = ((Q >> 4) + Q) ;
Q = ((Q >> 8) + Q) ;
Q = ((Q >> 16) + Q) >> 3;
//storing ramainder in array in reverse
ar[i--]=R-10*Q;
R=Q;
}
ar[i]=Q;
for(i=0;i<3;i++)
printf("%d ",ar[i]);
return 0;
}
我可能漏掉了重点,并且使用了我的 C#,但是计算蜜蜂不是最简单的吗?
static void Main(string[] args)
{
int number = 592;
int digit1 = 0;
int digit2 = 0;
int digit3 = 0;
for (int c = 0; c < number; c++)
{
digit1 += 1;
if (digit1 == 10)
{
digit2 += 1;
digit1 = 0;
}
if(digit2 == 10)
{
digit3 += 1;
digit2 = 0;
}
}
Console.WriteLine(digit1);
Console.WriteLine(digit2);
Console.WriteLine(digit3);
}
C++ 版本:
int main()
{
std::cout << "Enter a number ";
int number;
std::cin >> number;
int digit1 = -1;
int digit2 = -1;
int digit3 = -1;
for (int c = 0; c < number; c++)
{
digit1 += 1;
if (digit1 == 10)
{
digit2 += 1;
digit1 = 0;
}
if (digit2 == 10)
{
digit3 += 1;
digit2 = 0;
}
}
if (digit3 > -1) {
std::cout << digit3+1 << " ";
}
if (digit2 > -1) {
std::cout << digit2+1 << " ";
}
if (digit1 > -1) {
std::cout << digit1+1 << " ";
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}
使用两个循环,一个循环从最高到最低遍历占位符,另一个内部循环从值中减去直到值小于该位置,有效地除法而不使用除法运算符。类似于:
int number;
int subtractionvalue;
int[3] placevalues;
for(int thisvalue=2;thisvalue>=0;thisvalue--){
subtractionvalue=round(pow((double)10,thisvalue));
while(number>=subtractionvalue){
number=number-subtractionvalue;
placevalues[thisvalue]++;
}
}
placevalues 数组将包含您的解决方案。
一种方法是将整数转换为定点格式,提供能够容纳一个小数位的整数部分,并将剩余的位用于小数部分。例如,当使用 32 位 int
时,我们可以为整数分配 4 个最高有效位,为小数分配 28 个最低有效位。
首先将原始数字转换为纯分数,在本例中为除以 1000。然后乘以比例因子 228。为简单起见,下面的代码使用浮点运算来进行此计算,但是如果需要,也可以使用整数运算来完成。由于浮点数到整数类型的转换在 C++ 中会被截断,因此 ceil()
用于稍微增加定点数。
转换为定点格式后,我们现在可以通过将定点数乘以 10 来提取每个小数位,提取乘积的整数部分作为下一个小数位,然后丢弃整数部分的定点结果。
我为下面的程序保留了尽可能多的原始代码。
#include <iostream>
#include <cmath>
int main() {
std::cout << "Enter a number ";
int number;
std::cin >> number;
int digit[] = { -1, -1, -1 };
unsigned int t, dec_digit;
bool have_seen_nonzero;
t = ceil (number / 1e3 * (1 << 28)); // 4.28 fixed-point representation
for (int pos = 0; pos < 3; pos++) {
t = t * 10;
dec_digit = t >> 28; // extract integer portion of fixed-point number
t = t & 0x0fffffff; // discard integer portion of fixed-point number
have_seen_nonzero = dec_digit != 0;
if (have_seen_nonzero) digit[pos] = dec_digit;
}
for (int i = 0; i < 3; i++) {
if (digit[i] != -1) {
std::cout << digit[i] << " ";
}
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}
所以有一个挑战,你必须编写一个代码,在不使用字符串或除以 10 的情况下将 0-999 之间的数字拆分成数字。我已经很努力了,但无法想出完美的算法。我的代码用于拆分数字 1-99,但我真的认为有一些更好的选择而不使用 111 if 语句。好的,这就是我得到的:
#include <iostream>
int main() {
std::cout << "Enter a number ";
int number;
std::cin >> number;
int cycles;
if (number > 100) {
cycles = 3;
}
else if (number > 10) {
cycles = 2;
}
else {
cycles = 1;
}
int digit[] = { -1, -1, -1 };
for (int i = 0; i < cycles; i++) {
if (number < 10) {
digit[0] = number;
}
else if (number < 100) {
if (number < 20) {
digit[1] = number - 10;
number = 1;
}
else if (number < 30) {
digit[1] = number - 20;
number = 2;
}
else if (number < 40) {
digit[1] = number - 30;
number = 3;
}
else if (number < 50) {
digit[1] = number - 40;
number = 4;
}
else if (number < 60) {
digit[1] = number - 50;
number = 5;
}
else if (number < 70) {
digit[1] = number - 60;
number = 6;
}
else if (number < 80) {
digit[1] = number - 70;
number = 7;
}
else if (number < 90) {
digit[1] = number - 80;
number = 8;
}
else {
digit[1] = number - 90;
number = 9;
}
}
else if (number < 1000) {
if (number < 200) {
number -= 100;
}
else if (number < 300) {
number -= 200;
}
else if (number < 400) {
number -= 300;
}
else if (number < 500) {
number -= 400;
}
else if (number < 600) {
number -= 500;
}
else if (number < 700) {
number -= 600;
}
else if (number < 800) {
number -= 700;
}
else if (number < 900) {
number -= 800;
}
else {
number -= 900;
}
}
}
for (int i = 0; i < 3; i++) {
if (digit[i] != -1) {
std::cout << digit[i] << " ";
}
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}
我被卡住了,所以如果有人能帮助我,我将不胜感激!
基本上问题归结为,如何在不使用除法运算符的情况下实现除法运算符。由于可能性非常有限,即当测试每个数字时,只有 10 种可能的结果 0-9,一个简单的解决方案是遍历所有这些结果。您可以对每个都使用乘法,但稍微快一点的方法是迭代可能的答案。因此,一个以基数(1,10 或 100)为基础的简单函数和您要拆分的数字将是
int getDigit(int base, int number) {
int digit = 0;
for (int i = base;i <= number;i += base) ++digit;
return digit;
}
此函数仅在数字 < 10*base 时有效。所以你需要从最大的数字开始。然后从数字中减去 base*digit 并重复,直到你遍历所有数字。
由于不能除以 10,因此可以使用等同于除以 10 的移位运算符,请参阅 here:
使用移位运算符除以 10:
A:我们的整数 Q:quotient
Q = ((A >> 1) + A) >> 1;
Q = ((Q >> 4) + Q) ;
Q = ((Q >> 8) + Q) ;
Q = ((Q >> 16) + Q) >> 3;
/* either Q = A/10 or Q+1 = A/10 for all 32-bit unsigned A */
余数:
R=A-10*Q;
我们可以使用 while 循环扩展此方法,因为我们知道我们的整数小于 999,所以我们可以采用数组 [3]:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int A=123;
int R=A;
int Q=123; /* the quotient */
Q = ((A >> 1) + A) >> 1;
int ar[3]={0},i=2;
//loop for getting all digits
while(Q>10)
{
Q = ((Q >> 4) + Q) ;
Q = ((Q >> 8) + Q) ;
Q = ((Q >> 16) + Q) >> 3;
//storing ramainder in array in reverse
ar[i--]=R-10*Q;
R=Q;
}
ar[i]=Q;
for(i=0;i<3;i++)
printf("%d ",ar[i]);
return 0;
}
我可能漏掉了重点,并且使用了我的 C#,但是计算蜜蜂不是最简单的吗?
static void Main(string[] args)
{
int number = 592;
int digit1 = 0;
int digit2 = 0;
int digit3 = 0;
for (int c = 0; c < number; c++)
{
digit1 += 1;
if (digit1 == 10)
{
digit2 += 1;
digit1 = 0;
}
if(digit2 == 10)
{
digit3 += 1;
digit2 = 0;
}
}
Console.WriteLine(digit1);
Console.WriteLine(digit2);
Console.WriteLine(digit3);
}
C++ 版本:
int main()
{
std::cout << "Enter a number ";
int number;
std::cin >> number;
int digit1 = -1;
int digit2 = -1;
int digit3 = -1;
for (int c = 0; c < number; c++)
{
digit1 += 1;
if (digit1 == 10)
{
digit2 += 1;
digit1 = 0;
}
if (digit2 == 10)
{
digit3 += 1;
digit2 = 0;
}
}
if (digit3 > -1) {
std::cout << digit3+1 << " ";
}
if (digit2 > -1) {
std::cout << digit2+1 << " ";
}
if (digit1 > -1) {
std::cout << digit1+1 << " ";
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}
使用两个循环,一个循环从最高到最低遍历占位符,另一个内部循环从值中减去直到值小于该位置,有效地除法而不使用除法运算符。类似于:
int number;
int subtractionvalue;
int[3] placevalues;
for(int thisvalue=2;thisvalue>=0;thisvalue--){
subtractionvalue=round(pow((double)10,thisvalue));
while(number>=subtractionvalue){
number=number-subtractionvalue;
placevalues[thisvalue]++;
}
}
placevalues 数组将包含您的解决方案。
一种方法是将整数转换为定点格式,提供能够容纳一个小数位的整数部分,并将剩余的位用于小数部分。例如,当使用 32 位 int
时,我们可以为整数分配 4 个最高有效位,为小数分配 28 个最低有效位。
首先将原始数字转换为纯分数,在本例中为除以 1000。然后乘以比例因子 228。为简单起见,下面的代码使用浮点运算来进行此计算,但是如果需要,也可以使用整数运算来完成。由于浮点数到整数类型的转换在 C++ 中会被截断,因此 ceil()
用于稍微增加定点数。
转换为定点格式后,我们现在可以通过将定点数乘以 10 来提取每个小数位,提取乘积的整数部分作为下一个小数位,然后丢弃整数部分的定点结果。
我为下面的程序保留了尽可能多的原始代码。
#include <iostream>
#include <cmath>
int main() {
std::cout << "Enter a number ";
int number;
std::cin >> number;
int digit[] = { -1, -1, -1 };
unsigned int t, dec_digit;
bool have_seen_nonzero;
t = ceil (number / 1e3 * (1 << 28)); // 4.28 fixed-point representation
for (int pos = 0; pos < 3; pos++) {
t = t * 10;
dec_digit = t >> 28; // extract integer portion of fixed-point number
t = t & 0x0fffffff; // discard integer portion of fixed-point number
have_seen_nonzero = dec_digit != 0;
if (have_seen_nonzero) digit[pos] = dec_digit;
}
for (int i = 0; i < 3; i++) {
if (digit[i] != -1) {
std::cout << digit[i] << " ";
}
}
std::cout << "\n";
std::cout << "Press any key to exit... ";
char i;
std::cin >> i;
return 0;
}