• ベストアンサー

String配列を扱うアルゴリズムについて

よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

  • Java
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • BigBoin
  • ベストアンサー率36% (4/11)
回答No.2

BLUEPIXYさんのご回答の様にレコード数で回してその中で各カラムにアクセスする方法がスタンダードな感じがします。 しかし速度的には恐らく変わらないのではないでしょうか?元がString[][]ですのでgogosdさんのコーディング以外には考えられません。 初期のmaxLen[i]は何が入ってるんでしょう? もしこの初期の値で10以上とか指定ができればもう少し処理回数は減ると思いますがそれでもほとんど分からない程度でしょうね・・・

gogosd
質問者

お礼

ご回答ありがとうございます。 >元がString[][]ですのでgogosdさんのコーディング以外には考えられません。 自分も結局は処理対象の変数型がString[][]ですので、 それ以外には思いつかなかったのですが、何分未熟なもので、他により良い方法があるのではないかと思った次第です。 しかし、そうご指摘頂きましたことで、処理を採用する為の裏打ちとなりました。 >初期のmaxLen[i]は何が入ってるんでしょう? 各maxLen[i]の要素には、int型ですので0が生成されると思います。 >もしこの初期の値で10以上とか指定ができればもう少し処理回数は減ると思いますがそれでもほとんど分からない程度でしょうね・・・ まさにご指摘の通りなのですが、不確定要素の為に指定が行えない状態です・・・。 ご回答ありがとうございました。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

同じようでも 列ループ  行ループ とするより 行ループ  列ループ としたほうがいいかもしれません。 あと、tableData[i][j] は、tableData[j][i]の間違いですよね。

gogosd
質問者

お礼

ご回答ありがとうございます。 ループの順番を逆転させるということですが、その判断要素はどのようなものでしょうか。 宜しければお聞かせ願いたいと思います。 やはり、ループをさせて、全要素を比較していく 方法以外は無いのでしょうかね・・・。 >あと、tableData[i][j] は、tableData[j][i]の間違いですよね。 その通りです。申し訳ございませんでした。 ご回答ありがとうございました。

gogosd
質問者

補足

再質問中申し訳ございませんが、 これ以上回答が得られないと思いますので、 締め切らせていただきます。 ありがとうございました。

関連するQ&A

  • CSVファイルを多次元配列に格納する

    CSVファイルをopenCSVを読み込んでその行と列の要素数の多次元配列を作りその配列にデータを格納したいです。 しかし、データが格納できません。2回目の格納するためにwhileから何かおかしいのではないかと思っています。 なにかわかる方、アドバイスが欲しいです。 public class ReadCSV { public static void main(String[] args){ try{ CSVReader reader = new CSVReader( new FileReader("/home/masa/Desktop/WameiSample.csv")); //配列の宣言 String[] nextLine; //データを配列に入れる要素数を見る int j = 0; nextLine = reader.readNext(); int k = nextLine.length; System.out.println("列数[i]"+k); System.out.println("nextLine"+nextLine); while((nextLine = reader.readNext()) != null){ for (int i=0; i<nextLine.length; i++){ //System.out.print(nextLine[i] + "|" + i + "|"); } //System.out.println(); j++; } System.out.println("行数[j]"+j); //記憶する配列 String[][] Wamei = new String[k][j]; System.out.println("きてるよ"); //データを配列に格納していく int x = 0; while((nextLine = reader.readNext()) != null){ System.out.println("きてるよ");  <---こっから、表示してくれない. for (int y=0; y<nextLine.length; y++){ Wamei[x][y] = nextLine[y]; //多次元配列の要素を表示する System.out.print(Wamei[x][y]+"Wamei"+x+y); } System.out.println(); x++; } } catch (IOException e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • ファイル入力の仕方

    下記のような入力ファイル(input.txt)を配列に格納するプログラムを作成しています。 下のソースコードは行数・列数が一定の場合のものですが、実際の入力データは行数・列数とも不定です。つまり、行数・列数をプログラムで読み取らなければなりません。この場合、ソースコードをどのようにすれば良いのでしょうか? 大変お手数ですが、教えてください。よろしくお願いします。 x y1 y2 y3 y4 10.0 1.2 1.5 1.0 2.1 10.5 1.3 1.4 1.2 2.2 11.0 1.8 1.2 2.2 3.1 11.5 2.1 1.0 1.2 4.5 12.0 1.9 1.1 1.1 5.5 13.0 2.4 1.1 2.1 4.2 ・1行目をchar型配列に格納したい。 ・2行目以降はdouble型配列で1列目をX[]、2列目以降をY[][]に格納したい。 ・行数は20(2行目以降)まで、列数は10(2列目以降)まで #include <stdio.h> #include <stdlib.h> int main(){ int i,j; double X[20],Y[20][4]; char x[2],y[10][4]; FILE *fpi; if((fpi=fopen("input.txt","r"))==NULL){ fprintf(stderr,"Cannot open file.\n"); exit(1); } fscanf(fpi,"%s %s %s %s %s",x,y[0],y[1],y[2],y[3]); printf("%s %s %s %s %s\n",x,y[0],y[1],y[2],y[3]); for(i=0;i<6;i++){ fscanf(fpi,"%lf",&X[i]); printf("%4.1lf ",X[i]); for(j=0;j<4;j++){ fscanf(fpi,"%lf",&Y[i][j]); printf("%4.1lf ",Y[i][j]); } printf("\n"); } printf("\n"); return 0; }

  • 多次元配列の意味がわかりません。

    プログラミング初心者です。 以下の配列の記述があったのですが、どのような配列なのか理解できていません。 すみません。教えていただけますでしょうか。 $n = count($entry_count); for($i=0;$i<$n;$i++){ for($j=$n-1;$j>$i;$j--){ if分が続きます。 } } 私の理解が間違っていなければ、iは行数jは列数と理解しています。 $nが何を示しているのか推測でしか言えませんが、列数と考えれば良いでしょうか? それともデータの件数と考えれば良いでしょうか? 内容はjの初期値がn-1(件数よりマイナス1)として、iより大きい間、jを1つずつ減らしていき iは1つずつ足していく様です。 分からないのは以下の点です。 ・$nはデータの件数でしょうか?  もしそうであればiは始めのfor分はその件数分繰り返すと考えると分かります。  但し、jはどのように理解すれば良いか分かりません。 ・$jがもし列数と考えれば、なぜ初期値が$jの値がマイナス1なのか。  配列のインデックスが0から始まるからでしょうか? ・$jをなぜ1つずつ減らしていくのでしょうか?  列数を1つずつ減らしていくというのは、そのデータの列を前から読み込んでいくという処理の  意味の記述でしょうか? 要するにiとjが何かが理解できていません。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • カウンタを使用した配列の格納について

    EXCEL VBAについての質問です。 どなたか添削願えないでしょうか? A1からE40までSingle形式のデータが入っています。 ただし、A列はすべて見出し、行には5行おきに1,6,11...行目に見出しが入っています。 4x4のデータが8個ある計算です。 見出しを除くデータをすべて(8,4,4)の配列に格納しようと思い、下記のコードをSheet(1)に 書きましたが、「インデックスが有効範囲にありません」と出てうまく格納できません。 上の「Next j」を生かして、下の「Next j」を殺し、イミディエイトウインドウで確認したところ、 ネストの外ではうまくループしているようですが、入れ子にするとデータがうまく入りません。 jのループ完了後には  j=36  データ番号=8 が入っているはずですが、j がうまく格納されないようで、値がすべて0になります。 上の「Next j」と直下の2行をいかした場合、きちんと値が入り、うまく機能するようです。 色々考えましたが、手詰まりになってしまったので、何がおかしいのか教えてもらえません でしょうか?よろしくお願いします。 Option Base 1 Const データ数 As Integer = 8 Const 列数 As Integer = 4 Const 行数 As Integer = 4 Dim データ番号 As Integer Sub 換算値格納() ReDim 換算値(データ数, 行数, 列数) As Single For j = 1 To 36 Step 5 '(例)j=1→データ番号1、j=6→データ番号2、.... データ番号 = (j - 1) / 5 + 1 Debug.Print "データ番号=" & データ番号 & " j=" & j 'Next j 'データ番号 = 8'<任意に変えてみてください> 'j = (データ番号 - 1) * 5 + 1 For i = 4 To 19 '列定義 'カウンタを4で割って1を足したものが0になる (例)14÷4=3...2 → 2+1=3 列 = i Mod 4 + 1 '行定義 'カウンタがちょうど割り切れたら行をひとつ増やす (例)i=4,8,12...にて列=1,2,3 If i Mod 4 = 0 Then 行 = 行 + 1 換算値(データ番号, 行, 列) = Cells(行 + j, 列 + 1).Value Debug.Print "(" & データ番号 & "," & 行 & "," & 列 & ")は" & 換算値(データ番号, 行, 列) Next i Next j End Sub

  • C#で配列の値をチェックするメソッドを書きたい

    C#の配列についてお教え頂けませんでしょうか? CSVファイルから1行読取り、配列に格納しています。 string[] rowdata; string x; int y; double z; TextFieldParser Parser = new TextFieldParser(FILEPATH, Encoding.GetEncoding("shift_jis")); while (!Parser.EndOfData) { //1行読取り rowdata = csvParser.ReadFields(); //読み取った値を変数に x = rowdata[0]; //string y = rowdata[1]; //int z = rowdata[2]; //double } rowdata[0~3]を変数に格納する前に、データのチェックをおこないたいです。 例えば、rowdata[1]はint型変数に格納されます。しかしrowdata[1]に格納された値が「A1」とあった場合、int型変数yには格納できずエラーが起こります。 よって、rowdata[1]に数値以外の文字列があったら「0」に置き換えるなどの処理をいれたいです。 なので、配列を受け取ってデータチェックをするメソッドを作りたいと思いますが、どのように作っていいかがわかりません。 1つのメソッドでint、double、stringかどうかの、チェックを行いたいですが、そのようなことは可能なのでしょうか? 下記のように3つメソッドを作って、データをメソッドに渡しチェックを行なうのがいいのでしょうか? string CheckData(string[] arr){}; int CheckData(int[] arr){}; double CheckData(double[] arr){}; やりたい事は、 メソッド(配列を受取る) rowdata[0]が渡された場合、中身はstringかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[1]が渡された場合、中身はintかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[2]が渡された場合、中身はdoubleかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 以上のような事です。宜しくお願い致します。

  • 配列への文字列の格納について

    C言語で文字列を扱う時、配列に1文字ずつ格納していくか、ポインタ変数を使うと思うのですが、 ポインタ変数を使った場合の処理が上手くできずに困っています。 詳細を説明すると、値を取得して、前回取得した値と比較します。 それで、同じだった場合には"chritm1"に格納した矢印を書き込む処理なのですが、 現在はfor文により配列に格納したものを使用していますが、 この部分をポインタ変数を使用した処理(1文字1文字書くのではなく、string型変数の用に書き込みたい) に変更したいのですが、上手くできないという状況です。 何かとっかかりとなるようなことでもかまいませんので、教えてください。 よろしくお願いします。 static int mainA( char *fileName){ int loop, i, j; FILE *fd; /* 前回値格納用 */ char *preval; /* 現在値格納用 */ char *thisval; /* 同値用記号格納用 */ char chritm1[6] = " → "; -- 中略 -- for( i = 0 ; i < 150 ; i++ ) { thisval = redata[i]; /* 値の比較 */ if(preval == thisval) { for( j = 0 ; j < 6 ; j++){ /* 前回値と同じ場合は矢印 */ fprintf( fd, ",%c",chritm1[j]); } }else{ /* 前回値と異なる場合は値 */ fprintf( fd, ",%s", thisval); } preval = thisval; /*完了したら改行 */ fprintf( fd, "\n" ); } -- 以下略 --

  • Javaの配列の中身の並び替え

    数独の盤面上に、数字が0から9まであり、その数がそれぞれ何個あるのか数える プログラムを書きました。(0というのは、まだマス目がうまってない状態を指します) 以下のプログラムでは、ある座標に着目し、その座標が関連する行・列・ブロックに 数字が何個あるか数えています。(0のマスの数は特に気にしていません) final int x0 = x / 3 * 3; //000 333 666 final int y0 = y / 3 * 3; //その座標が関連するブロック、行、列に存在する値の数を数える //行 for( int i=0; i<9; ++i ){ countNum[state.getNum(i, y)]++; //state.getNum座標の数字を取得しています。 } //列 for( int i=0; i<9; ++i ){ countNum[state.getNum(x, i)]++; } //ブロック    for(int i=x0;i<3;i++){    for(int j=y0;j<3;j++){     if( i!=x || j!=y){ countNum[state.getNum(i, j)]++;    }    } これで、1の数字の個数や、2の数字の個数を求めることができました。 そして、個数の少ない順に並び替えたいのですが、並び替えてしまうと 何の数字が何個なのかわからなくなってしまいます。 どのようにすれば、数字とその個数がわかったまま並び替えをおこなえますか? 配列を二つ準備するべきなのでしょうか? 順番の入った配列と個数の入った配列。というように。

    • ベストアンサー
    • Java
  • 大きさがわからない配列

    String型の配列で、文字列を格納していきたいのですが、 格納する文字列はいくつ来るかわかりません。 配列を大きさを確保しないで、どんどん文字列を 格納していくことはできますか? ブログのURLを格納するのですが、

    • ベストアンサー
    • Java
  • JAVA String型のメモリ上の処理について

    JAVA初心者です。 String s; s = "abc"; という処理で、それぞれ一行ずつの文はメモリ上ではどのようなことを行っているか分かりません。 また、 Sampleclass sc;//自作クラス sc =new Sampleclass(); だとString型と同じ処理が働いているのでしょうか? int型では int i; …メモリ領域の確保(4バイト)し、iを宣言。 i = 3; …メモリ領域のiに000……011を格納。 だと思いますが、どうも同じ考えでは無いようです。 メモリ上だとString,Sampleclassのそれぞれの行はどのようにメモリ上で動いているか教えて下さい。 よろしくお願い致します。 テンプレ String s… s = "abc"… Sampleclass sc… sc =new Sampleclass()…

  • 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」内に入っている値を閲覧することができる方法を教えていただければと思います。 宜しくお願いいたします。

専門家に質問してみよう