模运算符 c# 示例

问题描述

谁能告诉我如何在不添加新语法等的情况下避免“第 0 天”? 在下面的例子中,如果囚犯在星期天出去,则输出为“0”,因为 7 % 7 is = 0

说明:1-7 代表一周中的天数,如果囚犯在第 2 天入狱并在那里待 3 天,他将在第 5 天离开。 但是,如果囚犯在第 3 天进入并停留 4 天,则使用此代码他不会在第 7 天而是在第 0 天离开。 我理解其中的原因(模 7 = 0),我想知道你们是否有任何创意(但避免使用新语法)来解决这个问题

    Console.WriteLine("Enter day of prison entry (from 1-7)");
    int dayOfEntry = int.Parse(Console.ReadLine());
    
    Console.WriteLine("How many days of sentencing?");
    int daysOfSentencing = int.Parse(Console.ReadLine());
    
    int dayOfRelease = (dayOfEntry + daysOfSentencing) % 7;
    
    Console.WriteLine("Prisoner is due to be released from prison on the: {0} day",dayOfRelease );

解决方法

通常在 C# 中,我们使用基于 0 的索引对现实世界的集合(通常是基于 1 的)进行建模。 C# 的基于 0 的数组索引的优势在于它可以很好地处理常见的范围逻辑和模数运算。

对于您的用例来说,一个非常好的示例是 System.DayOfWeek Enum,它将零设置为星期日。尽管您的要求不需要知道或显示星期几,但枚举是 .Net 标准的一个示例,其中在整个框架中普遍接受具有基于零的索引。

为了利用这一点,我们需要做的就是在执行任何范围或模数逻辑之前通过减去 1 来转置用户的输入,然后在返回给用户之前将结果加回 1:

需要的唯一更改是在这一行:

int dayOfRelease = ((dayOfEntry + daysOfSentencing - 1) % 7) + 1;

我们可以将其分解为离散的步骤:

// start with the day of entry
var zeroBasedDayOfRelease = dayOfEntry - 1;
// add the days
zeroBasedDayOfRelease += daysOfSentencing;
// apply the modulo
zeroBasedDayOfRelease = zeroBasedDayOfRelease % 7;
int dayOfRelease = zeroBasedDayOfRelease + 1;

这在对How can I modulo when my numbers start from 1,not zero?

的回答中有所涉及

我们可以使用 DayOfWeek 枚举为我们的用户提供更多价值,就目前而言,1-7 在许多国家、文化和环境中是不明确的。代码中的一个常见问题是我们可能需要知道一周的第一天是星期日还是星期一?

首先,让我们以声明的形式使用 DayOfWeek:

Console.WriteLine($"Enter day of prison entry (from 1-7,where 1 = {DayOfWeek.Sunday} and 7 = {DayOfWeek.Saturday})");
int dayOfEntryInput = int.Parse(Console.ReadLine());
DayOfWeek dayOfEntry = (DayOfWeek)(dayOfEntryInput - 1);
Console.WriteLine($"Prisoner entry on day {dayOfEntryInput}: {dayOfEntry}");
Console.WriteLine("How many days of sentencing?");
int daysOfSentencing = int.Parse(Console.ReadLine());
DayOfWeek dayOfRelease = (DayOfWeek)((int)(dayOfEntry + daysOfSentencing) % 7);
int dayOfReleaseNumber = (int)dayOfRelease + 1;
Console.WriteLine("Prisoner is due to be released from prison on the: {0} day - {1}",dayOfReleaseNumber,dayOfRelease);

输出:

Enter day of prison entry (from 1-7,where 1 = Sunday and 7 = Saturday)
> 3
Prisoner entry on day 3: Tuesday
How many days of sentencing?
> 4
Prisoner is due to be released from prison on the: 7 day - Saturday

如果一周的第一天需要是星期一,而你想让用户输入 1 代表星期一,那么我们仍然可以使用上面的逻辑,稍微改动一下:

DayOfWeek dayOne = DayOfWeek.Monday;
int dayZeroShift = 1 - (int)dayOne; 
Console.WriteLine($"Enter day of prison entry (from 1-7,where 1 = {dayOne} and 7 = {(DayOfWeek)((7-dayZeroShift) % 7)})");
int dayOfEntryInput = int.Parse(Console.ReadLine());
DayOfWeek dayOfEntry = (DayOfWeek)((dayOfEntryInput - dayZeroShift) % 7);
Console.WriteLine($"Prisoner entry on day {dayOfEntryInput}: {dayOfEntry}");
Console.WriteLine("How many days of sentencing?");
int daysOfSentencing = int.Parse(Console.ReadLine());
DayOfWeek dayOfRelease = (DayOfWeek)((int)(dayOfEntry + daysOfSentencing) % 7);
// to convert back,we need mod again,which means we have to do the -1 shift
// also add 7 to the base number to avoid negatives
int dayOfReleaseNumber = ((7 + (int)dayOfRelease + dayZeroShift - 1) % 7)+ 1;
Console.WriteLine("Prisoner is due to be released from prison on the: {0} day - {1}",where 1 = Monday and 7 = Sunday)
> 1
Prisoner entry on day 1: Monday
How many days of sentencing?
> 6
Prisoner is due to be released from prison on the: 7 day - Sunday

在此最终解决方案中,您可以将 dayOne 更改为 DayOfWeek.Wednesday,并且逻辑仍会评估正确的输出天数。