I'm trying to made a method that receives a matrix and prints its lines. For example:
line nb 1 : 3 2 5 6
line nb 2 : 7 9 0 1 4 3
line nb 3 : 3 5 3
I'd like to know why I cannot print the lines of the given matrix using this code. And also, why I cannot increment the variable k, that shows me the number of the line.
When I run this code it does not increment k. It always shows me the number 1 for the line
How can I fix my code?
public static void PrintLine(int[][] matrix){
for (i = 0; i < matrix.length; ++i){ // Loop all long the lines of the matrix
int k = 1; // Number of the line
System.out.print("Line nb " + k + matrix[i]);
k = k+1; // Increment the number of the line by 1
}
}
It's not so much that k does not get incremented; rather, you increment k only to discard it immediately, because the scope of the variable k is restricted to a single iteration (i.e., within the curly braces). The following should work:
for (int i = 0, k = 0; i < matrix.length; ++i, ++k) {
/* work in terms of i and k */
}
which, in your case, simplifies to using i and k for the same purpose:
for (int i = 0; i < matrix.length; ++i) {
System.out.print("Line nb " + i + matrix[i]");
}
Your k variable is initialized inside for loop. It means on each iteration it will be new variable. With initial 1 value.
Move it's itialization out of the loop:
int k = 1; // Number of the line
for (i = 0; i < matrix.length; ++i){ // Loop all long the lines of the matrix
As other have pointed out the scope of your k is incorrect, you can just use the value of i, also when you print your array you are getting the object reference details, you can use Arrays.toString() to print the values from an Array.
for (int i = 0; i < matrix.length; ++i) {
System.out.print("Line nb " + i +": "+ Arrays.toString(matrix[i]));
}
Related
I am attempting to create a fillArray method that fills and array with 20 random values and sums every third value. I am getting an ArrayExceptionOutOfBounds at line 21 which is when the method is called. Through the debug I have watched the array fill with proper values and the sum properly calculated. I am wondering what the error is.
public static void fillArray(){
//adding up A[0], A[3], A[6}, ...
double[] A = new double[20];
for(int i = 0; i < A.length; i++)
A[i] = Math.random();
double sum = 0;
int k = 0;
do{
k += 3;
sum += A[k];
}while(k < 20);
System.out.println("sum = " + sum);
}
Again I am looking to determine the reason for the error not necessarily a way to fix it.
Here is your problem:
do{
k += 3;
sum += A[k];
}while(k < 20);
K will be equal to 0, then 3, then 6, etc, up until it reaches 21 and then you try and access A[21] which is out of bounds.
This is because when k = 18 on the 6th iteration of the while loop, (k < 20) is true and therefore the while loop continues and adds another 3 to k making it 21. After that, the while loop stops as k is not less than 20 anymore leaving k with a value of 21.
You're getting the error because you're hitting 21 on a array with the size of 20. To fix:
do{
k += 3;
if(k <= 20){
sum += A[k];
}
}while(k < 20);
Your second loop, where you calculate the sum, is a do/while loop, meaning the condition will always get checked after the loop body is executed. You count k up in steps of 3, meaning it will reach 21 at some point before the while (k < 20) condition returns false, resulting in your error.
I think the problem is that k is incrementing and being used as an array index, before the <20 test.
something like this might work better:
for (int k = 0; k < 20; k = k + 3) {
sum += A[k];
}
In general, i think the do while construct here is a bit of unnecessary complexity. The version above is easier to read and is a more common pattern.
With the current logic, k will be 3,6,9,12,15,18 and 21. The last value is responsible for the out of bounds exception. Your loop will not stop at 18 as it is smaller than 20. You could resolve the bug by changing your code to this:
do{
k += 3;
sum += A[k];
}while(k < 18);
You increment the array index before using it. So you are not only going beyond the array index in last pass, you are also not adding the element at 0 index.
I have an array, and I'd like to go through it with a for loop in the following way:use 2 element then skip 2 elements,then use 2 elements etc.
So for instance if I have and int array : 1 2 3 4 5 6 7 8 9 10
I'd like to work with 1 and 2 then skip 3 and 4 ,then again work with 5,6 skip 7,8 etc.
Is this possible in java?
You can do something like this:
for (int i = 0; i < array.length - 1; i += 4) {
// work with i and (i + 1)
}
Yes, you need a loop, but two would be simpler.
for (int i = 0; i < N; i += 4)
for (int j = i; j < i + 1; j++)
System.out.println(j);
Also you can do
IntStream.range(0, N)
.flatMap(i -> IntStream.range(i+1, i+3))
.forEach(System.out::println):
Something along the lines of this pseudo code will do the job:
for (int i=0; i<array.length-3; i+=4) {
int first = array[i];
int second = array[i+1];
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
}
Note: normally when looping through an array you can just use i<array.length-1, but because you could be skipping 2 at that point I believe you want to decrease the "OK" length of the array by 2 more.
Update: actual working Java code using a toggle:
boolean skip = false;
for (int i=0; i<test.length-1; i+=2) {
if (!skip) {
System.out.println(test[i]);
System.out.println(test[i+1]);
}
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
skip = !skip;
}
You can introduce as many variables as you need inside of a for loop and iterate through those. It's similar to using two loops with the advantage being that there's no extra iterations being done.
The main thing here is that you're skipping four entries in your array every time. This applies to both variables, and you also want to be sure that both of them are less than the length of the overall array (so you don't step off of it by mistake).
for (int i = 0, j = i + 1; i < array.length && j < array.length; i += 4, j += 4) {
System.out.printf("(%d, %d) ", array[i], array[j]);
}
I need to produce a triangle as shown:
1
22
333
4444
55555
and my code is:
int i, j;
for(i = 1; i <= 5; i++)
{
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
Producing a triangle the opposite way
1
22
333
4444
55555
What do i need to do to my code to make it face the right way?
You need 3 for loops:
Upper-level loop for the actual number to be repeated and printed
first inner level for printing the spaces
second inner level for to print the number repeatedly
at the end of the Upper-level loop print new line
Code:
public void printReversedTriangle(int num)
{
for(int i=0; i<=num; i++)
{
for(int j=num-i; j>0; j--)
{
System.out.print(" ");
}
for(int z=0; z<i; z++)
{
System.out.print(i);
}
System.out.println();
}
}
Output:
1
22
333
4444
55555
666666
I came across this problem in my AP CS class. I think you may be starting to learn how to program so heres what I'd do without giving you the answer.
Use a loop which removes the number of spaces each iteration. The first time through you would want to print four spaces then print 1 one time(probably done in a separate loop).
Next time through one less space, but print i one more time.
You need to print some spaces. There is a relation between the number of spaces you need and the number (i) you're printing. You can print X number of spaces using :
for (int k = 0; k < numSpaces; k++)
{
System.out.print(" ");
}
So in your code:
int i, j;
for(i = 1; i <= 5; i++)
{
// Determine number of spaces needed
// print spaces
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
use this code ,
int i, j,z;
boolean repeat = false;
for (i = 1; i <= 5; i++) {
repeat = true;
for (j = 1; j <= i; j++) {
if(repeat){
z = i;
repeat = false;
while(z<5){
System.out.print(" ");
z++;
}
}
System.out.print(i);
}
{
System.out.print("\n");
}
}
You can use this:
int i, j;
int size = 5;
for (i = 1; i <= size; i++) {
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
for (j = 1; j <= i; j++) {
System.out.print(i);
}
System.out.print("\n");
}
This line:
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
Is going to print the left spaces.
It uses the old printf with a fixed sized string like 5 characters: %5s
Try it here: http://ideone.com/jAQk67
i'm having trouble sometimes as well when it's about formatting on console...
...i usually extract that problem into a separate method...
all about how to create the numbers and spacing has been posted already, so this might be overkill ^^
/**
* creates a String of the inputted number with leading spaces
* #param number the number to be formatted
* #param length the length of the returned string
* #return a String of the number with the size length
*/
static String formatNumber(int number, int length){
String numberFormatted = ""+number; //start with the number
do{
numberFormatted = " "+numberFormatted; //add spaces in front of
}while(numberFormatted.length()<length); //until it reaches desired length
return formattedNumber;
}
that example can be easily modified to be used even for Strings or whatever ^^
Use three loops and it will produce your required output:
for (int i=1;i<6 ;i++ )
{
for(int j=5;j>i;j--)
{
System.out.print(" ");
}
for(int k=0;k<i;k++)
{
System.out.print(i);
}
System.out.print("\n");
}
Your code does not produce the opposite, because the opposite would mean that you have spaces but on the right side. The right side of your output is simply empty, making you think you have the opposite. You need to include spaces in order to form the shape you want.
Try this:
public class Test{
public static void main (String [] args){
for(int line = 1; line <= 5; line++){
//i decreases with every loop since number of spaces
//is decreasing
for(int i =-1*line +5; i>=1; i--){
System.out.print(" ");
}
//j increases with every loop since number of numbers
//is decreasing
for(int j = 1; j <= line; j++){
System.out.print(line);
}
//End of loop, start a new line
System.out.println();
}
}
}
You approached the problem correctly, by starting with the number of lines. Next you have to make a relation between the number of lines (the first for loop) and the for loops inside. When you want to do that remember this formula:
Rate of change*line + X = number of elements on line
You calculate rate of change by seeing how the number of elements change after each line. For example on the first line you have 4 spaces, on the second line you have 3 spaces. You do 3 - 4 = -1, in other words with each line you move to, the number of spaces is decreasing by 1. Now pick a line, let's say second line. By using the formula you will have
-1(rate of change) * 2(line) + X = 3(how many spaces you have on the line you picked).
You get X = 5, and there you go you have your formula which you can use in your code as you can see on line 4 in the for loop.
for(int i = -1 * line +5; i >= 1; i--)
You do the same for the amount of numbers on each line, but since rate of change is 1 i.e with every line the amount of numbers is increasing by 1, X will be 0 since the number of elements is equal to the line number.
for(int j = 1; j <= line; j++){
I am recently reading the book called Algorithms by Robert Sedgewick. I came across one piece of code while reading "Analysis of Algorithms". The code is as follow :
public static int count(int a[]) {
int N = a.length;
int cnt = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) {
if (a[i] + a[j] + a[k] == 0) { //here
cnt++;
}
}
}
}
return cnt
}
What I want to know is how many times of the if-statement within the for-loop been executed. The answer provided by the book is N(N-1)(N-2)/6. But I don't know why, could anyone explain.
You just need to evaluate the following sum:
You could do that by hand, but Wolfram Alpha is much better at that.
It is not hard to verify that
(N-1)(N-2) = N2 - 3N + 2
which shows the formula you gave.
For the manual analysis:
Start with the inner sum, which is easy:
Plugging this in the middle sum gives:
This sum would be easier to evaluate if the dummy variable started from 0 (rather than i+1), therefore we apply the dummy transformation p = j - i - 1:
Finally, this must be plugged in the outer sum:
I've been having a play with this. It seems the question is as much one of Mathematics as it is of computing.
First thing's first. The actual contents of the if statement are a complete red herring as they are dependent on the contents of the array. I have used the first x natural numbers starting from 0 (effectively the index of the array) and as such the if statement never resolves to true.
To test the assertion that the if statement is accessed n(n-1)(n-2) times I have changed the code to the following:
public class Iteration {
public static void main(String[] args) {
int[] a = {0,1,2,3,4};
System.out.println(count(a));
}
public static int count(int a[]) {
int N = a.length;
int cnt = 0;
int access = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) {
access++;
System.out.println(access + " " +a[i] + a[j] + a[k]);
if (a[i] + a[j] + a[k] == 0 ) { //here
cnt++;
}
}
}
}
return cnt;
}
}
The console return from this is the following:
1 012
2 013
3 014
4 023
5 024
6 034
7 123
8 124
9 134
10 234
0
That is the count of unique combinations of the integers provided. So I have looked up the formula for unique combinations of three digits from Maths is fun.
A brief synopsis of the '6' in the formula then. As each combination of 3 digits is appearing only once consider how many times you could order 3 digits (lets look at 1, 2 and 3):
123 132 213 231 312 321
6 times! but as this combination is appearing only once (123) we divide the total by 6 to find how many are returned. The details on the maths are further described on the link above, including the general solution regardless of the number of integers used, and the size of the loop.
The variables i, j, and k are taken from the set {0,1,...,N-1}. But they're always in order, so the number of possibilities is C(N,3)=N!/((N-3)!3!).
I am writing a method that would take the values and the array and find duplicates. If there are duplicates, like for instance two values have the same value, I will multiple that value by 2. If two values have the same value, I will multiple that value by 3. This will continue until if seven values are the same. I will multiple that value by 7.
This is my source code.
public static double calculateWinnings(int[]numbers)
{
double total = 0;
for (int i = 0; i < numbers.length - 1; i++)
{
for (int j = i + 1; j < numbers.length; j++)
{
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total;
}
}
}
return total;
}
If order doesn't matter, you should sort first, then analyze.
Sorting will put identical values next to each other, where you could more easily notice them in a for loop.
The Java Collections classes may also be of use here.
See for instance http://download.oracle.com/javase/tutorial/collections/intro/index.html
For instance, if you don't want to sort first and use a loop, you could use a HashMap from the collections classes.
HashMap<Integer, Integer> counts = new HashMap<Integer, Integer>();
for(int i=0; i < numbers.length; ++i){
Integer before = counts.get(numbers[i]);
if (before == null) before=0;
counts.put(numbers[i], before+1);
}
now you have a mapper from numbers to counts
later you can use something like max(counts.valueSet()) to find the maximum count
and then loop back through your hash to see which number caused that.
If you have same values at index 1, 4, 6, you will find them with
i j conclusion
--------------
1 4 2 values
1 6 3 values
4 6 4 values // oops! already counted
and so on. Well you would - but there is no so on, since you return on the first hit:
if(numbers[i] == numbers[j])
{
total = numbers[i] * .01;
System.out.println("Total is " + total);
return total; // oops!
}
Do you mean break?
You should provide some example inputs and outputs. It's not clear exactly what output you expect. Are you just looking to find the most duplicates and then multiply that number by the frequency it appears? For example:
1 2 5 5 5 7 8 8 = three 5's = 15
Or perhaps the two 8's wins because their total is 16? Or are you going to sum all of the duplicates? In any case I'd start with this, where MAX_NUM is the highest number you expect in the array:
int[] counts = new int[MAX_NUM];
for (int i = 0; i < numbers.length; i++) {
counts[numbers[i]]++;
}
Now you have the counts of each number. If you're looking for the number with the highest count:
int num = 0;
int best = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] > best) {
num = i;
best = counts[i];
}
}
Now num * best would be 15 for my example. Now num will contain the number that occurs the most and best will be the count for it. If there are two numbers with the same count then the higher number will win. Perhaps though in my example above you want 16 instead of 15 because the two 8's have a greater sum:
int max = 0;
for (int i = 0; i < counts.length; i++) {
max = Math.max(i * counts[i], max);
}
Now max would have 16.