让我们来看看这些类型:
public enum KeyTone : int
{
C = 0,
Cs = 1,
D = 2,
Ds = 3,
E = 4,
F = 5,
Fs = 6,
G = 7,
Gs = 8,
A = 9,
As = 10,
H = 11
}
public class PianoKey
{
public KeyTone Tone { get; set; }
public int Octave { get; set; }
}
PianoKey代表了一把 - 好吧,你猜对了 - 钢琴的关键。我需要检查有多少白键(例如没有" s"后缀的那些)在两个指定的白键之间。问题是键盘不规则,E和F之间以及下一个八度音阶H和C之间没有黑键。
有一个明显的暴力解决方案 - 跳到下一个白键,直到达到所请求的第二个键。但也许有一些更简单的方法来计算它?
答案 0 :(得分:2)
首先,计算给定键的基音(我假设所有键都用它们的整数表示):
if tone <= KeyTone.E
baseTone = tone / 2
else
baseTone = (tone + 1) / 2
然后,添加八度音阶:
baseTone += Octave * 7
然后,您可以通过简单的减法找到白键的差异:
diffInWhiteKeys = baseTone(key1) - baseTone(key2)
E.g。 E2和G3之间的区别是:
baseTone(E2) = 4 / 2 + 2 * 7 = 16
baseTone(G3) = (7 + 1) / 2 + 3 * 7 = 25
diff = 24 - 16 = 9
,这正是您必须从E2前进到G3的白键数。如果您对键之间的白键数感兴趣,只需减去一个。
答案 1 :(得分:1)
创建两个映射
的静态数组static int[] whiteLeft = new int[] {0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6};
static int[] whiteRight = new int[] {0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6};
然后可以计算两个键之间的白键数,就像
一样简单public static int WhiteKeysBetween(PianoKey left, PianoKey right)
{
int wl = whiteLeft[(int)left.Tone];
int wr = whiteRight[(int)right.Tone];
return (right.Octave - left.Octave) * 7 + (wr - wl - 1);
}
编辑:这也适用于任意两个键之间的白键(白色或黑色)。我没有意识到问题陈述只要求白键之间的白键。