C++ 确定一个数字是十的倍数还是在一组特定范围内

C++ 确定一个数字是十的倍数还是在一组特定范围内,c++,comparison,conditional-statements,integer-arithmetic,C++,Comparison,Conditional Statements,Integer Arithmetic,我有几个循环,我需要在我的程序。我可以写出伪代码,但我不完全确定如何逻辑地编写它们 我需要- if (num is a multiple of 10) { do this } if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this } else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90 这是一个蛇和梯子的棋盘游戏,如果它对我的问题更有意

我有几个循环,我需要在我的程序。我可以写出伪代码,但我不完全确定如何逻辑地编写它们

我需要-

if (num is a multiple of 10) { do this }

if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90
这是一个蛇和梯子的棋盘游戏,如果它对我的问题更有意义的话

我想第一个if语句需要使用模。如果(num==100%10)正确吗


第二个我不知道。如果(num>10&&num是<21 | | |等),我可以像
那样写出来
,但必须有比这更聪明的东西。

你可能想得太多了

if (x % 10)
{
   .. code for 1..9 ..
} else
{
   .. code for 0, 10, 20 etc.
}
第一行
如果(x%10)
起作用,因为(a)10的倍数的值计算为“0”,其他数字会导致它们的余数,(b)如果
中的值为0,则认为
为假
,任何其他值都是

编辑:

要在20岁时来回切换,请使用相同的技巧。这一次,关键数字是
10

if (((x-1)/10) & 1)
{
  .. code for 10, 30, ..
} else
{
   .. code for 20, 40, etc.
}

x/10
将0到9之间的任意数字返回为
0
,将10到19之间的任意数字返回为
1
,依此类推。对偶数或奇数进行测试--
&1
--告诉您它是偶数还是奇数。因为你的范围实际上是“11到20”,所以在测试之前减去1。

你基本上自己解释了答案,但这里的代码只是以防万一

if((x % 10) == 0) {
  // Do this
}
if((x > 10 && x < 21) || (x > 30 && x < 41) || (x > 50 && x < 61) || (x > 70 && x < 81) || (x > 90 && x < 101)) {
  // Do this
}
if((x%10)==0){
//这样做
}
如果((x>10&&x<21)|(x>30&&x<41)|(x>50&&x<61)|(x>70&&x<81)|(x>90&&x<101)){
//这样做
}

对于第一个,要检查数字是否是使用倍数:

if (num % 10 == 0) // It's divisible by 10
关于第二个问题:

if(((num - 1) / 10) % 2 == 1 && num <= 100)
这是相同的逻辑,但通过使用函数,我们可以更清楚地了解它的含义

如果(num是10的倍数){dothis}

如果(num在11-20、31-40、51-60、71-80、91-100范围内){dothis}

这里的技巧是在这些范围中寻找某种共同点。当然,您可以始终使用“暴力”方法:

换句话说,第一个数字是奇数的所有两位数。接下来,你需要想出一个公式来表达这一点。你可以通过除以10得到第一个数字,当你除以2时,你可以通过检查1的余数来检验它是否是奇数。综上所述:


if((num>0)和&(num如果您使用的是GCC或任何支持您的编译器,您可以这样做,但是您的代码将不可移植

switch(num)
{
case 11 ... 20:
case 31 ... 40:
case 51 ... 60:
case 71 ... 80:
case 91 ... 100:
    // Do something
    break;
default:
    // Do something else
    break;
}

这是为未来的访问者而不是初学者准备的。对于更通用、类似算法的解决方案,您可以获取起始值和结束值的列表,并检查传递的值是否在其中一个值内:

template<typename It, typename Elem>
bool in_any_interval(It first, It last, const Elem &val) {
    return std::any_of(first, last, [&val](const auto &p) {
        return p.first <= val && val <= p.second;
    });
}

有一个实例。

第一个很简单。您只需对num值应用模运算:

if ( ( num % 10 ) == 0)
<>因为C++对每个不是0的数进行求值,你也可以写:

if ( ! ( num % 10 ) )  // Does not have a residue when divided by 10
对于第二个问题,我认为这更容易理解:

模式每20次重复一次,因此可以计算模20。 除可除以20的元素外,所需的所有元素都将在一行中

要获得这些,只需使用num-1或更好的num+19,以避免处理负数

if ( ( ( num + 19 ) % 20 ) > 9 )
这是假设模式永远重复,因此对于111-120,它将再次应用,依此类推。否则,您需要将数字限制为100:

if ( ( ( ( num + 19 ) % 20 ) > 9 ) && ( num <= 100 ) )

如果(((num+19)%20)>9)和&(num在代码中有一些好的注释,那么它可以写得非常简洁易懂

// Check if it's a multiple of 10
if (num % 10 == 0) { ... }

// Check for whether tens digit is zero or even (1-10, 21-30, ...)
if ((num / 10) % 2 == 0) { ... }
else { ... }

对可读性的诉求

虽然您已经有了一些很好的答案,但我想推荐一种编程技术,它将使您的代码对未来的读者更具可读性-这可能是您在六个月后,一位同事要求执行代码审阅,您的继任者

这是将任何“聪明”的语句封装到一个函数中,该函数准确地(用它的名称)显示它正在做什么。虽然对性能的影响很小(来自“函数调用开销”),但在这样的游戏环境中,这是可以忽略不计的

在此过程中,您可以对输入进行清理—例如,测试“非法”值。因此,您可能会得到这样的代码—看看它的可读性有多高?可以将“帮助器函数”隐藏在某个地方(不需要在主模块中:从它们的名称可以清楚地看出它们的作用):

#包括
枚举{否,是,获胜者};
枚举{OUT_OF_RANGE=-1,奇数,偶数};
整数非整数范围(整数平方){
返回(平方<1 | |平方>100)?是:否;
}
int isEndOfRow(int方形){
如果(不在范围内(平方))返回在范围内的值;
如果(square==100)返回赢家;//我正在弥补这个错误。。。
返回值(平方%10==0)?是:否;
}
整数行类型(无符号整数平方){
//如果正方形为奇数行,则返回1(向右)
//如果正方形在偶数行中(向左),则为0
if(notInRange(square))返回\u范围之外的\u;//捕获此错误
int rowNum=(平方-1)/10;
return(rowNum%2==0)?奇数:偶数;//对于1-10、21-30等返回0(奇数)。
//11-20,31-40。。。
}
内部主(空){
INTA=12;
int-rt;
rt=rowType(a);//这将替换模糊的if语句
//下面是如何处理可能的返回值:
开关(rt){
单数:
printf(“这是一个奇数行\n”);
打破
偶数:
printf(“它是一个偶数行\n”);
打破
超出范围的情况:
printf(“超出范围\n”);
打破
违约:
printf(“行类型的意外返回值!\n”);
}
如果(isEndOfRow(10)==是)printf(“10在一行的末尾\n”);
如果(isEndOfRow(100)=获胜者)printf(“我们有获胜者!\n”);
}

正如其他人所指出的,使条件更加简洁不会加快编译或执行,也不一定有助于提高可读性

它可以使你的程序更加灵活,以防你以后决定在6 x 6的棋盘上玩幼儿版的游戏,或者
std::pair<int, int> intervals[]{
    {11, 20}, {31, 40}, {51, 60}, {71, 80}, {91, 100}
};

const int num = 15;
std::cout << in_any_interval(std::begin(intervals), std::end(intervals), num);
if ( ( num % 10 ) == 0)
if ( ! ( num % 10 ) )  // Does not have a residue when divided by 10
if ( ( ( num + 19 ) % 20 ) > 9 )
if ( ( ( ( num + 19 ) % 20 ) > 9 ) && ( num <= 100 ) )
// Check if it's a multiple of 10
if (num % 10 == 0) { ... }

// Check for whether tens digit is zero or even (1-10, 21-30, ...)
if ((num / 10) % 2 == 0) { ... }
else { ... }
#include <stdio.h>

enum {NO, YES, WINNER};
enum {OUT_OF_RANGE=-1, ODD, EVEN};

int notInRange(int square) {
  return(square < 1 || square > 100)?YES:NO;
}

int isEndOfRow(int square) {
  if (notInRange(square)) return OUT_OF_RANGE;
  if (square == 100) return WINNER; // I am making this up...
  return (square % 10 == 0)? YES:NO;
}

int rowType(unsigned int square) {
  // return 1 if square is in odd row (going to the right)
  // and 0 if square is in even row (going to the left)
  if (notInRange(square)) return OUT_OF_RANGE; // trap this error
  int rowNum = (square - 1) / 10;
  return (rowNum % 2 == 0) ? ODD:EVEN; // return 0 (ODD) for 1-10, 21-30 etc.
                                       // and 1 (EVEN) for 11-20, 31-40, ...
}

int main(void) {
  int a = 12;
  int rt;
  rt = rowType(a); // this replaces your obscure if statement

  // and here is how you handle the possible return values:
  switch(rt) {
  case ODD:
    printf("It is an odd row\n");
    break;
  case EVEN:
    printf("It is an even row\n");
    break;
  case OUT_OF_RANGE:
    printf("It is out of range\n");
    break;
  default:
    printf("Unexpected return value from rowType!\n");
  }

  if(isEndOfRow(10)==YES) printf("10 is at the end of a row\n");
  if(isEndOfRow(100)==WINNER) printf("We have a winner!\n");
}
// What is the size of the game board?
#define ROWS            10
#define COLUMNS         10

// The numbers of the squares go from 1 (bottom-left) to (ROWS * COLUMNS)
// (top-left if ROWS is even, or top-right if ROWS is odd)
#define firstSquare     1
#define lastSquare      (ROWS * COLUMNS)
// We haven't started until we roll the die and move onto the first square,
// so there is an imaginary 'square zero'
#define notStarted(num) (num == 0)
// and we only win when we land exactly on the last square
#define finished(num)   (num == lastSquare)
#define overShot(num)   (num > lastSquare)

// We will number our rows from 1 to ROWS, and our columns from 1 to COLUMNS
// (apologies to C fanatics who believe the world should be zero-based, which would
//  have simplified these expressions)
#define getRow(num)   (((num - 1) / COLUMNS) + 1)
#define getCol(num)   (((num - 1) % COLUMNS) + 1)

// What direction are we moving in?
// On rows 1, 3, 5, etc. we go from left to right
#define isLeftToRightRow(num)    ((getRow(num) % 2) == 1)
// On rows 2, 4, 6, etc. we go from right to left
#define isRightToLeftRow(num)    ((getRow(num) % 2) == 0)

// Are we on the last square in the row?
#define isLastInRow(num)    (getCol(num) == COLUMNS)

// And finally we can get onto the code

if (notStarted(mySquare))
{
  // Some code for when we haven't got our piece on the board yet
}
else
{
  if (isLastInRow(mySquare))
  {
    // Some code for when we're on the last square in a row
  }


  if (isRightToLeftRow(mySquare))
  {
    // Some code for when we're travelling from right to left
  }
  else
  {
    // Some code for when we're travelling from left to right
  }
}
if (x % 10 == 0)
10, 20, 30, .. 100 .. 1000 ...
if (((x-1) / 10) % 2 == 1)
11-20, 31-40, 51-60, ..
10-19, 30-39, 50-59, ..
1, 3, 5, ..
// Multiple of 10
if ((num % 10) == 0)
{
   // Do something
}
else if (((num / 10) % 2) != 0)
{
    // 11-20, 31-40, 51-60, 71-80, 91-100
}
 else
{
    // Other case
}