My program freezes when I enter one million as a number for input. How do I fix this?
I tried separating second for loop as a second function, it didn't work.
import java.io.*;
public class Array {
public static void main(String[] args) {
String line = System.console().readLine("How many digits of Pi do you want? ");
int n = Integer.parseInt(line);
int columns = (int)(10.0*n/3.0);
int[][] makedigitsofpi = new int[columns][2];
makedigitsofpi[0][0] = 30;
makedigitsofpi[0][1] = 10;
for(int i = 1; i < columns; i++) {
makedigitsofpi[i][0] = i;
makedigitsofpi[i][1] = i*2+1;
}
int[] make2s = new int[columns];
for(int i = 0; i < columns; i++) {
make2s[i] = 2;
}
int[] timesby10 = new int[columns];
int[] thirdrow = new int[columns];
int[] fourrow = new int[columns];
int[] fifthrow = new int[columns];
for(int four_rows = 0; four_rows < n; four_rows++) {
for(int i = 0; i < columns; i++) {
timesby10[i] = make2s[i]*10;
}
for(int column = (columns - 1); column >= 0; column--) {
if(columns == (column + 1)) { //last column
thirdrow[column] = 0; // add last
}
else { // Third Row
int[] cell0 = makedigitsofpi[(column+1)];
int cellfour = fourrow[(column+1)];
int cellfive = fifthrow[(column+1)];
int d = cellfour - cellfive;
thirdrow[column] = (d*cell0[0])/cell0[1];
}
}
}
}
}
I need my program to be able to handle large numbers. This program is only the start of my project. The project is to create a program that generates Pi to a unlimited amount of digits.
How do I fix this?
Do the work in background thread.
Your code is working, the processor is used, doing math.
The "freeze" it is because it is not handling your inputs and is not finished his job.
To finish earlier the job, give smaller number of course.
To handle your imputs you need to do those for loops in a separated Thread
The code will not ececute faster, but you will not have the "freeze" feeling. If you would have a button to start in this case the button would be pressed and stay pressed, no other input.
In multi threaded context the button would release and you could switch from "start" state to "stop" state and if you press the button again, you set a Boolean variable value toggle: ex shouldCalculate = false; In your for loop if check that value, if is false, than exit from the thread, that's all.
Please take a look here to work with threads.
Related
So I help tutor an Algebra 2 class at my local high school, and the class is currently looking over matrices. Though not there, they will eventually get to multiplication of matrices. After taking Computer Science last year and learning Java, the teacher I help thought I should try to write a program to multiple matrices.
At the moment, I have up to defining the numbers for the first array that holds the information for the first matrix. However, I have a small issue. As represented by this picture:
the line asking for the index integers is being repeated after already recording the integers. I assume this is due to my layered for loops, but I can't be for certain. Usually new eyes see problems clearer. Any who could help me would be appreciated.
Code:
package matrixmultiplication;
import java.util.*;
public class MatrixMultiplication {
public static void main(String[] args) {
System.out.println("What is the size of the first matrix?");
int matrix1Rows = matrixRows();
int matrix1Columns = matrixColumns();
int[] matrix1 = new int[matrix1Rows * matrix1Columns];
doubleSpace();
System.out.println("What is the size of the second matrix?");
int matrix2Rows = matrixRows();
int matrix2Columns = matrixColumns();
int[] matrix2 = new int[matrix2Rows * matrix2Columns];
doubleSpace();
if (matrix1Columns != matrix2Rows) {
System.out.println("These cannot be multiplied!");
System.exit(0);
} else {
matrix1Numbers(matrix1Rows, matrix1Columns);
}
}
public static int matrixRows() {
System.out.print("Rows:");
Scanner rowSc = new Scanner(System.in);
int rows = rowSc.nextInt();
return rows;
}
public static int matrixColumns() {
System.out.print("Columns:");
Scanner colSc = new Scanner(System.in);
int cols = colSc.nextInt();
return cols;
}
public static int[] matrix1Numbers(int rows, int cols) {
int[] numb = new int[rows * cols];
for (int j = 0; j <= numb.length; j += rows) {
for (int i = 1; i <= cols; i++) {
for (int k = 1; k <= rows; k++) {
System.out.println("What is the value for index ("
+ k + "," + i + ")?");
Scanner inp = new Scanner(System.in);
if (j + k <= numb.length) {
numb[j + k - 1] = inp.nextInt();
}
}
}
}
for (int i = 0; i < numb.length; i++) {
System.out.println(numb[i]);
}
return numb;
}
public static void doubleSpace() {
System.out.println();
System.out.println();
}
}
I use NetBeans 8.2 and the latest working version of Java for NetBeans.
I'm not familiar with the matrixmultiplication package, so I may be rambling here.
for (int j = 0; j <= numb.length; j += rows){
I'm not entirely sure what the outer for loop your have is for, but this most outer for loop causes you to ask for the values of the indices cols times more than you want.
I feel that you originally wanted to use this outer for loop to iterate through each row, and wasn't planning on having the second for loop iterating through cols perhaps?
Also, Kevin Anderson mentions this above. You might avoid this problem altogether if you return a double int array as opposed to storing all values in the matrix in a single dimension. I personally feel it would make more sense.
Just nitpicking, but I wouldn't make a new scanner every time you want to use one in a different method. You could just make a field at the top of your class, instantiate it once in your main method, and then pass it in as a parameter to all methods using the scanner.
Hello I have with repetitions in drawing randoms. I tried to do this on tables but every time I have problem with comparing generated random number with numbers in table. Be carefull there because this code now is endless loop what is throwing ArrayIndexOutOfBoundsException. Do you have any ideas? To show you what I want to get is similar to polish TV show Lotto where they are drawing 6 random numbers written on balls without repetition.
I have seen topic where it was done on lists but it's possible on tables like that?
public static void main(String[] args) {
Lotto lot = new Lotto();
int[] table = new int[6];
Random random = new Random();
for(int i = 0; i < 6; i++) {
int numbers = random.nextInt(48) + 1;
for(int k = 0; k < 6; k++) {
if (table[k] != numbers) {
try {
table[i] = numbers;
} catch (ArrayIndexOutOfBoundsException e){
System.out.println(e);
}
} else {
i--;
}
}
}
Arrays.sort(table);
for (int m = 0; m < 6; m++) {
System.out.println(table[m]);
}
}
I suggest following approach:
// Get list of all number
List<Integer> all = new ArrayList<>();
for (int i = 1; i <= 48; i++) {
all.add(i);
}
//Shuffle it
Collections.shuffle(all);
//Take first 6
List<Integer> result = all.subList(0, 6);
There are two popular techniques, choose only items that are available or choose any possible and check if it has been chose. This answer chooses from possible numbers, check if the number has been chosen already. If it has not been chosen, it is added to the array. If it has been chosen, then the process is repeated.
for(int i = 0; i < 6; i++) {
boolean selected = false;
while(!selected){
selected = true;
int numbers = random.nextInt(48) + 1;
for(int k = 0; k <= i; k++) {
if (table[k] == numbers) {
selected = false;
break;
}
}
if(selected){
table[i] = numbers;
}
}
}
The usage for the techniques depends on how many samples you need compared to the population you are choosing from.
If you need to choose any six numbers between 1 and 1000000, then this technique will work better because the odds of repeating are small, but shuffling a million element list takes more calculations.
The other technique is more appropriate say if your possible numbers are small, for example if you had to pick 6 numbers between 1 and 7, then you would pick a lot of duplicates. So shuffling a list will be better.
In your range, 6 out of 49, the choose and repeat will be faster because most often you'll find a new number.
I would do it like this:
TreeSet<Integer> t = new TreeSet<>();
while (t.size()<6) {
t.add((int)(Math.random()*48+1));
}
TreeSet guarantees that only unique items will be put into target collection.
Try and model the real world and get your application to do what happens in real life. You have 48 balls, numbered 1 to 48. Let's make a collection of them:
List<Integer> ballsInTheMachine = new ArrayList<>(48);
for (int i = 1; i <= 48; i++)
ballsInTheMachine.add(i);
Using Java 8 Streams, you can also create the same list in a way that is supposedly more succinct:
List<Integer> ballsInTheMachine = IntStream.rangeClosed(1, 48)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
Next, you pick 6 balls at random out of the 48:
Random rng = new Random();
List<Integer> ballsPicked = new ArrayList<>(6);
for (int i = 1; i <= 6; i++) {
int index = rng.nextInt(ballsInTheMachine.size());
Integer pickedBall = ballsInTheMachine.remove(index);
ballsPicked.add(pickedBall);
}
And now you have your 6 randomly chosen balls in the list ballsPicked.
im new to Java and currently trying to learn how to best store numbers in arrays.
the specific problem im working on is trying to find a way to better implement the below methods by storing the computations in an array.
the code looks like this:
public static long myF(int N) {
long[] computedValues;
computedValues = new long[N+1];
computedValues[0] = 0;
computedValues[1] = 1;
for (int i = 2; i < computedValues.length ;i++){
computedValues[i] = computedValues[(i-1)]+computedValues[(i-2)];
System.out.println("array["+(i)+"] = "+computedValues[i]);
}
return computedValues[N-1];
}
public static void runMyF() {
for (int N = 0; N < 100; N++)
StdOut.println(N + " " + myF(N));
}
public static void main(String[] args) {
runMyF ();
}
Main in this code is supposed to call runMyF(), and then runMyF() is supposed to call myF().
My problem is that I cant get computedValues[0] = 0; computedValues[1] = 1; included in the output and the second problem is that ie get this error message when runMyF() calls myF():
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at algs11.MyFib.myF(MyFib.java:21)
at algs11.MyFib.runMyF(MyFib.java:30)
at algs11.MyFib.main(MyFib.java:37)
Any help please?
#Dukeling, your solution was a bit over my pay grade (sorry) - I think there are some bugs in my code and I need help to find them. Thank you.
You're incrementing the wrong variable.
for (int i = 2; i < computedValues.length; N++){
should be
for (int i = 2; i < computedValues.length; i++){
Note the N++ changed to i++.
Remember to initialize computedValues[0] and computedValues[1]. This should appear before the loop:
computedValues[0] = 0;
if (N > 0) // needed because when N = 0, the below will be out of bounds
computedValues[1] = 1;
It should probably be computedValues = new long[N+1];, otherwise the array is too small.
You need to return the correct value - change return computedValues[N]; to return 0;.
Additional efficiency:
I guess the point is to compare the efficiency of the two method. If not, you should declare computedValues outside of the function as an ArrayList and, in the function, add to it as required. This will cause you to only compute each value once for the entire run of the program.
static ArrayList<Long> computedValues = new ArrayList<Long>(Arrays.asList(0l,1l));
public static long myF(int N) {
for (int i = computedValues.size(); i <= N; i++){
computedValues.add(computedValues.get(i-1) + computedValues.get(i-2));
System.out.println("array[" + i + "] = " + computedValues.get(i));
}
return computedValues.get(N);
}
You forgot the initial numbers in the array:
long[] computedValues;
computedValues = new long[N];
computedValues[0] = 0;
computedValues[1] = 1;
You are initializing computedValues to a new long
computedValues = new long[N];
I think you wanted to do this :
computedValues[i] = F(N);
Also, in your loop you are not incementing i which makes it as infinite loop. Change it to
for (int i = 2; i < computedValues.length ;i++)
You can use a method that returns an arraylist:
ArrayList<Long>series=new ArrayList<Long>();
for(int i=0;i<100;i++)
{
if(i==0)series.add(new Long(0));
if(i==1)series.add(new Long(1));
if(i>1)series.add(new Long(series.get(i-1).longValue()+series.get(i-2).longValue()));
}
the list will have 0,1,1,2,3,5,8,....
I was looking through some old contest questions, and I found this one, it looked fun, http://dwite.ca/old/Problem5Jan2006.pdf , I tried using the floyd warshall algorithm to get the shortest path from any node to any other node, can you guys see what I did wrong? it does not give the desired output set out on the contest question page
import java.io.*;
import java.util.*;
public class DistanceBetween {
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("DATA5.txt"));
int n = Integer.parseInt(s.nextLine());
int[][] dist = new int[60][60];
for(int y=0;y<60;++y)for(int x=0;x<60;++x)dist[y][x]=10000000;
Map<Character, Integer> map = new TreeMap<Character, Integer>();
for (int i = 0; i < n; ++i) {
String text[] = s.nextLine().split(" ");
int c = 0;
if (!map.containsKey(text[0].charAt(0))) {
map.put(text[0].charAt(0), c);
c++;
}
if (!map.containsKey(text[0].charAt(1))) {
map.put(text[0].charAt(1), c);
c++;
}
dist[map.get(text[0].charAt(0))][map.get(text[0].charAt(1))] = Integer.parseInt(text[1]);
}
for (int k = 0; k < map.size(); ++k) {
for (int i = 0; i < map.size(); ++i) {
for (int j = 0; j < map.size(); ++j) {
dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
for (int i = 0; i < 5; ++i) {
String text = s.nextLine();
System.out.println(dist[map.get(text.charAt(0))][map.get(text.charAt(1))]);
}
}}
There are several problems in your code:
Overwritten mapping
Your int c is local variable of the for cycle which means the highest used mapping index doesn't survive to the next iteration, so the reading in next iteration overrides the previous one. So the distance matrix is not properly filled after data loading.
Solution: move the int c = 0; outside from the for loop.
Unidirectional roads
The roads are bidirectional in the instructions, but you register them only as unidirectional. As the consequence of that are higher on non-existent connections between towns.
Solution: add dist[map.get(text[0].charAt(1))][map.get(text[0].charAt(0))] = Integer.parseInt(text[1]); right after the similar one.
Besides these hard issues I have also couple hints for you. You do not have follow them but as if you want to improve your programming skills then you should think about them.
Messy code
Your code is hard to read, there are multiple restated information such as indicies, the solving process is in the single method etc. Such code is not only hard to read but also extremely hard to debug and fix. For your own good I recommend you to write it cleaner.
Algorithm efficiency
Floyd-Warshall's algorithm has a O(n^3) complexity. The size of problem (amount of towns) is A-M = 13. In this complexity it makes 13^3 = 2197 iterations. I know, it might not seem to be a lot, but consider the amount of tasks to solve in a given time limit.
I would recommend you to use Dijkstra's algorithm which has complexity O(|E| + |V|log|V|). In this task the worst case with some simplification is |E| = (|V|^2)/2, |V|=13. It means, that the final number of iterations is 5 (|V|^2 / 2 + |V|log|V|) = 5 (13^2 / 2 + 13 * log13) ~ 5 * 132 = 660. If I am not wrong and made any mistake, this is significantly less, especially when we consider the total amount of tasks.
Input reading
I might be wrong but I attended multiple programming contests and competitions and it never forced attendees to work with files. An input was always redirected from files to a standard input. I guess, that the main reason for this is a security, but the simplification is probably also highly beneficial.
Well that question I got, I am starting to do SPOJ now, and I gotta admit it is pretty difficult later on, but I came across the same kind of question http://www.spoj.com/problems/SHPATH/ , I also used Floyd Warshall
import java.util.*;
public class Floydwarshall {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String q = s.nextLine();
for(int t=0;t<Integer.parseInt(q);++t){
int n = Integer.parseInt(s.nextLine());
int[][] cost = new int[n][n];
for (int y = 0; y < n; ++y) {
for (int x = 0; x < n; ++x) {
cost[x][y] = 10000;
}
}
Map<String, Integer> map = new TreeMap<String, Integer>();
int c = 0;
for (int i = 0; i < n; ++i) {
String a = s.nextLine();
if (!map.containsKey(a)) {
map.put(a, c);
c++;
}
int f = Integer.parseInt(s.nextLine());
for (int j = 0; j < f; ++j) {
String text[] = s.nextLine().split(" ");
cost[map.get(a)][Integer.parseInt(text[0]) - 1] =
cost[Integer.parseInt(text[0]) - 1][map.get(a)] = Integer.parseInt(text[1]);
}
}
for (int k = 0; k < map.size(); ++k) {
for (int i = 0; i < map.size(); ++i) {
for (int j = 0; j < map.size(); ++j) {
cost[i][j] = Math.min(cost[i][j], cost[i][k] + cost[k][j]);
}
}
}
int num = Integer.parseInt(s.nextLine());
for (int i = 0; i < num; ++i) {
String text[] = s.nextLine().split(" ");
System.out.println(cost[map.get(text[0])][map.get(text[1])]);
}
}
}}
now it runs alright for the sample input, but when I hand it in, it gives me this
NZEC (non-zero exit code) - this message means that the program exited returning a value different from 0 to the shell. For languages such as C, this probably means you forgot to add "return 0" at the end of the program. For interpreted languages (including JAVA) NZEC will usually mean that your program either crashed or raised an uncaught exception.
Problem is I cannot kind where it crashes or raises an uncaught exception since it
works with the sample input
I'm trying to generate a Sudoku board via a 2D array: board[5][5]. The Sudoku board should only contain unique vowels. However, I have only made unique vowels appear in a row. For the columns, they still seem to have duplicates. How am I suppose to generate a column with no duplicates using the code I have so far?
Here's the code I have for generating unique letters in a row:
String [] vowels = {"A","E","I","O","U"};
String [][] board = new String [vowels.length][5];
public Actions(){
int rows = 5;
for(int row = 0;row<rows;row++){
ArrayList<String> tempVowels = new ArrayList<String>(Arrays.asList(vowels));
int numVowPerLine = (int)Math.floor(Math.random()*4);
for(int j = 0;j<numVowPerLine;j++){
do{
int pos = (int)Math.floor(Math.random()*5);
if(board[row][pos] == null){
int temp = (int)Math.floor(Math.random()*tempVowels.size());
board[row][pos] = tempVowels.get(temp);
tempVowels.remove(temp);
break;
}
}while(true);
}
}
Credits to: L7ColWinters
This is related to a rather well known problem, called the Rooks Problem.
Might I suggest a simpler loop?
EDIT: After reading comments, I see that the problem needs to be applied to each vowel. In my opinion, this is more readable:
java.util.Random random = new Random();
boolean[] r_occupied;
boolean[] c_occupied;
for (i = 0; i < vowels.length; i++)
{
// Clear the 'occupied' information
r_occupied = new boolean[5];
c_occupied = new boolean[5];
// we will put vowel[i] 'count' times into the 'board'
count = random.nextInt(5);
for (j = 0; j < count; j++)
{
// generate a random row
row = random.nextInt(5);
// if it is already occupied, select the next one
while (r_occupied[row])
row = (row + 1) % 5;
// generate a random column
col = random.nextInt(5);
// if it is already occupied, select the next one
while (c_occupied[col])
col = (col + 1) % 5;
/* put the vowel at board[row][col] */
r_occupied[row] = true;
c_occupied[col] = true;
board[row][col] = vowel[i];
}
}
Note: It will overwrite some vowels, but this should be OK.
If the content of first column / first row is A and you are on the first column / second row, you could use a truncated array, i.e. String [] availableVowels = {"E","I","O","U"};, to select from. If you pick O, then when you are on first column / thrid row, you would choose from String [] availableVowels = {"E","I","U"};. etc.
Before adding an additional vowel character in a row check if it
already contains this vowel and with continue you can pass to the
other vowel
You can also do the same thing for the columns with just switching
it
before this:
board[row][pos] = tempVowels.get(temp);
Write this:
boolean b = false;
for(int j = 0;j<columnLength; j++){
if(board[row][j] == tempVowels.get(temp))
b= true;
if(b == true)
{
b = false;
continue;
}
board[row][pos] = tempVowels.get(temp);
}