• ベストアンサー

Dosのdir/pのようなアルゴリズム

JavaでRandom Access Fileから読み出して表示するプログラムを作っています。 ただ、次の指示がアルゴリズムとして浮かびません。 ... It should display as many records as will fit on a single screen, and then prompt the user with the following: Return to the main menu (M); Next screen (N); or Display all (A). Dosでのdir/pみたいな働きだと思います。 3時間やってもまだ出来ません(泣)。 Next screenのところは適当に10 recordsずつにします。 recordの数は100とかになりそうです。 MかNかA以外に押された場合は適当にreturnにします。 ファイルの長さはoutLengthで定義しています。 今回は簡素化しました。 jも本当は2つずつ増えますが無視します。 下のは私の苦労の結果です。 アルゴリズムが見える方、助けてください。m(__)m RandomAccessFile inout = new RandomAccessFile (output_file, "r"); outLength = inout.length(); String prompt; System.out.println("Return to the main menu (M); Next screen (N); or Display all (A)"); System.out.print("Enter an option: "); prompt = io.readLine(); if (prompt.charAt(0) == 'M') return; else if (prompt.charAt(0) == 'N') else if (prompt.charAt(0) == 'A') else return; //繰り返したい処理(このままだと全部表示) for (int j=0; j<outLength; j++) { inout.seek(j * REC_SIZE); yearR = ""; placeR = ""; for (int i = 0; i < yearLen; i++) yearR += inout.readChar(); for (int i = 0; i < placeLen; i++) placeR += inout.readChar(); System.out.println(yearR + placeR); }

  • ginkgo
  • お礼率94% (132/139)
  • Java
  • 回答数2
  • ありがとう数3

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

  • ベストアンサー
  • gatyan
  • ベストアンサー率41% (160/385)
回答No.1

日本語で処理を書くとこんな感じにすればいいのでは? (Javaはよく知らないのですが…) 表示カウンタを0にする ここから繰り返す 1つデータ読んで表示し、表示カウンタを+1する 表示カウンタが特定の数(1画面に表示できる限界の数)なら、プロンプトを表示し、指示を求める ※1 ここから繰り返すに戻る ※1 DisplayAllが残り全部一気に表示なら、一気表示フラグを設けて、カウンタの+1をスキップさせるか、表示件数のチェックをしないようにする プロンプト表示をしたら、表示カウンタは0にする メニューに戻るのは、ReturnやBreakで脱出する

ginkgo
質問者

お礼

ようやく、出来ました。 苦労と成果のほどを見てやって下さい。 int pRepeat = 0, allDisp = 0; String prompt; while(true) { if ((pRepeat != 0) && (pRepeat%20 == 0) && (allDisp == 0)) { System.out.println("M: Menu N: Next screen A: Display all"); System.out.print("Enter an option: "); prompt = io.readLine(); if (prompt.charAt(0) == 'M' || prompt.charAt(0) == 'm') break; else if (prompt.charAt(0) == 'N' || prompt.charAt(0) == 'n'); else if (prompt.charAt(0) == 'A' || prompt.charAt(0) == 'a') allDisp = 1; else return; } inout.seek(pRepeat * REC_SIZE); yearR = ""; endR = ""; placeR = ""; referenceR = ""; descriptionR = ""; for (int i = 0; i < yearLen; i++) yearR += inout.readChar(); for (int i = 0; i < endLen; i++) endR += inout.readChar(); for (int i = 0; i < placeLen; i++) placeR += inout.readChar(); for (int i = 0; i < referenceLen; i++) referenceR += inout.readChar(); for (int i = 0; i < descriptionLen; i++) descriptionR += inout.readChar(); System.out.print(pRepeat/2 + ". "); System.out.println(yearR + endR + placeR + referenceR + descriptionR); pRepeat+=2; } pRepeat = 0; allDisp = 0; inout.close(); ありがどうございました!

その他の回答 (1)

  • kacchann
  • ベストアンサー率58% (347/594)
回答No.2

全体の骨格と、「N」を入力したときの処理だけ書いてみました。 けっこう長い・・・。 実際にこれをmain()関数にすれば、動くと思います。 残りの処理も、なんとか考えてがんばってくだされ。 ひとつ、ginkgoさんのソースコードで、最後の「繰り返し処理」の ところの繰り返し数が間違ってるので、指摘しておきます。 (ファイルの長さ分ループさせるのではなく、レコード数ぶんループさせる。 わかりますよね?) -------------------------------------------------- final int yearLen = 4;//データサイズ(char単位) final int placeLen = 10;//データサイズ(char単位) int curPage = -1;//現在、何ページ目を表示しているか String menuStr="Main(M); Next(N); All(A)\n Enter option: ";//メニュー String prompt;//入力用 final int RECS_IN_PAGE = 10;//1ページ内に表示するレコード数 int REC_SIZE = (yearLen+placeLen)*2;//1レコードのサイズ(byte単位)   //たしか 1char = 2 byte だったような・・・。違うかな? String yearR, placeR; int offset;//ファイル内の位置(byte) int recNumber;//レコード番号 RandomAccessFile inout=null; try {  inout = new RandomAccessFile("abc.txt", "r");  long outLength = inout.length();//ファイル長(byte)  int NUM_OF_ALL_RECS   = (int)(outLength/REC_SIZE);//ファイルに記録された全レコード数  BufferedReader io =   new BufferedReader(new InputStreamReader(System.in));//キー入力用  //メインループ  while (true) {   /**    *メニュー表示とユーザ入力待ち   **/   System.out.println(menuStr);//メニュー表示   prompt = io.readLine();//ユーザ入力待ち   if (prompt.charAt(0) == 'M') {    continue;//メインループ先頭へ戻る   }else if (prompt.charAt(0) == 'N') {    curPage++;//ページをめくる //(つまりNを押すたびにこの値が増える。ページをめくる)   }else if (prompt.charAt(0) == 'A') {    System.exit(0);//とりあえず終了   }else {    System.exit(0);//終了   }   //ココに到達したということは、「N」が入力されたということ   /**   *1ページ分だけ表示   **/   for(int j=0 ; j<RECS_IN_PAGE;j++){   //(※1ページに表示するレコード分だけループ)    //ファイル先頭からどれだけジャンプするか計算    recNumber = j+ RECS_IN_PAGE*curPage;//レコードの番号      //(上式は、何ページ目の何番目のレコードか、と考えている)    if (recNumber >= NUM_OF_ALL_RECS ) {     System.out.println("---no more record!!---");//もうないよ     break;//このforループを抜ける    }    offset = recNumber*REC_SIZE;//そのレコード先頭のファイル位置    //レコード先頭へジャンプ    inout.seek(offset);    yearR = "";    placeR = "";    for (int i = 0; i < yearLen; i++) {     yearR += inout.readChar();    }    for (int i = 0; i < placeLen; i++) {     placeR += inout.readChar();    }    //1レコード表示    System.out.println(yearR+ placeR);   }//forループ終わり  }//メインループ(whileループ)終わり } catch (IOException e) {}

ginkgo
質問者

お礼

はっ! 実はgatyanさんの回答を基に今ちょうど自分で終えたところなんですよ。 コードで書いて下さってたんですね。 でも何時間か前にここをチェックしたんですよ…その時はまだ回答はgatyanさんだけでした…。 >たしか 1char = 2 byte だったような・・・。違うかな? はい、仰る通りです。そこが複雑→簡素化した部分です(本当はoutLength/2でした)。 jの値も本来なら2bytesずつ増えます。 アルゴリズムさえあれば、というのと、少しでも複雑になっていると回答が来ないかな、と恐れで簡素化しました。分かる人にはやっぱり分かるんですね。次回からそのまま載せますね。 …あ、そうそう、それがですね、(先週Hello Worldを打ったような不束者なのでよく分かりませんが)lengthで割り出した値(=(outLength/2)/132)を使わずに、while(true)のまま出力させてもエラーにならずに何故か無事終了します。C++なら無限にゴミを吐きまくってるところでしょうに…。ま、たまたま、なんでしょうけど(^^ゞ 後でkacchannさんのコードを参考にきちんとレコードの数を数えてから表示するように変更してみます。 ありがとうございました!

関連するQ&A

  • 数独を解くアルゴリズム

    バックトラック法で解いているのですが、どこがおかしいのか見当もつかないので教えてください。 コンパイルエラーはありません。 表示の関数は省いてあります。 よろしくお願いします。 #include <stdio.h> #define M 3 //小さいブロックのサイズ #define N M*M //全体のサイズ #define MTX N*N //全体のマス数 int sudoku[N][N]={    {0,2,4,5,0,0,6,0,0},    {0,0,6,3,2,0,0,0,4},    {0,0,5,0,9,0,0,8,3},    {0,0,8,4,0,3,0,0,1},    {0,6,1,9,0,0,4,3,0},    {7,0,0,1,0,0,5,0,0},    {8,3,0,0,4,0,9,0,0},    {4,0,0,0,3,5,8,0,0},    {0,0,7,0,0,9,3,4,0}    }; /* 候補がOKかどうかチェック */ int OKkouho(int x, int y, int k) {    int i,j;    int p,q;    for(i=0; i < N; i++){ //その行に候補は入るか       if(sudoku[y][i] == k)          return 0;    }    for(j=0; j < N; j++){ //その列に候補は入るか       if(sudoku[j][x] == k)          return 0;    }    p = x/M*M;    q = y/M*M;    //そのブロックに候補は入るか    for(j = q; j < q+M; j++){       for(i = p; i < p+M; i++){          if(sudoku[j][i] == k)             return 0;       }    }    return 1; } void Solve(int level) {    int k;    int x,y;    if(level >= MTX){       printf("OK");       return;    }    x = level%N;    y = level/N;    if(sudoku[y][x])       Solve(level+1);    else{       for(k = 1; k <= N; k++){          if(OKkouho(x,y,k)){             sudoku[y][x] = k;             Solve(level+1);             sudoku[y][x] = 0;             }       }    } } int main(void) {    Solve(0);    return 0; }

  • アルゴリズム

    public class A1 { public static void main(String[] args) { int[] dataes = {10, 8, 9, 3, 2, 1, 4, 6, 5, 0}; System.out.println("result index = " + search(dataes, 2)); } public static int search(int[] dataes, int valueToFind) { for (int i = 0; i < dataes.length; i++) { if (dataes[i] == valueToFind) { return i; } } return -1; } } このプログラムのフローチャートを教えてください

    • ベストアンサー
    • Java
  • 選択ソートアルゴリズム(selection sort)について 質問No.1226692のつづき

    BLUEPIXYさん、keikanさんありがとうございました。せっかく教えていただいたのですが、セグメンテーションエラーが出てしまいます。 選択法で基準値(pivot)を使用し、K番目に小さい要素を見つけるプログラムを作成しようとしています。しかし、コンパイル時にセグメンテーションフォルトメッセージが出力されるのですが、どこが間違っているのかわからず、途方にくれています。どなたか教えていただきたく。よろしく御願いいたします。 #include<stdio.h> int s[100]={27,10,12,20,25,13,15,22}; int pivotpoint; int selection(int, int, int); //void partition(int, int, int); main(){ int num; num=selection(0,7,3); printf("The third smallest is %d?n ", num); } int selection(int low,int high,int k) { void partition(int, int, int); //int pivotpoint; if(low==high) return s[low]; else{ partition(low,high,pivotpoint); if(k==pivotpoint) return s[pivotpoint]; else if(k<pivotpoint) return selection(low,pivotpoint-1,k); else return selection(pivotpoint+1,high, k); } } void partition(int low,int high,int pivotpoint) { int i,j; int pivotitem; int tmp; pivotitem=s[low]; j=low; for(i=low+1;i<=high;i++){ if(s[i]<pivotitem){ j++; tmp=s[i]; s[i]=s[j]; s[j]=tmp; } } pivotpoint=j; tmp=s[low]; s[pivotpoint]=s[low]; s[low]=tmp; }

  • sortアルゴリズムにおけるstack操作

    あるサイトさんを参考にしてstackを用いたソートアルゴリズムを作っていたのですが、先ほど偶然完成してしまいました。 スタックの動きがよく分からないまま出来てしまったので何だか腑に落ちません・・・ (参考にしたサイトさんも解説がありませんでした) よろしければ(1)~(3)の部分の解釈を教えていただけないでしょうか? よろしくお願いしますm(_ _)m void sort(int A[], int a, int b) /* 昇順整列 */ { int i, j; int pvt; /* 枢軸 */ int sp = 0; /* スタックポインタ */ int left_stc[64], right_stc[64]; while(FOREVER){ pvt = a[b], i = a, j = b-1; while(i < j){ while(A[i] < pvt) i++; while(A[j] > pvt) j--; if(i < j){ swap(&A[i], &A[j]); i++; j--; } } if(A[i] > pvt) swap(&A[i], &A[b]); (1)if(a < i-1){ left_stc[sp] = i; right_stc[sp++] = b; b = i-1; continue; } (2)if(i+1 < b){ a = i+1; continue; } (3)else{ if((sp--) <= 0) break; a = left_stc[sp]; b = right_stc[sp]; continue; } } }

  • Cのソースコードについて

    #include<stdio.h> int main(void) { long a[6000],sum[6000],max=0; int i,j=0,n,m; for (m = 0; m <= 6000; m++) sum[m] = 0; for (i = 0;; i++) { scanf_s("%ld", &a[i]); if (a[i] > 0) sum[j] += a[i]; else if (a[i] < 0) { j++; sum[j] = -1; j++; } else break; } for (n = 0; sum[n] == 0; n++) { if (max < sum[n]) max = sum[n]; } printf("%ld",max); while(1){} return 0; } こんなコードを書いたのですが 答えが常に0になってしまいます。 原因がはっきりしないので教えてください 使用言語はCです

  • 関数に配列を渡す場合のプログラムについて

    猫でもわかるc言語プログラミングという本に #include <stdio.h> int showint(int x[][2]); int main() { int a[][2] = {1,2, 3,4, 5,6, 7,8 }; showint(a); return 0; } int showint(int m[][2]) { int i , j; for(i = 0;i < 4;i++){ for(j = 0; j < 2 ; j++){ printf("m[%d][%d] = %d\n", i, j, m[i][j]); } } return 0; } というソースコードがあり、 showint関数の int showint(int m[][2])はint showint(int **)やint showint(int (*m)[2])とも書ける とかかれてあったのですが、どうしてそうなのかがわかりません。 また、自分の考えではshowint(a);の部分のaは配列名=a[0][0]のアドレスなので、 (int m[][2])の部分はポインタでないといけないのではないかと思うのですが どうでしょうか?実行すると正しく動作していたので、間違っているのはわかっているんですが・・・。 初心者なので、詳しく説明していただけるととてもありがたいです。 よろしくお願いします。

  • クイックソートの分割アルゴリズムについて。

    int partition(int[] a,int i,int j,int x){ int l=i,r=j; // 検索が交差するまで繰り返します while(l<=r){ // 軸要素以上のデータを探します while(l<=j && a[l]<x) l++; // 軸要素未満のデータを探します while(r>=i && a[r]>=x) r--; if(l>r) break; int t=a[l]; a[l]=a[r]; a[r]=t; l++; r--; } return l; } この部分でたとえば数値が{5,9,4,2,8,6}と与えられているとしたらどのような交換手順で分割していくのでしょうか?

  • パスカルのピラミッドを作りたいのですが...

    */ 入力した段数のパスカルの三角形をつくる */ #include <stdio.h> /*---nCr値を返す---*/ int comb(int n,int r) { if (r == 0 || r == n) return (1); else if (r == 1) return (n); else return (comb(n - 1,r-1) + comb(n - 1,r)); } int main(void) { int ln; int i,j; do{ printf(" 段数を入力して下さい:"); scanf("%d",&ln); }while (ln < 1); if (r == 0 || r == n) return (1); else if (r == 1) return (n); else return (comb(n - 1,r-1) + comb(n - 1,r)); } int main(void) { int ln; int i,j; do{ printf(" 段数を入力して下さい:"); scanf("%d",&ln); }while (ln < 1); for (i = 0; i < ln; i++){ for(j = 0;j < ln - i;j++) putchar(' '); for(j = 0; j < i; j++){ printf("%d",comb(i,j)); printf(" "); } putchar('\n'); } return (0); } と作ったら、うまく 1 1 1 1 2 1 1 3 3 1 とは表示されず、 1 1 2 1 3 3 1 4 6 4 となってしまいます。 どこを直せばよいのでしょうか。教えて下さるとうれしいです。 よろしくお願い致します。

  • 最小ヒープソートについて

    問題:numbers.datから10個の整数を読みこみヒープソートで昇順に表示せよ。 numbers.dat 91 63 71 14 60 1 24 13 80 15 質問:下記が自分のコードなんですが実行すると 1 13 13 13 13 13 13 13 13 13になるんですが、何を直せばいいでしょうか。最小の値を取り出していくようにしているつもりなんですが #include<stdio.h> #include<stdlib.h> void insert( int i,int a[], int n); int deletemin(int a[], int n,int m); int main() { int a[10],m[10]; int i,j,k; int n = 10; FILE *fp; fp = fopen("numbers.dat", "r"); if(fp == NULL) { printf("ファイルが開けません\n"); return 1; } fscanf(fp,"%d %d %d %d %d %d %d %d %d %d\n",&a[0] ,&a[1] ,&a[2] ,&a[3] ,&a[4] ,&a[5] ,&a[6] ,&a[7] ,&a[8],&a[9] ); for(i = (n - 2)/2; i >= 0; i--) { insert(i, a, n-1); } for(i = n-1; i >= 0; i-- ) { m[9-i] = deletemin(a, i, n-1); } for(j = 0; j < 10; j++){ printf("%3d",m[j]); } return 0; } void insert( int i,int a[], int n) { int j; int temp; while (2 * i + 1 <= n) { j = 2 * i + 1; if (j < n) { if (a[j] > a[j + 1]) { j++; } } if (a[i] <= a[j]) { break; } temp = a[j]; a[j] = a[i]; a[i] = temp; i = j; } } int deletemin(int a[],int n, int m) { int b; int temp; int i,j; b = a[0]; a[0] = a[n]; i = 0; while (2 * i + 1 <= m) { j = 2 * i + 1; if (j < m) { if (a[j] > a[j + 1]) { j++; } } if (a[i] <= a[j]) { break; } temp = a[j]; a[i] = a[j]; a[i] = temp; i = j; } return b; }

  • 遺伝的アルゴリズム

    遺伝的アルゴリズムのプログラムを作っているのですがサンプルソースの下の関数のやってこるこがよく意味がわかりません。よかったら解説 お願いします。 // 一点交叉 void one_point_crossover(struct genotype *ind) { int i, ia, ib; // 個体インデックス int j; // 遺伝子座インデックス int c; // 交叉点 int test[M]; // 個体の利用フラグ int temp[N]; // 遺伝子を入れ替えるための仮変数 // 4/24修正 int r; // 乱数値 for(i=0; i<M; i++) test[i] = 0; ia = ib = 0; for(i=0; i<M/2; i++) { // 個体をランダムにペアリング for(; test[ia]==1; ia=(ia+1)%M); test[ia] = 1; r = random() % (M-2*i) + 1; while(r>0) { ib=(ib+1)%M; for(; test[ib]==1; ib=(ib+1)%M); r--; } test[ib] = 1; // 個体iaとibを交叉 if(flip(Pc)) { c = random() % N; for(j=0; j<c; j++) { temp[j] = ind[ia].gene[j]; ind[ia].gene[j] = ind[ib].gene[j]; ind[ib].gene[j] = temp[j]; } } } } // End of one_point_crossover()

専門家に質問してみよう