Loop not properly modifying array elements - java

The loop causing issues is the second for loop.
import java.util.Scanner;
public class StudentScores {
public static void main (String [] args) {
Scanner scnr = new Scanner(System.in);
final int NUM_POINTS = 4;
int[] dataPoints = new int[NUM_POINTS];
int controlValue;
int i;
controlValue = scnr.nextInt();
for (i = 0; i < dataPoints.length; ++i) {
dataPoints[i] = scnr.nextInt();
}
for (i = 0; dataPoints[i] < controlValue; ++i) {
dataPoints[i] = dataPoints[i] * 2;
}
for (i = 0; i < dataPoints.length; ++i) {
System.out.print(dataPoints[i] + " ");
}
System.out.println();
}
}
Currently when i run the test, this is what pops up.
Testing with inputs: 10 2 12 9 20
Output differs.
Your output
4 12 9 20
Expected output
4 12 18 20
the first number in the list of inputs is the maximum number it should multiply by 2. Since 20 is > 10, it is not multiplied. However 9 should be multiplying to 18, but it is not. If anyone could give some insight into anything i might be doing wrong when forming this loop, I would greatly appreciate it. Thank you!

Your second for loop is exiting because of the condition and the order of your input data, and will stop when a control value is reached. For example, if you instead had an input of 10 1 2 3 4, you would get the results you expect (ie. 2 4 6 8), but your for loop is exiting when the condition dataPoints[i] < controlValue is reached (in your case at 12).
Instead you should loop through the entire dataPoints array, as you do in your 3rd loop, and check the controlValue before doubling the values.
import java.util.Scanner;
public class StudentScores {
public static void main (String [] args) {
Scanner scnr = new Scanner(System.in);
final int NUM_POINTS = 4;
int[] dataPoints = new int[NUM_POINTS];
int controlValue;
int i;
controlValue = scnr.nextInt();
for (i = 0; i < dataPoints.length; ++i) {
dataPoints[i] = scnr.nextInt();
}
for (i = 0; i < dataPoints.length; ++i) {
if (dataPoints[i] < controlValue) {
dataPoints[i] = dataPoints[i] * 2;
}
}
// This could be combined into the loop above...
for (i = 0; i < dataPoints.length; ++i) {
System.out.print(dataPoints[i] + " ");
}
System.out.println();
}
}
You could also do all of this in a single loop if you wanted to, for example:
for (i = 0; i < dataPoints.length; ++i) {
dataPoints[i] = scnr.nextInt();
if (dataPoints[i] < controlValue) {
dataPoints[i] = dataPoints[i] * 2;
}
System.out.print(dataPoints[i] + " ");
}

Related

Why does my code output an extra "0" after finding the most frequent integer in an array?

An example of integers entered would be: 5 9 2 2 1 4 5 5 -1 and my code's output is "5 0". In this example array, I only need it to display "5 ". Try it yourself with any combination of integer input, ending your input with a -1 and you'll get the most frequent integer with a zero. Any ideas why my code does this?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int[] b = new int[21];
for (int i = 0; i < b.length; ++i) { //integer input from user
b[i] = scnr.nextInt();
if (b[i] == -1) { //array input stops when input is -1
break;
}
}
int maxcount = 0;
int element_having_max_freq;
for (int i = 0; i < b.length; ++i) {
int count = 0;
for (int j = 0; j < b.length; ++j) {
if (b[i] == b[j]) {
count = count + 1;
}
}
if (count > maxcount) {
maxcount = count;
element_having_max_freq = b[i];
System.out.println(element_having_max_freq+ " ");
}
}
}
}
Your array is of size 21 and initialized as all zeros. All numbers you don't overwrite with the user input will remain zeros, which means that in the case of your test input 5 9 2 2 1 4 5 5 -1, you get another 12 zeros.
Try placing a breakpoint after the part of the code that parses the user input and have a look at b.

How do I change the position of my triangle?

am trying to do this triangle using 2 arguments.
Can someone help me out and see what is wrong with my code?
I can't seems to flip it to the same as this image.
Thank you!
int width = Integer.parseInt(args[0]);
int height = Integer.parseInt(args[1]);
for (int i = 0; i < height; i++) {
int starsThisLine = (int) Math.round(width * ((i + 1) / (double) height));
int dotsBeforeStars = Math.round((width - starsThisLine));
for (int j = 0; j < width; j++) {
if (j > dotsBeforeStars) {
System.out.print(".");
} else if (j < (dotsBeforeStars + starsThisLine)) {
System.out.print("*");
} else {
System.out.println(1);
Here is one way to do it. Just create a repeat method to return the String with the proper number of characters.
int height = 10;
for (int i = 0; i < height; i++) {
System.out.println(repeat("*", height-i)+repeat(".",i));
}
public static String repeat(String a, int count) {
StringBuilder sb = new StringBuilder();
while(count-- > 0) {
sb.append(a);
}
return sb.toString();
}
Both will print
**********
*********.
********..
*******...
******....
*****.....
****......
***.......
**........
*.........
One observation. Notice the first line has all stars. But that last line does not have all dots. The same was true in your patterns too.
If you want the start and finish to look like this:
**********
..........
The loop should be as follows:
for (int i = 0; i <= height; i++) {
If you want the start and finish to look like this:
*********.
*.........
The loop should be as follows:
for (int i = 1; i < height; i++) {
Assuming that the height and width will always be the same, here is an example implementation that uses a scanner (you can change this if you want to):
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int dimensions = scan.nextInt();
for(int i = 0; i < dimensions; i++){
for(int dots = 0; dots < i; dots++){
System.out.print(". ");
}
for(int stars = dimensions; stars > i; stars--){
System.out.print("* ");
}
System.out.println();
}
}
}
In this example, our outer for loop with the dimensions represents the code for each row of the triangle, in this case, if we inputted 5, 5 rows.
Then, we start with printing dots since they are on the left side. Since the number of dots goes 0 -> 1 -> 2 -> 3 -> 4, this is equivalent to what "i", or our outer loop counter is.
With the stars, the number of stars goes 5 -> 4 -> 3 -> 2 -> 1, so if we just count backwards from the number of rows to our counter variable, we can get this number.

Transpose java error

I was trying to do a 2D array program to demonstrate a TRANSPOSE but I am getting error .. here is my code.
import java.util.Scanner;
/* To demonstrate TRANSPOSE USING 2-D array */
public class Array_2ddd {
public static void main(String args[]) {
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[9][9];
int myArray2[][] = new int[9][9];
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.println("Enter array from 1 to 9");
myArray1[i][j] = s1.nextInt();
System.out.print("your array is" + myArray2[i][j]);
}
}
// Transposing now...
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.print("Your array is as follow" + myArray2[i][j]);
}
}
}
}
EDIT: My error during runtime (Solved)
EDIT 2: Solved
EDIT 3: The loop is in infinity ..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity..
There are several errors in your code, also it is recommend that the dimensions of the array is to be declared as a final int, so your code works for all matrix sizes and that debugging is easier. In your original code, the errors are:
At the input step, you are printing one element of myArray[2] before you perform the transpose. That means, you are getting your array is0.
In the section commented "After transposing", you are outputting your array wrong. Namely, for each entry, you call System.out.print("Your array is as follow" + myArray2[i][j]);, and that you forgot to add a new line after each row (when inner loop is finished).
"..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity.." There are 81 entries for the 9-by-9 case and you did not output which i,j index to be applied. You probably mistaken an infinite loop with a long but terminating loop.
Your transpose step is good.
Here is a refined version of your code which allows you to input array (in reading order, or more technically, row-major order), create a transposed array. You can copy and compare your current code with this code directly to test it.
public static void main(String args[]) {
final int m = 9; // Rows
final int n = 9; // Columns
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[m][n]; // Original array, m rows n cols
int myArray2[][] = new int[n][m]; // Transposed array, n rows m cols
// Input
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
// Should be only prompt.
// Improved to show which entry will be affected.
System.out.printf("[%d][%d]" + "Enter array from 1 to 9\n", i, j);
myArray1[i][j] = s1.nextInt();
}
}
// Transposing now (watch for the ordering of m, n in loops)...
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing, output
System.out.print("Your array is:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
System.out.print(myArray1[i][j] + " ");
}
System.out.println(); // New line after row is finished
}
System.out.print("Your transposed array is:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
System.out.print(myArray2[i][j] + " ");
}
System.out.println();
}
s1.close();
}
For an array with three rows (m = 3) and four columns (n = 4), I inputted the numbers from 0 to 9, and then 0, 1, 2. As expected, the output should be:
Your array is:
0 1 2 3
4 5 6 7
8 9 0 1
Your transposed array is:
0 4 8
1 5 9
2 6 0
3 7 1
You define your matrix as 9x9
int myArray1[][] = new int[9][9];
But actually you want to insert 10x10 items:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
So either:
Redefine your arrays to store 10x10 items
int myArray1[][] = new int[10][10];
Only read and store 9x9 items in your defined array
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++)
You haven't close your first outer for loop i.e in line 17 and change your array size to 10,as you wanted take 10 input (for 0 to 9 = 10 values).

Printing spaces to align numbers according to my pyramid pattern

It sounds a lot easier than it looks. Basically I have my code finished this is my output where the leading number is whatever integer the program receives as input. In this case n = 5:
1
21
321
4321
54321
but this is what it is suppose to look like:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
How should I go about adding spaces in between my numbers while maintaining this pattern? I've tried editing here and there but it keeps coming out like this:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
My code:
import java.util.Scanner;
public class DisplayPattern {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
displayPattern(n);
}
public static void displayPattern(int n) {
final int MAX_ROWS = n;
for (int row = 1; row <= MAX_ROWS; row++) {
for (int space = (n - 1); space >= row; space--) {
System.out.print(" ");
}
for (int number = row; number >= 1; number--) {
System.out.print(number + " "); /*<--- Here is the edit.*/
}
System.out.println();
}
}
Edit:
#weston asked me to display what my code looks like with the second attempt. It wasn't a large change really. All i did was add a space after the print statement of the number. I'll edit the code above to reflect this. Since it seems that might be closer to my result I'll start from there and continue racking my brain about it.
I managed to get the program working, however this only caters to single digit number (i.e. up to 9).
import java.util.Scanner;
public class Play
{
public static class DisplayPattern
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
displayPattern(n);
}
public static void displayPattern(int n)
{
final int MAX_ROWS = n;
final int MAX_COLUMNS = n + (n-1);
String output = "";
for (int row = 1; row <= MAX_ROWS; row++)
{
// Reset string for next row printing
output = "";
for (int space = MAX_COLUMNS; space > (row+1); space--) {
output = output + " ";
}
for (int number = row; number >= 1; number--) {
output = output + " " + number;
}
// Prints up to n (ignore trailing spaces)
output = output.substring(output.length() - MAX_COLUMNS);
System.out.println(output);
}
}
}
}
Works for all n.
In ith row print (n-1 - i) * length(n) spaces, then print i+1 numbers, so it ends with 1 separated with length(n) spaces.
public static void printPiramide(int n) {
int N = String.valueOf(n).length();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1 - i; j++) {
for (int k = 0; k < N; k++)
System.out.print(" ");
}
for (int j = i+1; j > 0; j--) {
int M = String.valueOf(j).length();
for (int k = 0; k < (N - M)/2; k++) {
System.out.print(" ");
}
System.out.print(j);
for (int k = (N - M)/2; k < N +1; k++) {
System.out.print(" ");
}
}
System.out.println();
}
}
public class DisplayPattern{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
List<Integer> indentList = new ArrayList<Integer>();
int maxLength= totalSpace(n) + (n-1);
for(int i = 1; i <= n; i++ ){
int eachDigitSize = totalSpace(i);
int indent = maxLength - (eachDigitSize+i-1);
indentList.add(indent);
}
for(int row = 1; row<=n; row++){
int indentation = indentList.get(row-1);
for(int space=indentation; space>=0; space--){
System.out.print(" ");
}
for(int number = row; number > 0; number--){
System.out.print(number + " ");
}
System.out.println();
}
}
private static int totalSpace(int n) {
int MAX_ROWS = n;
int count = 0;
for(int i = MAX_ROWS; i >= 1; i--){
int currNum = i;
int digit;
while(currNum > 0){
digit=currNum % 10;
if(digit>=0){
count++;
currNum = currNum/10;
}
}
}
return count;
}
}
It works properly for any number of rows(n).
java-8 solution to the problem:
IntStream.rangeClosed(1, MAX)
.forEach(i -> IntStream.range(0, MAX)
.map(j -> MAX - j)
.mapToObj(k -> k == 1 ? k + "\n" : k <= i ? k + " " : " ")
.forEach(System.out::print)
);
Output for MAX = 5:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
For the bottom row, you have the right number of spaces. But for the next row from the bottom, you're missing one space on the left (the 4 is out of line by 1 space). In the next row up, you're missing two spaces on the left (the 3 is out of line by 2 spaces)... and so on.
You're adding a number of spaces to the beginning of each line, but you're only taking into account the number of digits you're printing. However, you also need to take into account the number of spaces you're printing in the previous lines.
Once you get that part working, you might also consider what happens when you start to reach double-digit numbers and how that impacts the number of spaces. What you really want to do is pad the strings on the left so that they are all the same length as the longest line. You might check out the String.format() method to do this.

How to display a result from a class?

I've been working on a program which multiplies matrices using threads. I written the program in a non-threaded fashion and it was working like a charm. However when I was writing it w/ threading function, it appears that I am not getting a result from the Threading class (I will rename it later on). Also if I were to use 1 thread, I would get all 3 matrices followed by a empty results for the matC matrix. Anything more than 1 would get me a Array index out of bounds.
Still pretty inept using classes and whatnot, and i apologize in advance of being somewhat wordy. But any help would be appreciated.
Main class:
package matrixthread;
import java.io.*;
import java.util.*;
public class MatrixThread extends Thread{
public static void matrixPrint(int[][] A) {
int i, j;
for (i = 0; i < A.length; i++) {
for (j = 0; j < A.length; j++) {
System.out.print(A[i][j] + " ");
}
System.out.println("");
}
}
public static void matrixFill(int[][] A) {
int i, j;
Random r = new Random();
for (i = 0; i < A.length; i++) {
for (j = 0; j < A.length; j++) {
A[i][j] = r.nextInt(10);
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int threadCounter = 0;
System.out.print("Enter number of rows: ");
int M = in.nextInt();
System.out.print("Enter number of threads: ");
int N = in.nextInt();
Thread[] thrd = new Thread[N];
if (M < N)
{
System.out.println("Error! Numbers of rows are greater than number of threads!");
System.exit(0);
}
if(M % N != 0)
{
System.out.println("Error! Number of rows and threads aren't equal");
System.exit(0);
}
int[][] matA = new int[M][M];
int[][] matB = new int[M][M];
int[][] matC = new int[M][M];
try
{
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++)
{
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
thrd[threadCounter].join();
threadCounter++;
}
}
catch(InterruptedException ie){}
long startTime = (int)System.currentTimeMillis();
matrixFill(matA);
matrixFill(matB);
//mulMatrix(matA, matB, matC);
long stopTime = (int)System.currentTimeMillis();
int execTimeMin = (int) ((((stopTime - startTime)/1000)/60)%60);
int execTimeSec = ((int) ((stopTime - startTime)/1000)%60);
System.out.println("\n" + "Matrix 1: ");
matrixPrint(matA);
System.out.println("\n" + "Matrix 2: ");
matrixPrint(matB);
System.out.println("\n" + "Results: ");
matrixPrint(matC);
System.out.println("\n" + "Finish: " + execTimeMin + "m " + execTimeSec + "s");
}
}
And here's my threading class:
package matrixthread;
public class Threading implements Runnable {
//private int N;
private int[][] matA;
private int[][] matB;
private int[][] matC;
public Threading(int matA[][], int matB[][], int matC[][]) {
this.matA = matA;
this.matB = matB;
this.matC = matC;
}
#Override
public void run() {
int i, j, k;
for (i = 0; i < matA.length; i++) {
for (j = 0; j < matA.length; j++) {
for (k = 0; k < matA.length; k++) {
matC[i][j] += matA[i][k] * matB[k][j];
}
}
}
}
}
Here are my results using 2 rows and 1 thread
Matrix 1:
7 8
4 5
Matrix 2:
3 0
1 5
Results:
0 0
0 0
You have a large number of problems here. First and foremost is this loop:
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++) {
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
thrd[threadCounter].join();
threadCounter++;
}
You run this loop before calling matrixFill. matA and matB are both equal to the Zero matrix at this point.
You then, for each Thread, call join() which waits for completion. So all you do is 0 * 0 = 0 N2 times.
Creating threads in a loop and calling join() on them as they are created waits for each thread to finish. This means that you never have two tasks running in parallel. This isn't threading, this is doing something with a single thread in a very complicated manner.
You then fill matA and matB and print out all three. Unsurprisingly, matC is still equal to the Zero matrix.
Your next issue is with your threading:
public void run() {
int i, j, k;
for (i = 0; i < matA.length; i++) {
for (j = 0; j < matA.length; j++) {
for (k = 0; k < matA.length; k++) {
matC[i][j] += matA[i][k] * matB[k][j];
}
}
}
}
Each thread runs this code. This code multiplies two matrices. Running this code N2 times as you do just makes a single matrix multiplication N2 times slower.
If you fixed your threading (see above) so that all your threads ran concurrently then all you would have is the biggest race hazard since in creation of Java. I highly doubt you would ever get the correct result.
TL;DR The reason matC is zero is because, when multiplication happens, maA == matB == 0.
First of all I don't know why you run the thread with the same data N^2 times. Possible you wanted to fill matA and matB every time with different data?
If you want to compute many data parallel you should do it in this way:
//First start all Threads
for (int x = 0; x < N; x ++)
for (int y = 0; y < N; y++)
{
thrd[threadCounter] = new Thread(new Threading(matA, matB, matC));
thrd[threadCounter].start();
threadCounter++;
}
//then wait for all
for(int i = 0; i < threadCounter; i++){
thrd[threadCounter].join();
}
Otherwise there is nothing parallel because you wait until the first Thread is ready and then do the next.
That you get a result of 0 0 0 0 is because matA and matB are 0 0 0 0 at the moment you start the threads.

Categories