C#の動的配列のソート方法とは?

このQ&Aのポイント
  • C#でMIDIファイルを解析する際にトラック別の音符情報をソートする方法が知りたいです。
  • 現在、音符情報を別のクラスにコピーしてソートしているため時間がかかっています。
  • データをコピーせずに効率的にソートする方法があれば教えてください。
回答を見る
  • ベストアンサー

C#の動的配列について

こんにちは。今C#でMIDIファイルを解析するプログラムを開発しているのですが、 ファイルからトラック別の音符情報を読み取ってソートするのに結構な時間がかかるのです。 データをソートするのにいちいち別のクラスに全部コピーしてるせいだと思うのですが、データをコピーせずにソートする方法はあるのでしょうか。(もしくは、もっと早い方法) //絶対時間、周波数、フラグ:1=発音 0=消音 ArrayList _time = new ArrayList(); ArrayList _freq = new ArrayList(); ArrayList _flag = new ArrayList(); ~中略~ ~↓本体の一部~ switch (lastStates & 0xF0) { case 0x80: // 音を消す case 0x90: // 音を鳴らす double hz = base_frq * Math.Pow(2.0, (d[addr + 1] - 69) / 12.0); //音の周波数 _freq.Add(hz); _time.Add((long)time);//time=算出した絶対時間 if (d[addr + 1] != 0x0 && (lastStates & 0xF0) == 0x90) _flag.Add(1); else _flag.Add(0); break; ~中略~ musicData[] list = new musicData[_time.Count]; for (int i = 0; i < _time.Count; i++) { list[i] = new musicData((long)_time[i], (int)_freq[i], (int)_flag[i]); } Array.Sort(list);//時間で並べ替え ~中略~ class musicData : IComparable<musicData> { public long time; public int frq; public int flag; public musicData(long time, int frq, int flag) { this.time = time; this.frq = frq; this.flag = flag; } int IComparable<musicData>.CompareTo(musicData other) { return this.time.CompareTo(other.time); } } ソースは以上です。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kero_mio
  • ベストアンサー率90% (94/104)
回答No.1

ArrayList に頼っているということは、VS.NET 2003か2002あたりで 開発してますか? 2002/2003で開発されているのであれば、SortedListを使ってみてはいかがでしょう?そうするとソートの必要性がないような気がします。 ■SortedList http://msdn.microsoft.com/ja-jp/library/system.collections.sortedlist(VS.80).aspx また、VS.NET2005/2008で開発しているのであれば、 Genericが使えるので、SortedList(Of TKey, TValue) を使い、さらに高速に処理でき、ソートの手間もいくぶん はぶけると思います。 ■SortedListのGeneric http://msdn.microsoft.com/ja-jp/library/ms132319(VS.80).aspx MIDIは詳しくない上に、上記ソースからでは、何がしたいのか 若干読み取れなかった部分がありますが、 Array.Sort(list);//時間で並べ替え の部分の"list"のソートが 重いってことだけはわかったので、Arrayではなく、SortedListの 導入をご検討ください。 ご参考になれば幸いです。

satosi3141
質問者

お礼

探していたのはまさにこれです。ありがとうございます! こんな便利なものがあるとは知らず・・・ ジェネリックも今度勉強しようと思います。 ありがとうございました!

関連するQ&A

  • ArrayList で配列を扱う場合の記述方法について

    ArrayList で配列を扱う場合の記述方法について、 探しきれないのでご教授お願いします。 ArrayList list = new ArrayList(); list.add("AAA"); list.add("BBB"); list.add("CCC"); for (int i = 0; i < list.size(); i++) { System.out.println(i+"は"+list.get(i)); } という箇所をArrayList<Date>listを使って書き直すのはどのようになるでしょうか。 ArrayList<Date>list= new ArrayList<Date>(); list.add("AAA"); list.add("BBB"); list.add("CCC"); for (int i = 0; i < list.size(); i++) { System.out.println(i+"は"+list.get(i)); } とすると、 型 ArrayList<Date> のメソッド add(Date) は引数 (String) に適用できません。 というエラーになってしまいました。

    • ベストアンサー
    • Java
  • ソートについて

    以下のプログラムを実行すると整数のソート結果が "1","12","3"となってしまいます。 整数と文字列を分離させてそれぞれソートさせたいのですが 方法がわかりません。 import java.util.*; import java.io.*; class StrArray{ ArrayList list = new ArrayList(); //最下行に要素を追加 public void add(String data){ list.add(data); } //全ての要素を配列で所得 public String[] getAll(){ String[] all = new String[list.size()]; for(int i=0; i<list.size(); i++){ all[i] = super.get(i); } return all; } public static final int ASC_SORT = 0; public void sort(int mode){ ArrayList al = this.qsort(mode, list); al = list; } //クイックソート public ArrayList qsort(int mode, ArrayList data){ ArrayList result = new ArrayList(); if(data.size()<1){ return new ArrayList(); } String middle = (String)data.get(data.size()/2); ArrayList left = new ArrayList(); ArrayList right = new ArrayList(); for(int i=0; i<data.size(); i++){ if(i != data.size()/2){ if(mode == 0){ if(((String)data.get(i)).compareTo(middle)<=0){ left.add(data.get(i)); } else{ right.add(data.get(i)); } result.addAll(qsort(0, left)); result.add(middle); result.addAll(qsort(0, right)); return result; } return result; } } } } class Sample{ public static void main(String args[]){ StrArray alist = new StrArray(); alist.add("bbb"); alist.add("aaa"); alist.add("ddd"); alist.add("ccc"); alist.add("3"); alist.add("1"); alist.add("12"); alist.sort(0); String[] info = alist.getAll(); for(int i = 0; i < info.length; i++){ System.out.println(info[i]); } } }

  • コレクションクラスについて

    ●下記のコードについて質問があります import java.util.*; public class Test { public static void main(String args[]) { ArrayList<ObjectOne> list = new ArrayList<ObjectOne>(); list.add(new ObjectOne()); list.add(new ObjectOne()); list.add(new ObjectOne()); Collections.sort(list); } } class ObjectOne { private int x = 0; private int y = 0; } このソースをコンパイルすると、 シンボル: メソッド sort(java.util.ArrayList<ObjectOne>) 場所 : java.util.Collections の クラス Collections.sort(list); と、エラーが表示されてしまいます。 java.util.*をインポートしているので、上記のようなエラーはでないと 思うのですが、うまくいかないです。おそらく、ObjectOneクラスで 何か処理漏れが起きているのかもしれませんが、エラーとなる原因を 特定することができません。 エラーとなる原因と解消する手立てを教えていただければと思っております。 宜しくお願い致します。 「追記」 ArrayList<ObjectOne> list = new ArrayList<ObjectOne>(); の<ObjectOne>を消せばエラーはなくなりますが、 <ObjectOne>を消さない方針で考えがあればと思っております。

  • C# 配列の配列(多次元配列?)

    C#において、配列の配列中に格納した値を、検索することを 行いたいのですが、格納した値そのものを見ることができません。 まだ、C#を始めて間もないので、配列に格納する時点で、 不備があるかも知れませんが、お願いします。 やりたいこと ・テキストファイル内にある値を、2次元配列または、多次元配列に格納 ・配列に格納した値で、データチェックなどを行う予定  テキストファイル内のデータは、下記内容となり要素数も固定ではなく変動する   A=1,2,3・・・   B=11,22,33・・・ 実際のソースは、 //配列 ArrayList list = new ArrayList(); //配列格納 1レコード毎用 ArrayList listtmp = new ArrayList(); while ((strGenderTextLine = objReader.ReadLine()) != null) {  string strBuffer;  //「=」前の値格納用変数  string[] strBuffer2; //「=」後の値格納用配列  listtmp=null;  //strtmpに「=」前の値を格納  strtmp = TextLine.Split('=').GetValue(0).ToString();  //strtmp2に「=」後の値を格納(配列)  strtmp2 = TextLine.Split('=').GetValue(1).ToString().Split(',');  for (int i = 0; i <= strtmp2.Length - 1; i ++)  {   //[i,0]に、「=」前の値を代入   if (i == 0)   {   listtmp.Add(strtmp);   }   else   {   listtmp.Add(strtmp2[i].ToString());   }  }  //list配列にlistTmp配列を格納(配列の配列)  list.Add(listtmp);  intT = intT + strtmp2.Length;  //行数カウント  intTLine = intTLine + 1;  } ここから、配列「list」内に入っている値を閲覧することができる方法を教えていただければと思います。 宜しくお願いいたします。

  • 配列の抽出

    たびたび失礼します 以下のようなプログラムを記述しました private String[] setWorst(String[] score,String[] score2,String[] score3){ //ソート Data[] Datas = new Data[score.length]; for(int i = 0; i < Datas.length; i++){ Data Data = new Data(); Datas[i] = Data; Data.score = Integer.valueOf(score[i]); Data.s_indicator = s_indicator[i]; Data.center = center[i]; } ScoreComparator scoreComparator = new ScoreComparator(); Arrays.sort(Datas,scoreComparator); //ワーストの抽出 ArrayList worst3 = new ArrayList(); public class Data{ Integer score; String score2; // String score2; // } public class ScoreComparator implements Comparator{ public int compare(Object o1, Object o2){ Data Data1 = (Data)o1; Data Data2 = (Data)o2; int result = Data1.score.compareTo(Data2.score); return result; } } 変数scoreを中心としたソートを作成しました。 次にscoreの値を読み込んで下位4つを抜き出してArrayList worst3に格納していきたいと思っています。 scoreには0~10の数字が入っていますので0~3を抜き出したいということです。 自分でもいろいろ試しましたが、なかなか良い考えが浮かばないので知恵を借りたいと思います。 ヒントやアイデアだけでも結構ですので、よろしくお願いします。

  • StringクラスのcompareToメソッド

    ArrayListに登録した文字列を五十音順にソートしようと思いComparator を使用して 以下のようなサンプルプログラムを作ってみました。 ところが想定していたような {赤ちゃん、富士山、山口県}とはならず {富士山、山口県、赤ちゃん} というような結果になりました。 compare() の戻り値の部分を return ((String)arg1).compareTo((String)arg0); に変更しても{赤ちゃん、山口県、富士山} となり辞書の並びとは異なる結果になりました。 辞書順に並べるにはなにかよい方法はありますでしょうか。 public class compareTest { public static void main(String[] args) { ArrayList<String> array = new ArrayList<String>(); String a = "赤ちゃん"; String b = "山口県"; String c = "富士山"; array.add(a); array.add(b); array.add(c); for(int i=0;i<array.size();i++) { System.out.println("ソート前=" + array.get(i)); } Collections.sort(array, new testComp()); for(int i=0;i<array.size();i++) { System.out.println("ソート後=" + array.get(i)); } } } public class testComp implements Comparator { public int compare(Object arg0, Object arg1) { return ((String)arg0).compareTo((String)arg1); } }

    • ベストアンサー
    • Java
  • ArrayListを使った多次元配列の作成について

    ArrayListで可変長配列を扱っているのですが、 2次元可変長配列を用いる必要が出てきたので、 下記のように変更したのですがうまくいきません。 何が悪いのか教えていただけませんでしょうか? ----------------------------------------- ArrayList cars=new ArrayList(); cars.add("フェラーリ"); cars.add("ポルシェ"); cars.add("メルセデスベンツ"); for(int i=0;i<cars.size();i++){  String str=(String)cars.get(i);  System.out.println(str);} ----------------------------------------- 上記から下記のように変更しました。 ----------------------------------------- ArrayList[] cars=new ArrayList[3]; cars[0].add("フェラーリ"); cars[0].add("ポルシェ"); cars[0].add("メルセデスベンツ"); for(int i=0;i<cars[0].size();i++){  String str=(String)cars[0].get(i);  System.out.println(str);} ----------------------------------------- エラーは「Exception in thread "main" java.lang.NullPointerException」です。 どうやら初期配列が10ではなく3となってしまっているようです。

    • ベストアンサー
    • Java
  • [C#]Arraylistに追加した構造体の内容の変更

    struct Hoge {     public string name;     public string address; } ArrayList list = new ArrayList(); Hoge test = new Hoge(); test.name = "あいうえお"; test.address = "123"; list.Add(test); test.name = "かきくけこ"; test.address = "456"; list.Add(test); //ここから //list[0].name = "さしすせそ"; のように追加するコードを書きたいです //ここに for (int i = 0; i < List.Count; i++) {     MessageBox.Show((Hoge)List[i]).name.ToString()); } これで、 list[0]のnameには"あいうえお" list[1]のnameには"かきくけこ" が、代入されていますが list[0]のnameをArrayListに追加したあとに変更したいのです。 このままだと、「あいうえお」「かきくけこ」と表示されますが、 「さしすせそ」を途中でlist[0]の代入して、 「さしすせそ」「かきくけこ」と表示したいのです。

  • JSPとJavaBeansについて

    JSPとJavaBeansを用いて情報を共有したいと考えています。 値を取得した後に配列に入れています。 ArrayList list = new ArrayList(); while(rs.next()){ int op = rs.getInt("op"); list.add(new Integer(op)); } int[] in = new int[list.size()]; for (int i = 0; i < list.size(); i++) { in[i] = ((Integer)list.get(i)).intValue(); この後に、in[i]の要素をBeansに送り、別のJSPでその値を使いたいと考えています。 ただ、Beansで配列のデータを扱う場合にはどのようにすれば宜しいのでしょうか? アドバイスを頂けると助かります。 宜しくお願いします。

  • C#.NET ArrayListの使用方法について

    C#.NETを使用しています。ArrayListを宣言、インスタンス化し、 "別々の値を持つ"要素20個をAdd(追加)しているはずなのですが、 要素を取り出して、値を見てみると"同じ値"になってしまっています。 自分なりに考えたのですが原因がわかりません。 どなたかご教授お願いします。 書いたソースは以下のような感じです。 public class Area{ _____// リスト _____public ArrayList list; _____//コンストラクタ _____public Area(){ _________ list = new ArrayList(); __________//要素の作成は以下で行う __________for(int cnt=0;cnt<20;cnt++){ ___________ AddNodeList(new 要素); } _____} _____public void AddNodeList(要素){ _______要素型 a = 要素; _______list.Add(a); _____} }