In this case, I want to add two numbers in this array in to obtain a specific sum when added, let’s say, 4. I also want to output what indices are being added in order to obtain that specific sum, just to see the inner workings of my code. What am I doing wrong?
public static int addingNumbers(int[] a) {
int i1 = 0, i2 = 0;
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
if(a[i] + a[j] == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
System.out.println("The indices are " + i1 + " and " + i2);
return i1;
}
public static void main(String args[]) {
int[] a = {1, 2, 3, 4, 5, 6};
System.out.println(addingNumbers(a));
}
The error you are making is using only one loop that iterates over the array once:
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
In your loop you are setting i to 0 and j to 1, then you increment them with every step. So you are only comparing adjacent places in your array:
iteration: a[0] + a[1]
iteration: a[1] + a[2]
iteration: a[2] + a[3]
etc. pp
Since your array doesn't have two adjacent elements that sum up to 4 your if(a[i] + a[j] == 4) will never be entered and i1, i2 will still be 0 when the loop is finished.
To compare every array element with each other you should use 2 nested loops:
public static int addingNumbers(int[] a) {
int i1 = -1, i2 = -1;
for(int i = 0; i < a.length ; i++) {
for(int j = i+1; j < a.length ; j++) {
if(a[i] + a[j] == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
}
if(i1>=0 && i2 >=0) {
System.out.println("The indices are " + i1 + " and " + i2);
}
return i1;
}
Note that this will only print out the last detected 2 indices that add up to 4. If you want to be able to detect multiple possible solutions and print them out could for example move the System.out.println into the if block.
It can never be == 4 because 1+2=3 then 2+3=5. So it does nothing.
There is a logic error in your code. The sum you are checking in your code is never for.
I added some debug output for easy checking:
public static int addingNumbers(int[] a) {
int i1 = 0, i2 = 0;
for(int i = 0, j = i + 1; i < a.length && j < a.length; i++, j++) {
int sum = a[i] + a[j];
System.out.println(sum);
if(sum == 4) { // index 0 and index 2 when added gives you a sum 4
i1 = i;
i2 = j;
}
}
System.out.println("The indices are " + i1 + " and " + i2);
return i1;
}
Output is: 3
5
7
9
11
The indices are 0 and 0
0
this algorithm will never be able to add a[0] to a[2], be cause when you put j=i+1 it will always be 0+1 then 1+2 ... The sum of tow adjacent numbers is never pair.
An other matter is the condition to stop your loop must be j < a.length-1
try to explain more of what you want from your algorithm.
Are you over complicating this on purpose?
Trying to figure out your intention for this task.
Why don't you just do (this is pseudo):
for length of i {
if (a[i] + a[i+1] == 4) {
System.out.println("The indices are " + a[i] + " and " + a[i+1]);
}
}
Related
I'm supposed to write a program that reads an array of ints and outputs the number of "triples" in the array.
A "triple" is three consecutive ints in increasing order differing by 1 (i.e. 3,4,5 is a triple, but 5,4,3 and 2,4,6 are not).
How do I check for the "triples"?
Current Code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
int iterator = 0;
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
} for(int j =0; j < size; j++){
iterator++;
}
}
}
The following code loops through the entire array of integers. Inside of the loop it is checked if the third integer exists inside of the array ((i + 2) < array.Length) and the other 2 conditions are all about whether value1 is the same as the value2 decreased by 1 (array[i] == array[i + 1] - 1 and array[i + 1] == array[i + 2] - 1):
for (int i = 0; i < array.Length; i++)
{
if((i + 2) < array.Length && array[i] == array[i + 1] - 1 && array[i + 1] == array[i + 2] - 1)
System.out.println("Three values at indexes" + i + " " + (i + 1) + " and " + (i + 2) + " are a triple");
}
The code below is C# and sadly not compatible to Java that easily, I'll just leave that here for anyone who wants to know how its handled in C# (the vt variable is a so called ValueTriple):
(int, int, int) vt;
for (var i = 0; i < array.Length; i++)
{
if (i + 2 >= array.Length) continue;
vt = (array[i], array[i + 1], array[i + 2]);
if (vt.Item1 == vt.Item2 - 1 && vt.Item2 == vt.Item3 - 1)
Console.WriteLine($"Three values at indexes {i}, {i + 1} and {i + 2} (Values: {array[i]}, {array[i + 1]}, {array[i + 2]}) are a triple");
}
You may try following code
import java.util.Scanner;
public class Triplet {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
}
Integer counter = 0;
for(int i = 0; i < size-2; i++) {
if(array[i] == array[i+1] - 1 && array[i] == array[i+2] - 2) { //checking if three consecutive ints in increasing order differing by 1
counter++;
}
}
System.out.println(counter);
}
}
Hope this will help.
A method to find out the number of triplets could look like this. You then just have to call the method depending how your input is obtained and you wish to present the result.
public static int getNumberOfTriplets(int[] toBeChecked) {
int numberOfTriplets = 0;
int nextIndex = 0;
while (nextIndex < toBeChecked.length - 2) {
int first = toBeChecked[nextIndex];
int second = toBeChecked[nextIndex + 1];
int third = toBeChecked[nextIndex + 2];
if ((first + 1 == second) && (second + 1 == third)) {
numberOfTriplets++;
}
nextIndex++;
}
return numberOfTriplets;
}
Regardless of allowing the numbers to be in more than one triplet, the answer is fairly similar in how I would personally approach it:
//determines if the input sequence is consecutive
public boolean isConsecutive(int... values) {
return IntStream.range(1, values.length)
.allMatch(i -> values[i] == values[i - 1] + 1);
}
public int countTriples(int[] input, boolean uniques) {
if (input.length < 3) {
return 0;
}
int back = 0;
for(int i = 2; i < input.length; i++) {
if (isConsecutive(input[i - 2], input[i - 1], input [i]) {
back++;
if (uniques) { //whether to disallow overlapping numbers
i += 2; //triple found, ignore the used numbers if needed
}
}
}
return back;
}
Then in calling it:
Int[] input = new int[] {1, 2, 3, 5, 6, 7, 8};
countTriples(input, true); //3
countTriples(input, false); //2
I am trying to the length of the longest sequence of numbers shared by two arrays. Given the following two arrays:
int [] a = {1, 2, 3, 4, 6, 8,};
int [] b = {2, 1, 2, 3, 5, 6,};
The result should be 3 as the the longest common sequence between the two is{1, 2, 3}.
The numbers must be in a sequence for the program to consider to count it.
I have thought about it and wrote a small beginning however, I am not sure how to approach this
public static int longestSharedSequence(int[] arr, int[] arr2){
int start = 0;
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr2.length; j++){
int n = 0;
while(arr[i + n] == arr2[j + n]){
n++;
if(((i + n) >= arr.length) || ((j + n) >= arr2.length)){
break;
}
}
}
That is a very good start that you have. All you need to do is have some way of keeping track of the best n value that you have encountered. So at the start of the method, declare int maxN = 0. Then, after the while loop within the two for loops, check if n (the current matching sequence length) is greater than maxN (the longest matching sequence length encountered so far). If so, update maxN to the value of n.
Since you also want the matching elements to be in sequential order, you will need to check that the elements in the two arrays not only match, but that they are also 1 greater than the previous element in each array.
Putting these together gives the following code:
public static int longestSharedSequence(int[] arr, int[] arr2) {
int maxN = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr2.length; j++) {
int n = 0;
// Check that elements match and that they are either the
// first element in the sequence that is currently being
// compared or that they are 1 greater than the previous
// element
while (arr[i + n] == arr2[j + n]
&& (n == 0 || arr[i + n] == arr[i + n - 1] + 1)) {
n++;
if (i + n >= arr.length || j + n >= arr2.length) {
break;
}
}
// If we found a longer sequence than the previous longest,
// update maxN
if (n > maxN) {
maxN = n;
}
}
}
return maxN;
}
I didn't think of anything smarter than the path you were already on:
import java.util.Arrays;
import java.util.Random;
public class MaxSeq {
public static void main(String... args) {
int[] a = new int[10000];
int[] b = new int[10000];
final Random r = new Random();
Arrays.parallelSetAll(a, i -> r.nextInt(100));
Arrays.parallelSetAll(b, i -> r.nextInt(100));
System.out.println(longestSharedSequence(a, b));
}
private static int longestSharedSequence(final int[] arr, final int[] arr2) {
int max = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr2.length; j++) {
int n = 0;
while ((i + n) < arr.length
&& (j + n) < arr2.length
&& arr[i + n] == arr2[j + n]) {
n++;
}
max = Math.max(max, n);
}
}
return max;
}
}
see: https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
I'm trying to print the following:
2
2 4
2 4 6 ..etc
The code I have written (below) prints the following:
2
4 6
8 10 12 ...etc
Can anyone spot where I'm going wrong? The n variable comes from the main method which I am not including.
public static void printEvenTable(int n) {
int i;
int j;
int k = 0;
for (i = 1; i <= n; i++) {
for (j = 0; j < i; j++)
System.out.print(" " + (k += 2));
System.out.println(" ");
}
}
You need to prevent the variable k from using its old value by reassigning 0 to it right after the second for loop. Placing k = 0; before the second for loop makes redundant reassigning because it has already been assigned right before the loop. Ensure program optimization. If you are using a good editor, it show you some warning if placed before the second for loop.
for (i = 1; i <= n; i++) {
for (j = 0; j < i; j++) {
System.out.print(" " + (k += 2));
}
k=0;
System.out.println(" ");
}
Here, the inner loop is increasing the variable k by 2 in each steps after the first execution of the inner loop k becomes 2 from the initial value 0. In the second iteration of the outer loop k starts as 2. After k+=2, k becomes 4 so second line of output starts from 4. That's why we need to re-initialize k to 0 before each inner loop.
public static void printEvenTable(int n) {
int i;
int j;
int k = 0;
for (i = 1; i <= n; i++) {
k = 0;
for (j = 0; j < i; j++)
System.out.print(" " + (k += 2));
System.out.println(" ");
}
}
Note: no mapping, no sorting
Here's my code:
public static void countArray(int[] n){
int[] m = new int[n.length]; //50 elements of integers between values of 10 & 20
int count = 0;
int sum = 0;
for ( int i = 0; i < n.length ; i++){
m[i] = n[i]; //make a copy of array 'n'
System.out.print(m[i]+" ");
}System.out.println();
for ( int j =0; j < n.length ; j++){
count =0;
for(int i = 0; i < n.length ; i++){
if (n[j]%m[i]==0 && n[j] == m[i])
count++;
}if ( n[j]%m[j] == 0)
System.out.println(m[j] + " occurs = " + count);
}
}
So the problem is: I get repeating results like : "25 occurs = 5", on different lines.
What I think: the problem occurs because of if ( n[j]%m[j] == 0)
so I tried if ( n[j]%m[j+1] == 0). Another problem occurs since m[j] will be m[50] so it crashes but sort of give me the results that I want.
Result that I want: something like this: no repetitions and covers all the random integers on a set
17 occurs = 3
23 occurs = 2
19 occurs = 3
15 occurs = 2
12 occurs = 2
With some adaptation your code should work :
public static void countArray(int[] n){
boolean [] alreadyCounted = new boolean[n.length];
for (int i = 0; i < n.length ; i++){
int count = 0;
if (alreadyCounted[i]) {
// skip this one, already counted
continue;
}
for(int j = 0; j < n.length ; j++){
if (n[i] == n[j]) {
// mark as already counted
alreadyCounted[j] = true;
count++;
}
}
System.out.println(n[i] + " occurs = " + count);
}
}
You could definitely use the same logic with better code, I just tried to follow the original "coding style";
This is O(n^2) solution (read "very slow").
If you could use sorting, you could do it in O(n log(n)) - that is fast.
With mapping you could do it in O(n) - that is blazingly fast;
If you exploit the input limit you can lose the nested loop:
public static void main(String[] args)
{
//6 elements of integers between values of 10 & 20
int[] countMe = { 10, 10, 20, 10, 20, 15 };
countArray(countMe);
}
/** Count integers between values of 10 & 20 (inclusive) */
public static void countArray(int[] input)
{
final int LOWEST = 10;
final int HIGHEST = 20;
//Will allow indexes from 0 to 20 but only using 10 to 20
int[] count = new int[HIGHEST + 1];
for(int i = 0; i < input.length; i++)
{
//Complain properly if given bad input
if (input[i] < LOWEST || HIGHEST < input[i])
{
throw new IllegalArgumentException("All integers must be between " +
LOWEST + " and " + HIGHEST + ", inclusive");
}
//count
int numberFound = input[i];
count[numberFound] += 1;
}
for(int i = LOWEST; i <= HIGHEST; i++)
{
if (count[i] != 0)
{
System.out.println(i + " occurs = " + count[i]);
}
}
}
try this :(sort the array and then count the occurence of element)
public static void countArray(int[] n) {
int count = 0;
int i, j, t;
for (i = 0; i < n.length - 1; i++) // sort the array
{
for (j = i + 1; j < n.length; j++) {
if (n[i] > n[j]) {
t = n[i];
n[i] = n[j];
n[j] = t;
}
}
}
for (i = 0; i < n.length;)
{
for (j = i; j < n.length; j++) {
if (n[i] == n[j])
{
count++;
} else
break;
}
System.out.println(n[i] + " occurs " + count);
count = 0;
i = j;
}
}
Here's a nice, efficient way to do it, rather more efficiently than the other solutions posted here. This one runs in O(n) time, where the array is of length n. It assumes that you have some number MAX_VAL, representing the maximum value that you might find in your array, and that the minimum is 0. In your commenting you suggest that MAX_VAL==20.
public static void countOccurrences(int[] arr) {
int[] counts = new int[MAX_VAL+1];
//first we work out the count for each one
for (int i: arr)
counts[i]++;
//now we print the results
for (int i: arr)
if (counts[i]>0) {
System.out.println(i+" occurs "+counts[i]+" times");
//now set this count to zero so we won't get duplicates
counts[i]=0;
}
}
It first loops through the array increasing the relevant counter each time it finds an element. Then it goes back through, and prints out the count for each one. But, crucially, each time it prints the count for an integer, it resets that one's count to 0, so that it won't get printed again.
If you don't like the for (int i: arr) style, this is exactly equivalent:
public static void countOccurrences(int[] arr) {
int[] counts = new int[MAX_VAL+1];
//first we work out the count for each one
for (int i=0; i<arr.length; i++)
counts[arr[i]]++;
//now we print the results
for (int i=0; i<arr.length; i++)
if (counts[arr[i]]>0) {
System.out.println(arr[i]+" occurs "+counts[arr[i]]+" times");
//now set this count to zero so we won't get duplicates
counts[arr[i]]=0;
}
}
Hello I am a Java noob and I have trouble understanding this code.
Here is the code:
//print distinct triples (i, j, k) such that a[i] + a[j] + a[k] = 0
public static void printAll(int[] a) {
int N = a.length;
Arrays.sort(a);
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j++) {
int k = Arrays.binarySearch(a, -(a[i] + a[j]));
if (k > j) StdOut.println(a[i] + " " + a[j] + " " + a[k]);
}
}
}
I don't quiet understand this line
int k = Arrays.binarySearch(a, -(a[i] + a[j]));
Could anyone help me with this?
Thank you very much.
[...] what makes me confused is that why use -(a[i]+a[j]) at here.
They look for this value, since that's the only value that can make i + j + k = 0:
Given
a[i] + a[j] + a[k] = 0
and then solving for a[k] gives:
a[k] = -(a[i] + a[j])
The binarySearch method searches for the position of the second argument (in this case, -(a[i] + a[j])) in the array provided in the first argument. The array must be sorted. for example:
int[] ia = [ 2, 4, 6, 8, 10 ];
int i = Arrays.binarySearch(ia, 6);
// i == 2, since ia[2] = 6