模运算符 c# 示例

Modulus operator c# example

谁能告诉我如何在不添加新语法等的情况下避免“第 0 天”? 在下面的示例中,如果囚犯在周日出狱,则输出为“0”,因为 7 % 7 = 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 的数组索引的优势在于它非常适合公共范围逻辑和模数运算。

A really good example for your use case is the System.DayOfWeek Enum, which has zero set as Sunday. Although your requirement does not need to know or display the name of the day of week, the enum is an example of the .Net standard where having a zero based index is universally accepted across the framework.

要利用这一点,我们需要做的就是在执行任何范围或模数逻辑之前通过减去 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;

This is covered in the answer to 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}", dayOfReleaseNumber, dayOfRelease);

输出:

Enter day of prison entry (from 1-7, 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

In this final solution, you could change the dayOne to DayOfWeek.Wednesday and the logic would still evaluate the correct output days.