東方算程譚

Oriental Code Talk ── επιστημηが与太をこく、弾幕とは無縁のシロモノ。

目次

Blog 利用状況

ニュース

著作とお薦めの品々は

著作とお薦めの品々は
東方熱帯林へ。

あわせて読みたい

わんくま

  1. 東京勉強会#2
    C++/CLI カクテル・レシピ
  2. 東京勉強会#3
    template vs. generics
  3. 大阪勉強会#6
    C++むかしばなし
  4. 東京勉強会#7
    C++むかしばなし
  5. 東京勉強会#8
    STL/CLRによるGeneric Programming
  6. TechEd 2007 @YOKOHAMA
    C++・C++/CLI・C# 適材適所
  7. 東京勉強会#14
    Making of BOF
  8. 東京勉強会#15
    状態遷移
  9. 名古屋勉強会#2
    WinUnit - お気楽お手軽UnitTest

CodeZine

  1. Cで実現する「ぷちオブジェクト指向」
  2. CUnitによるテスト駆動開発
  3. SQLiteで組み込みDB体験(2007年版)
  4. C++/CLIによるCライブラリの.NET化
  5. C# 1.1からC# 3.0まで~言語仕様の進化
  6. BoostでC++0xのライブラリ「TR1」を先取りしよう (1)
  7. BoostでC++0xのライブラリ「TR1」を先取りしよう (2)
  8. BoostでC++0xのライブラリ「TR1」を先取りしよう (3)
  9. BoostでC++0xのライブラリ「TR1」を先取りしよう (4)
  10. BoostでC++0xのライブラリ「TR1」を先取りしよう (5)
  11. C/C++に対応した、もうひとつのUnitTestFramework ─ WinUnit
  12. SQLiteで"おこづかいちょう"
  13. STL/CLRツアーガイド
  14. マージ・ソート : 巨大データのソート法
  15. ヒープソートのアルゴリズム
  16. C++0xの新機能「ラムダ式」を次期Visual Studioでいち早く試す
  17. .NETでマンデルブロ集合を描く
  18. .NETでマンデルブロ集合を描く(後日談)
  19. C++/CLI : とある文字列の相互変換(コンバージョン)
  20. インテルTBBによる選択ソートの高速化
  21. インテルTBB3.0 によるパイプライン処理
  22. Visual C++ 2010に追加されたSTLアルゴリズム
  23. Visual C++ 2010に追加されたSTLコンテナ「forward_list」
  24. shared_ptrによるObserverパターンの実装
  25. .NETでマンデルブロ集合を描く(番外編) ── OpenCLで超並列コンピューティング
  26. StateパターンでCSVを読む
  27. 状態遷移表からStateパターンを自動生成する
  28. 「ソートも、サーチも、あるんだよ」~標準C++ライブラリにみるアルゴリズムの面白さ
  29. インテルTBBの同期メカニズム
  30. なぜsetを使っちゃいけないの?
  31. WPFアプリケーションで腕試し ~C++でもWPFアプリを
  32. C++11 : スレッド・ライブラリひとめぐり
  33. Google製のC++ Unit Test Framework「Google Test」を使ってみる
  34. メールでデータベースを更新するココロミ
  35. Visitorパターンで遊んでみたよ
  36. Collection 2題:「WPFにバインドできる辞書」と「重複を許す検索set」
  37. Visual C++ 2012:stateless-lambdaとSQLiteのぷち拡張
  38. 「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能

@IT

  1. Vista時代のVisual C++の流儀(前編)Vista到来。既存C/C++資産の.NET化を始めよう!
  2. Vista時代のVisual C++の流儀(中編)MFCから.NETへの実践的移行計画
  3. Vista時代のVisual C++の流儀(後編) STL/CLRによるDocument/Viewアーキテクチャ
  4. C++開発者のための単体テスト入門 第1回 C++開発者の皆さん。テスト、ちゃんとしていますか?
  5. C++開発者のための単体テスト入門 第2回 C++アプリケーションの効率的なテスト手法(CppUnit編)
  6. C++開発者のための単体テスト入門 第3回 C++アプリケーションの効率的なテスト手法(NUnit編)

AWARDS


Microsoft MVP
for Visual Developer - Visual C++


Wankuma MVP
for いぢわる C++


Nyantora MVP
for こくまろ中国茶

Xbox

Links

記事カテゴリ

書庫

日記カテゴリ

逆引き可能な辞書

ネタ元 → グローバル変数を使いたくない

     「オリンピックの参加国がそれぞれどの競技に選手を派遣しているか」
     のデータから
    「オリンピックの各競技はそれぞれどの国からの選手で競われるか」
     を割り出すようなものです。

スピードを気にしなくていいならそんなにメンドくもなさげー

using System;
using System.Collections.Generic;

namespace Wankuma.Episteme {

  public class ListOfPair<TKey,TValue> : IList<KeyValuePair<TKey,TValue>> {
    private List<KeyValuePair<TKey,TValue>> list_ = new List<KeyValuePair<TKey,TValue>>();
    public bool Add(TKey key, TValue val) {
      KeyValuePair<TKey,TValue> item = new KeyValuePair<TKey,TValue>(key,val);
      if ( list_.Contains(item) ) {
        return false;
      }
      list_.Add(item);
      return true;
    }
    public bool Remove(TKey key, TValue val) {
      return list_.Remove(new KeyValuePair<TKey,TValue>(key,val));
    }
    public bool ContainsKey(TKey key) {
      foreach ( KeyValuePair<TKey,TValue> pair in list_ ) {
        if ( pair.Key.Equals(key ) ) return true;
      }
      return false;
    }
    public bool ContainsValue(TValue val) {
      foreach (KeyValuePair<TKey, TValue> pair in list_ ) {
        if (pair.Value.Equals(val)) return true;
      }
      return false;
    }
    public IEnumerable<TKey> KeysOf(TValue val) {
      List<TKey> result = new List<TKey>();
      foreach (KeyValuePair<TKey, TValue> pair in list_ ) {
        if (pair.Value.Equals(val) && !result.Contains(pair.Key) ) {
          result.Add(pair.Key);
        }
      }
      return result;
    }
    public IEnumerable<TKey> Keys() {
      List<TKey> result = new List<TKey>();
      foreach (KeyValuePair<TKey, TValue> pair in list_) {
        if ( !result.Contains(pair.Key) ) {
          result.Add(pair.Key);
        }
      }
      return result;
    }
    public IEnumerable<TValue> ValuesOf(TKey key) {
      List<TValue> result = new List<TValue>();
      foreach (KeyValuePair<TKey, TValue> pair in list_) {
        if (pair.Key.Equals(key) && result.Contains(pair.Value) ) {
          result.Add(pair.Value);
        }
      }
      result.Sort();
      return result;
    }
    public IEnumerable<TValue> Values() {
      List<TValue> result = new List<TValue>();
      foreach (KeyValuePair<TKey, TValue> pair in list_) {
        if ( !result.Contains(pair.Value) ) {
          result.Add(pair.Value);
        }
      }
      result.Sort();
      return result;
    }
    #region IList<KeyValuePair<TKey,TValue>> メンバ
    public int IndexOf(KeyValuePair<TKey, TValue> item)
      { return list_.IndexOf(item); }
    public void Insert(int index, KeyValuePair<TKey, TValue> item)
      { list_.Insert(index, item); }
    public void RemoveAt(int index)
      { list_.RemoveAt(index); }
    public KeyValuePair<TKey, TValue> this[int index]
      { get { return list_[index]; } set { list_[index] = value; } }
    #endregion

    #region ICollection<KeyValuePair<TKey,TValue>> メンバ
    public void Add(KeyValuePair<TKey, TValue> item)
      { list_.Add(item); }
    public void Clear()
      { list_.Clear(); }
    public bool Contains(KeyValuePair<TKey, TValue> item)
      { return list_.Contains(item); }
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
      {  list_.CopyTo(array, arrayIndex); }
    public int Count
      { get { return list_.Count; } }
    public bool IsReadOnly
      { get { return false; } }
    public bool Remove(KeyValuePair<TKey, TValue> item)
      { return list_.Remove(item); }
    #endregion

    #region IEnumerable<KeyValuePair<TKey,TValue>> メンバ
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
      { return list_.GetEnumerator(); }
    #endregion

    #region IEnumerable メンバ
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
      { return list_.GetEnumerator(); }
    #endregion
  }

  public class Program {
    public static void Main() {
      ListOfPair<string,string> olympic = new ListOfPair<string,string>();
      olympic.Add("US", "マラソン");
      olympic.Add("JP", "マラソン");
      olympic.Add("UK", "マラソン");
      olympic.Add("CH", "マラソン");
      olympic.Add("US", "100m");
      olympic.Add("JP", "100m");
      olympic.Add("UK", "100m");
      olympic.Add("JP", "400m");
      olympic.Add("US", "400m");
      olympic.Add("US", "砲丸投げ");

      Console.Write("\n参加国: ");
      foreach ( string item in  olympic.Keys() ) Console.Write(" {0}", item);
      Console.Write("\n競技種目: ");
      foreach (string item in olympic.Values()) Console.Write(" {0}", item);
      Console.WriteLine("\n\n競技種目毎の参加国");
      foreach (string game in olympic.Values()) {
        Console.Write("{0} : ", game);
        foreach ( string country in olympic.KeysOf(game) ) {
          Console.Write(" {0}", country);
        }
        Console.WriteLine();
      }
    }
  }

}

投稿日時 : 2009年3月9日 13:44

コメントを追加

# re: 逆引き可能な辞書 2009/03/09 14:12 NyaRuRu

元の問題は Enumerable.ToLookup 使えば一発なような.
あんまりまじめに読んでないですが.

http://msdn.microsoft.com/ja-jp/library/system.linq.enumerable.tolookup.aspx

# re: 逆引き可能な辞書 2009/03/09 14:31 επιστημη

Lookup<Key,Value> なんてのがあんのかー
こんな便利なもんをナゼに
Sustem.Collections.Generic
に置いてくんないんだろ(ぷんすか)。

# re: 逆引き可能な辞書 2009/03/09 14:45 NyaRuRu

using System;
using System.Collections.Generic;
using System.Linq;

enum Country { US, JP, UK, CH, }
enum Event { マラソン, _100m, _400m, 砲丸投げ, 野球, }

static class Program
{
  static void Main(string[] args)
  {
    var data = new[]
    {
      new { Country = Country.US, Event = new[] {Event.マラソン, Event._100m, Event._400m, Event.砲丸投げ, } },
      new { Country = Country.JP, Event = new[] {Event.マラソン, Event._100m, Event._400m, } },
      new { Country = Country.UK, Event = new[] {Event.マラソン, Event._100m, } },
      new { Country = Country.CH, Event = new[] {Event.マラソン, } },
    };

    var lookup = data.SelectMany(item => item.Event.Select(e => new { item.Country, Event = e }))
             .ToLookup(item => item.Event, item => item.Country);

    // 100m競争
    Console.WriteLine("100m: " + lookup[Event._100m].ToStringAndJoin());

    // 野球
    Console.WriteLine("野球: " + lookup[Event.野球].ToStringAndJoin());

    Console.WriteLine();

    // 全列挙
    foreach (var g in lookup)
      Console.WriteLine("{0}\t{1}",
        g.Key,
        g.ToStringAndJoin());
  }
}

static class Util
{
  public static string ToStringAndJoin(this IEnumerable<string> source, string separator)
  {
    return string.Join(separator, source.ToArray());
  }
  public static string ToStringAndJoin(this IEnumerable<string> source)
  {
    return string.Join(", ", source.ToArray());
  }
  public static string ToStringAndJoin<T>(this IEnumerable<T> source, string separator)
  {
    return source.Select(_ => _.ToString()).ToStringAndJoin(separator);
  }
  public static string ToStringAndJoin<T>(this IEnumerable<T> source)
  {
    return source.Select(_ => _.ToString()).ToStringAndJoin();
  }
}

# re: 逆引き可能な辞書 2009/03/09 15:13 επιστημη

ないすー♪

# re: 逆引き可能な辞書 2009/03/09 18:26 ground

これでどうでしょう
var list = new[] {
new {Country = "US", Sport="マラソン"},
new {Country = "JP", Sport="マラソン"},
new {Country = "UK", Sport="マラソン"},
new {Country = "CH", Sport="マラソン"},
new {Country = "US", Sport="100m"},
new {Country = "JP", Sport="100m"},
new {Country = "UK", Sport="100m"},
new {Country = "JP", Sport="400m"},
new {Country = "US", Sport="400m"},
new {Country = "US", Sport="砲丸投げ"},
};

Console.WriteLine("競技ごと");
var sports =
from s in list
group s.Country by s.Sport;
foreach (var s in sports)
{
Console.WriteLine(s.Key);
foreach (var c in s)
Console.WriteLine("\t" + c);
}

Console.WriteLine("国ごと");
var countries =
from s in list
group s.Sport by s.Country;
foreach (var c in countries)
{
Console.WriteLine(c.Key);
foreach (var s in c)
Console.WriteLine("\t" + s);
}

タイトル  
名前  
URL
コメント