Javaでべき乗余を求めるプログラムの実行時間を短縮する方法

このQ&Aのポイント
  • Javaでべき乗余を求めるプログラムの実行時間を短縮する方法について教えてください。
  • 質問者はjavaでべき乗余を求めるプログラムを作成していますが、int Nの大きさを大きくすると実行時間がかなり遅くなってしまいます。
  • 実行時間を早くするための方法はありますか?
回答を見る
  • ベストアンサー

javaでべき乗余

テストプログラムとしてjavaでべき乗余を求めるプログラムを作っているんですがint N の大きさを大きくするとかなり時間がかかってしまいます。実行時間を早くする方法はないでしょうか? import java.math.BigInteger; import java.util.Random; public class s1{ public static void main(String args[]){ BigInteger a = new BigInteger("2"); int N = 100000; BigInteger n,p,q; Random rnd = new Random(); BigInteger f[] = new BigInteger[N]; int bit = 512; int k = 10; p = new BigInteger(bit,k, rnd); q = new BigInteger(bit,k, rnd); n = p.multiply(q); int j; for(j=0;j<N;j++){ f[j]=(a.modPow(BigInteger.valueOf(j), n)) ; } for(j=0;j<N;j++){ System.out.println(j +"="+f[j]); } } }

  • Java
  • 回答数1
  • ありがとう数0

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

えぇと.... f[j] = f[j-1]*a mod n という感じで計算しちゃいかんの?

関連するQ&A

  • Javaで数独の自動解法プログラム

    Javaで次のようなプログラムを作りました。 次に、ここから実行で得られた数独を自動解法プログラムによって、解が「1つ or 複数」かを調べるようにしたいのですが、その自動解法プログラムは新しく作らなければいけないのでしょうか。 import java.util.Random; public class NumberPlace { public static void main(String[] args) { int i, j, k, l, m, n, check=0, count=0, tmp; int a[][] = new int [9][9]; Random rnd = new Random(); int ran; Random rnd1 = new Random(); int ran1; Random rnd2 = new Random(); int ran2; boolean A=false; while(A==false){ A=true; for ( i=0; i<9; i++ ) for ( j=0; j<9; j++ ) a[i][j] = 0; count = 0; for ( i=0; i<9; i++ ) { for ( j=0; j<9; j++ ) { ran = rnd.nextInt(9); tmp = ran + 1; check = 0; //System.out.println(tmp); for ( k=0; k<j; k++ )  //横列に入る数字をチェック if ( a[i][k] == tmp ) check = 1; for ( k=0; k<i; k++ )  //縦列に入る数字をチェック if ( a[k][j] == tmp ) check = 1; for ( k=(i/3)*3; k<(i/3)*3+3; k++ )  //ボックスに入る数字をチェック for ( l=(j/3)*3; l<(j/3)*3+3; l++ ) if ( a[k][l] == tmp ) check = 1; if ( check == 0 ) a[i][j] = tmp; if ( check == 1 ) j--; if ( count > 50000 ){ A=false;break;} count++; } count = 0; } } for ( i=0; i<30; i++ ) {    //0を入れる回数 ran1 = rnd1.nextInt(9); m = ran1; ran2 = rnd2.nextInt(9); n = ran2; if ( a[m][n] == 0 ) {  //0にしようとした場所が既に0だったら直前に戻る i--; } a[m][n] = 0; } for ( i=0; i<9; i++) { for ( j=0; j<9; j++ ) { if ( a[i][j] < 10 ) { System.out.print(" "); } System.out.print(a[i][j]);       } System.out.print("\n"); } } } これを(最初に入れる0の数を30個として)実行すると、次のようになります。 0 7 6 9 4 1 8 2 5 2 0 5 3 7 0 9 4 0 9 0 4 8 2 5 0 3 7 1 0 2 0 0 0 5 0 6 6 9 3 1 0 0 0 8 2 7 0 8 0 0 0 0 1 4 0 0 0 0 0 0 0 0 3 4 3 0 5 6 8 2 7 9 5 2 9 4 3 7 0 0 8 皆さんの回答の程宜しくお願いします。

  • do while文のエラー??

    下のような拡張ユーグリッドのプログラムを組んだのですがエラーが出て何が悪いのかがわかりません。エラーの内容は apRSA.java:18: 型の開始が不正です。 do{ ^ apRSA.java:57: <identifier> がありません。 }while(q.compareTo(BigInteger.ONE) !=0); ^ の二つです。どなたか助けてください。 import java.math.*; import java.util.Random; import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class apRSA extends Applet{ BigInteger p,q,e,d,m,c,m2,t,t1,p1,q1,e1; final int bit =512; final int k =10; Random rnd =new Random(); do{ p=new BigInteger(bit,k,rnd); p1=p; q=new BigInteger(bit,k,rnd); q1=q; BigInteger []x; BigInteger []y; BigInteger []z; x =new BigInteger[3]; y =new BigInteger[3]; z =new BigInteger[3]; x[0] =BigInteger.ONE; y[0] =BigInteger.ZERO; z[0] =p; x[1] =BigInteger.ZERO; y[1] =BigInteger.ONE; while(q.compareTo(BigInteger.ZERO) !=0){ BigInteger r =p.mod(q); p=q; q=r; } }while(q.compareTo(BigInteger.ONE) !=0); }

    • ベストアンサー
    • Java
  • 行列をべき乗させるプログラム

    2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・ 何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。 <プログラム> #include <stdio.h> #define N 2 int A[N][N]; int A_NEW[N][N]; int A_5[N][N]; /* 行列Aを5乗したもの */ int main() { int i,j,k,l; /* 2行2列の係数行列Aの成分を入力 */ printf("係数行列Aを%d行%d列で入力してください\n", N, N); for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("A[%d][%d]=", i+1, j+1); scanf("%d", &A[i][j]); } } for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_NEW[i][j] += A[i][k] * A[k][j]; } } } for(l=0; l<3; l++) { for(i=0; i<N; i++) /* A_5の計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_5[i][j] += A_NEW[i][k] * A[k][j]; } } } for(i=0; i<N; i++) { for(j=0; j<N; j++) { A_NEW[i][j] = A_5[i][j]; } } } printf("A_5=\n"); /* 出力 */ for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("%d ", A_5[i][j]); } printf("\n"); } } <入力例> A= 1 3 2 1 <期待する結果> A= 241 303 202 241 <このプログラムの結果> 406 498 332 406

  • JAVA初心者です。

    以下の文法でコンパイルエラーが出ます。 添削をお願いします。 import java.util.Random; public class Test{ public static void main(String[] args){ int n; for (n = 0; n < 200; n++){ int i; for (i = 0; i < 38; i++) { Random rnd = new Random(); int ran = rnd.nextInt(10); System.out.print(ran); System.out.print(" "); for (t = 0; t < 200; t++) } System.out.println(); } } }

    • ベストアンサー
    • Java
  • JAVAで配列を使って * を縦向きのグラフで表示したいです。

    JAVAの勉強をしています。 このプログラムは配列に乱数を生成して * を 横向きにするプログラムです。 練習問題で、以下のプログラムを書き換えて、* を縦向きのグラフで表示する問題なのですが、解く方法がわかりません。 どなたか答えもしくはヒントを下さい。 よろしくお願いします。 import java.util.Random; import java.util.Scanner; public class Test06_04 { public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数 : "); int n = stdIn.nextInt(); //要素数を読み込む int[] a = new int[n]; //配列を生成 for (int i = 0; i < n; i++) { a[i] = 1+ rand.nextInt(10); } for (int i = 0; i < n; i++) { System.out.print("a[" + i + "] : "); for (int j = 0; j < a[i]; j++) System.out.print('*'); System.out.println(); } } }

    • ベストアンサー
    • Java
  • Javaで数独の自動問題作成プログラム

    Javaで次のようなプログラムを作りました。 import java.util.Random; public class NumberPlace { public static void main(String[] args) { int i, j, k, l, check=0, count=0, tmp; int a[][] = new int [9][9]; Random rnd = new Random(); int ran; boolean A=false; while(A==false){ A=true; for ( i=0; i<9; i++ ) for ( j=0; j<9; j++ ) a[i][j] = 0; count = 0; for ( i=0; i<9; i++ ) { for ( j=0; j<9; j++ ) { ran = rnd.nextInt(9); tmp = ran + 1; check = 0; //System.out.println(tmp); for ( k=0; k<j; k++ ) if ( a[i][k] == tmp ) check = 1; for ( k=0; k<i; k++ ) if ( a[k][j] == tmp ) check = 1; for ( k=(i/3)*3; k<(i/3)*3+3; k++ ) for ( l=(j/3)*3; l<(j/3)*3+3; l++ ) if ( a[k][l] == tmp ) check = 1; if ( check == 0 ) a[i][j] = tmp; if ( check == 1 ) j--; if ( count > 50000 ){ A=false;break;} count++; } count = 0; }       } for ( i=0; i<9; i++) { for ( j=0; j<9; j++ ) { if ( a[i][j] < 10 ) { System.out.print(" "); } System.out.print(a[i][j]);       } System.out.print("\n"); } } } これを実行すると、次のようになります。 2 5 3 6 8 4 9 1 7 4 7 9 1 3 5 2 6 8 8 1 6 9 2 7 3 4 5 7 3 5 4 1 6 8 9 2 9 2 1 8 5 3 6 7 4 6 4 8 7 9 2 5 3 1 1 9 4 2 6 8 7 5 3 5 6 2 3 7 1 4 8 9 3 8 7 5 4 9 1 2 6 あとは、ここからランダムに50個数字を抜いて数独の問題にしたいのですが、 どうやったらランダムに数字を抜くことが出来るでしょうか? プログラムソースを提示していただくとありがたいのですが。宜しくお願いします。

  • javaのプログラム

    int型の配列の各要素に1~10の乱数を代入し、各要素の値を縦向きの*のグラフで表示するプログラムを作っているのですが、結果がランダムででるので、自分の書いたプログラムが正しいのかわかりません。ソースを載せますので合っているのか間違っているか教えて下さい。もし間違っているならどこが間違いなのか教えていただけると嬉しいです。よろしくお願いします。 ●ソース import java.util.Random; import java.util.Scanner; class Graph { public static void main(String[] args){ Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数:"); int n = stdIn.nextInt(); int a[] = new int[n]; for (int i = 0; i < n; i++) a[i] = 1 + rand.nextInt(10); for (int i = 1; i <= 10; i++){ for (int j = 0; j < n; j++) if (a[j] <= i) System.out.print("* "); else System.out.print(" "); System.out.println(); } } } ●実行例 要素数:12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

    • ベストアンサー
    • Java
  • java 格納した乱数それぞれにボタンを付け配置

    2回目の質問させて頂きます。 java勉強中の初級者です。 前回乱数を重複させずに5行×5列の25個並べる方法を教えて頂きました。 この25個にボタンをつけて最終的にタッチナンバーのゲームを作りたいです。 (ランダムに並んだ数字1~25まで順番に押してくゲーム) 5行×5列のボタンを配置まではできたのですが、 (1)そのボタンそれぞれに毎回違う乱数と紐付ける方法 (2)1~25まで順番に押してく処理 (3)そのボタンにその都度の数字に合わせた画像を付ける方法(押したら押された時用の画像に変わる) 上の3つが今悩んでいて、今回お聞きしたいところです。 (2)はifを使って 『25は24を押した後じゃないと押せない、24は23を押した後じゃないと押せない。』 みたいに一つずつ処理していくのかなぁと言うイメージです。 (合ってるのか効率いいのかもわかりませんが。) (3)はこの数字が来たらこの画像、あらかじめ指定しておくのかな?と言うイメージです。 (これも合ってるのかすらわかりません。) 前回教えて頂いたソースコードを載せておきます。 import java.util.ArrayList; import java.util.Collections; import java.util.Formatter; import java.util.List; class RandomArray { public static void main(String[] args) { int n = 5; int[][] a = new int[n][n]; List<Integer> shuffled = new ArrayList<Integer>(); // initialize for (int i = 0; i < n * n; i++) shuffled.add(i + 1); // shuffle Collections.shuffle(shuffled); System.out.println("shuffled: " + shuffled); // set int c = 0; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) a[i][j] = shuffled.get(c++); // output StringBuilder sb = new StringBuilder(); Formatter f = new Formatter(sb); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) f.format("%2d ", a[i][j]); f.format("\n"); } System.out.print(f); } } やりかた、考え方でもありがたいのですが、ソースコードも教えて頂けたら大変ありがたいです。 ぜひご教授頂きたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 0が表示されてしまいます

    次のようなプログラムを作成し、3つの配列の共通部分を表示したいのですが、うまく表示されず0が何個も表示されました。おかしい部分は/**/で囲みましたので、なぜ0が表示されるのかわかる方いましたら教えてください。お願いします。 import java.util.*; import java.lang.*; public class hairetu { public static void main(String[] args) { Random generator = new Random(); int hairetu[] = new int[90]; for(int i=0; i<90; i++) { hairetu[i] = (int)(Math.random() * 450); } int hairetu2[] = new int[90]; for(int i=0; i<90; i++) { hairetu2[i] = (int)(Math.random() * 450); } int hairetu3[] = new int[90]; int k = 0; for(int i=0; i<90; i++) { for(int j=0; j<90; j++) { if(hairetu[i] == hairetu2[j]) { hairetu3[k] = hairetu[i]; System.out.println(hairetu3[k]); k++; } } } System.out.println("\n---------------------------------\n"); int hairetu4[] = new int[90]; for(int i=0; i<90; i++) { hairetu[i] = (int)(Math.random() * 450); } /* int hairetu5[] = new int[90]; int m = 0; for(int i=0; i<90; i++) { for(int j=0; j<90; j++) { if(hairetu3[i] == hairetu4[j]) { hairetu5[m] = hairetu3[i]; System.out.println(hairetu5[m]); m++; } } }*/ } }

    • ベストアンサー
    • Java
  • javaの簡単な質問です

    学校の課題で、ループ文を使い、1-6までのカードを順に引いた場合、起こりうるパターンを全て表示するプログラムを作りなさいというのが出ました。 六枚全てを引くのだけではなく、一枚や二枚、五枚だけ引くというのもあるので、720+360+120+30+6通りがあります 下が作ったものなのですが、うまくいきません。 こういった場合、どのようなコードを書けばよいのでしょうか?for文で実現可能なのでしょうか?whileで同じ数字が出なくなるまで++するような形にするほうが良いのでしょうか? プログラミング初心者で、よくわかっていないです。すみません。どなたか助けてください。 *printsは表示処理を行う関数です public static void main(String[] args){ int[] numbers=new int[6];; for(int i=0;i<numbers.length;i++){//1 for(int j=0;j<numbers.length-1;j++){//2 int o=(i+j+1)%6; prints(numbers[i],numbers[o]); for(int k=0;k<numbers.length-2;k++){//3 int p=(o+k+1)%6; prints(numbers[i],numbers[o],numbers[p]); for(int l=0;l<numbers.length-3;l++){//4 int q=(p+l+1)%6; prints(numbers[i],numbers[o],numbers[p],numbers[q]); for(int m=0;m<numbers.length-4;m++){//5 int r=(q+m+1)%6; prints(numbers[i],numbers[o],numbers[p],numbers[q],numbers[r]); for(int n=0;n<numbers.length-5;n++){//6 int s=(r+n+1)%6; prints(numbers[i],numbers[o],numbers[p],numbers[q],numbers[r],numbers[s]); } } } } } } private void prints(int... num){ for(int i=0;i<num.length;i++){ System.out.print(num[i]); } } }

専門家に質問してみよう