8

こんにちは、私はプログラミングに少し慣れていませんが、どちらかというと趣味です。次のロジックまたはテクニックに特定の名前または用語があるかどうか疑問に思っています。現在のプロジェクトには、曜日ごとに 1 つずつ、合計 7 つのチェック ボックスがあります。どのボックスがチェックされたかを簡単に保存する必要がありました。

以下は、チェックボックスを単一の番号に保存する方法です。各チェックボックスは、最後のチェック ボックスの 2 倍の値を取得します。どのボックスがチェックされているかを知りたいときは、逆算して合計値をチェックボックスの値で割り切れる回数を調べます。

private int SetSelectedDays()
{
     int selectedDays = 0;
     selectedDays += (dayMon.Checked) ? 1 : 0;
     selectedDays += (dayTue.Checked) ? 2 : 0;
     selectedDays += (dayWed.Checked) ? 4 : 0;
     selectedDays += (dayThu.Checked) ? 8 : 0;
     selectedDays += (dayFri.Checked) ? 16 : 0;
     selectedDays += (daySat.Checked) ? 32 : 0;
     selectedDays += (daySun.Checked) ? 64 : 0;
     return selectedDays;
}

private void SelectedDays(int n)
{
     if ((n / 64 >= 1) & !(n / 64 >= 2))
     {
          n -= 64;
          daySun.Checked = true;
     }
     if ((n / 32 >= 1) & !(n / 32 >= 2))
     {
          n -= 32;
          daySat.Checked = true;
     }
     if ((n / 16 >= 1) & !(n / 16 >= 2))
     {
          n -= 16;
          dayFri.Checked = true;
     }
     if ((n / 8 >= 1) & !(n / 8 >= 2))
     {
          n -= 8;
          dayThu.Checked = true;
     }
     if ((n / 4 >= 1) & !(n / 4 >= 2))
     {
          n -= 4;
          dayWed.Checked = true;
     }
     if ((n / 2 >= 1) & !(n / 2 >= 2))
     {
          n -= 2;
          dayTue.Checked = true;
     }
     if ((n / 1 >= 1) & !(n / 1 >= 2))
     {
          n -= 1;
          dayMon.Checked = true;
     }
     if (n > 0)
     {
          //log event
     }
}

この方法は私が必要としているものにはうまく機能しますが、これを行う別の方法やより良い書き方があれば、あなたの提案に興味があります.

4

7 に答える 7

6

他の誰かがビット マスキングについて言及しましたが、コードを単純化する方法を紹介したいと思います。

daySun.Checked = (n & 64) == 64;
daySat.Checked = (n & 32) == 32;
dayFri.Checked = (n & 16) == 16;
dayThu.Checked = (n & 8) == 8;
dayWed.Checked = (n & 4) == 4;
dayTue.Checked = (n & 2) == 2;
dayMon.Checked = (n & 1) == 1;
于 2010-03-19T15:09:10.050 に答える
4

これはビットマスキングに似ています。この正確な例を使用して、今週読んだブログを見つけることができたら、投稿します!

ああ、わかった! ここにあります。

次に、次のようなことができます。

DaysOfWeek week = DaysOfWeek.Sunday | DaysOfWeek.Monday;

日曜日と月曜日を選択します。または、あなたの例では、各チェックボックスの値を確認すると、次のことができます。

DaysOfWeek week = DaysOfWeek.None; // DaysOfWeek.None = 0

if (Monday.Checked)
{
    week |= DaysOfWeek.Monday;
}

特定の日が設定されているかどうかを確認するには、次のようにします。

DaysOfWeek week = DaysOfWeek.Monday | DaysOfWeek.Tuesday;

// this will be FALSE (so Wednesday will remain unchecked) because "week" contains Monday/Tuesday, but not Wednesday.
if ((week & DaysOfWeek.Wednesday) == DaysOfWeek.Wednesday)
{
    Wednesday.Checked = true;
}

編集:

.NET の組み込みの DayOfWeek では、複数の値をビットマスクすることはできないため、独自のDaysOfWeek列挙型をロールする必要があります。

于 2010-03-19T15:06:46.003 に答える
3

すべての日で列挙型を作成し、属性 [Flags] でマークしてから、毎日 (bla.checked) と同じ値を与えることができますか? XX..

次に、+=、および、またはを使用して同じ機能を得ることができます..

値に含まれているかどうかを確認するには、月曜日としましょう

if (myEnum & Days.Monday == Days.Monday) { ... }

于 2010-03-19T15:08:32.313 に答える
1

これはビットマスキングと呼ばれ、 Enum と Flags 属性を使用して同じことをより簡単に行うことができます。

于 2010-03-19T15:08:24.680 に答える
1

これはビットフィールドと呼ばれ、そうです、これはこれを解決する最もスペース効率の良い方法です。個別のブール値を使用すると、おそらくより多くのメモリが使用されますが、IMO の読みやすさは 6 バイトほどの価値があります。

于 2010-03-19T15:09:44.850 に答える
0

列挙型を使用できます...より読みやすく、きれいです

    public enum daysOfWeek
    {
        Mon = 1, Tue = 2, Wed = 4, Thu = 8, Fri = 16, Sat = 32, Sun = 64
    }
于 2010-03-19T15:12:15.670 に答える
0

関数の複雑さを隠すことができます: 分割する代わりにビットシフトする方が良いです

private bool get_bit(int val, int idx)
{
  return ((val >> idx) & 1) != 0;
}
于 2010-03-19T15:12:40.260 に答える