Im having trouble to find out if a specific amount of numbers is in another array.The first array generates 10 random numbers and in the second array the user guesses 5 numbers.Im trying to find out if the user guessed any sequences.I used for loops to find out if numbers of user input is in any of the numbers from 1-5 in the array of 10 , if not it will check numbers 2-6 and so on.
For example, if the program had the following winning numbers:
23 56 67 06 43 22 59 24 90 66 and user entered: 01 06 43 22 89.
I keep getting index out of bounds.How do I fix this ?
// to check if user guessed a sequence
boolean guessed = false;
int counter = 0;
int i , j = 0;
for (i = 4; i < numbers.length; i++) { // users numbers
for ( j = 4; j < lottery.length; j++) { // first 5 numbers from array
if ( lottery[i] == numbers[j]) {
break;
}
if ( j == i) {
guessed = true;
}
}
}
It seems that a method similar to String::indexOf should be implemented in this task for the arrays trying to find an index of a subarray int indexOf(int[] search, int[] input).
Also, it might be needed to look for all possible subarrays of the search subarray (lottery). Thus, the mentioned method should be extended to look for a subrange of the search argument: int indexOf(int[] search, int[] input)
Straightforward implementation would be:
static int indexOf(int search[], int from, int to, int[] input) {
if (null == search || null == input || search.length > input.length) {
return -1;
}
for (int i = 0, n = input.length - (to - from); i <= n; i++) {
boolean found = true;
for (int j = from; found && j < to; j++) {
if (input[i + j - from] != search[j]) {
found = false;
}
}
if (found) {
return i;
}
}
return -1;
}
The widths and appropriate indexes from / to of the search subranges can be generated as follows (from the entire length of lottery to 2):
int[] numbers = {23, 56, 67, 06, 43, 22, 59, 24, 90, 66};
int[] lottery = {01, 06, 43, 22, 89};
for (int n = lottery.length; n > 1; n--) {
for (int m = 0; m <= lottery.length - n; m++) {
int ix = indexOf(lottery, m, m + n, numbers);
if (ix > -1) {
System.out.printf("Found subarray %s, width=%d from: %d to %d ",
Arrays.toString(Arrays.copyOfRange(lottery, m, m + n)), n, m, m + n - 1);
System.out.printf("at index: %d%n", ix);
}
}
}
Output
Found subarray [6, 43, 22], width=3 from: 1 to 3 at index: 3
Found subarray [6, 43], width=2 from: 1 to 2 at index: 3
Found subarray [43, 22], width=2 from: 2 to 3 at index: 4
A more efficient implementation would use Knuth - Morris - Pratt algorithm to bypass recurrent checks of the same values in the input array.
Related
In an infinite sequence of numbers [2, 5, 7, 22, 25, 27, 52, 55, 57, 72, 75, 77, 222, ...].
Given any number in this sequence get the immediate successor number.
Example:
Input Output
22 25
77 222
5 7
I have written the below logic to find the next number in a sequence.
public static int getNextNumInSequence(Integer sequenceCurrentNum) {
List<Integer> sequence = new ArrayList<>();
sequence.add(2);
sequence.add(5);
sequence.add(7);
if(sequence.get(0).equals(sequenceCurrentNum))
return sequence.get(1);
else if(sequence.get(1).equals(sequenceCurrentNum))
return sequence.get(2);
//This is not a finite loop, just for my testing i am running 300 iterations.
for(int i=0;i<300;i++) {
if(sequence.get(i).equals(sequenceCurrentNum)) {
return sequence.get(i+1);
}
int nextVal = sequence.get(i)*10;
Integer firstSeq = nextVal + sequence.get(0);
Integer secondSeq = nextVal + sequence.get(1);
Integer thirdSeq = nextVal + sequence.get(2);
sequence.add(firstSeq);
sequence.add(secondSeq);
sequence.add(thirdSeq);
if(firstSeq.equals(sequenceCurrentNum)) {
return secondSeq;
}else if(secondSeq.equals(sequenceCurrentNum)) {
return thirdSeq;
}
}
return 0;
}
My Approach:
I am constructing the entire sequence from the beginning
Then checking if we have reached to the given number in sequence.
Then return the successor.
Drawbacks:
I am constructing the entire sequence to reach to given number.
Memory wise and performance wise not suggestable.
Please help to understand, is there any better approach to get the successor without constructing entire sequence.
Example: Given 277755 should return 277757. (Without constructing the
entire sequnce)
Note: The sequence will not be provided as an input to our function. The only input we will be given is a valid number from the sequence.
Try this.
public static int getNextNumInSequence(Integer sequenceCurrentNum) {
int head = sequenceCurrentNum / 10;
int tail = sequenceCurrentNum % 10;
int headNext = head == 0 ? 2 : getNextNumInSequence(head);
if (headNext == 0) return 0;
switch (tail) {
case 2: return head * 10 + 5;
case 5: return head * 10 + 7;
case 7: return headNext * 10 + 2;
default: return 0;
}
}
public static void main(String[] args) {
for (int i = 0, k = 2; i < 20; ++i, k = getNextNumInSequence(k))
System.out.println(i + " : " + k);
}
output:
0 : 2
1 : 5
2 : 7
3 : 22
4 : 25
5 : 27
6 : 52
7 : 55
8 : 57
9 : 72
10 : 75
11 : 77
12 : 222
13 : 225
14 : 227
15 : 252
16 : 255
17 : 257
18 : 272
19 : 275
You can also get n-th number.
public static int getNumAtIndex(int n) {
int h = n / 3;
int t = n % 3;
return (h == 0 ? 0 : getNumAtIndex(h) * 10)
+ (t == 0 ? 2 : t == 1 ? 5 : 7);
}
test:
public static void main(String[] args) {
for (int i = 0; i < 10; ++i)
System.out.println(i + " : " + getNumAtIndex(i));
}
output:
0 : 2
1 : 5
2 : 7
3 : 52
4 : 55
5 : 57
6 : 72
7 : 75
8 : 77
9 : 522
First try to understand what is the logic behind the sequence. If you look carefully to the numbers, you may see counting in ternary base. To be more clear, let's replace '2' by '0', '5' by '1' and '7' by '2'. Then your sequence becomes:
(0, 1, 2, 10, 11, 12, 20, 21, 22, 100, 101, 102, ...)
It's just counting.
So the thing is to get the next number in ternary base, but using the digits 2, 5, 7. We must take care of digit 7: if we increment it, we get 2 but we have a carry for the digit before.
Here is a sample code:
public static Integer getNextNumInSequence(Integer number)
{
int digits[] = {2,5,7};
int idx_digits[] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, -1};
Integer next_number = 0;
int carry = 1;
Integer pow10 = 1;
while (number>0)
{
int digit = number%10; //extract last digit
int idx_d = idx_digits[digit]; //get index of digit -- must be 0,1 or 2
if (idx_d==-1)
{
System.out.println("Invalid number");
return -1;
}
next_number += digits[(idx_d+carry)%3]*pow10; //compute next digit in sequence, taking care of the carry
carry = (digit==7)?1:0; //carry is 1 only if the current digit is 7
pow10 *= 10; //increment
number /= 10; //erase last digit
if (carry==0) //if no carry, we can stop the loop here, it's not useful to continue
{
break;
}
}
// at this point, either number>0 or carry==1
return ((carry>0)?2:number)*pow10+next_number; //final number is the digit sequence [2 if carry else number ; next_number]
}
You can solve this recursively.
If the final digit of the given number is 2 or 5, then it is easy: just change that final digit to 5 or 7 respectively.
Otherwise (when the final digit is 7), solve the problem without the last digit, and then append the digit 2 to that result. Of course, "without last digit" means an integer division by 10, and "appending" means multiplying by 10 and then adding the value of the digit.
Here is the function:
public static int getNextNumInSequence(Integer curr) {
if (curr % 10 == 2) return curr + 3;
if (curr % 10 == 5) return curr + 2;
if (curr == 7) return 22;
return getNextNumInSequence(curr / 10) * 10 + 2;
}
Note that one call has worst case time complexity of O(logn) where n is the value of the function argument, but amortised time complexity is O(1) per call.
To construct the list, you can simply do this:
List<Integer> list = Arrays.asList(2, 5, 7, 22, 25, 27, 52, 55, 57, 72, 75, 77, 222);
Note that there are cases where there is not successor. Here I will return null in those cases:
public static Integer getNextNumInSequence(List<Integer> list, Integer num) {
int pos = list.indexOf(num);
if (pos >= 0 && pos+1 < list.size()) {
return list.get(pos+1);
}
return null;
}
Note that I've added a parameter list so that you don't have to build the list each time you want to do a search.
In your example, the list is sorted; If it's always the case, you can use a binary search: Collections.binarySearch(list, num) instead of list.indexOf(num).
OK. If I understand correctly, you have three initial values:
static final int[] initial = {2, 5, 7};
and you can calculate the value at position ix like this:
private static int calculate(int ix) {
int div = ix/initial.length;
int rest = ix%initial.length;
int value = 0;
if (div > 0) {
value = 10*calculate(div-1);
}
return value+initial[rest];
}
To get the successor of num:
public static Integer getNextNumInSequence(int num) {
for (int i = 0; ; ++i) {
int cur = calculate(i);
if (cur == num) {
return calculate(i+1);
} else if (cur > num) {
return null;
}
}
}
I want to save a triangular matrix in a 1 dim array (to minimize needed space, all zeros are left out) and create a function get() to find a specific entry from the original matrix.
For example:
Lets look at the following triangular matrix :
0 1 2 3
0 0 4 5
0 0 0 6
0 0 0 0
I am saving this matrix like this:
double[] test = {1,2,3,4,5,6};
So all the zeros are left out.
I want to write a function that gives me a value of the original matrix:
get(3,4)
should give me 6
I am checking the input to see if its out of bound and if it is below or on the diagonal.
//Checking if input is valid
if (i <= n && j <= n && i >= 1 && j >= 1){
if( j <= i ){
return 0.0;
}else {
}
}
This works.
How do I proceed though? I have trouble finding the equivalent matrix entry in my array.
Any help would be appreciated.
EDIT:
My whole code:
public class dreiecksmatrix {
int n = 4;
double[] a = {1,2,3,4,5,6};
public double get( int i, int j){
//Checking if input is valid
if (i <= n && j <= n && i >= 0 && j >= 0){
if( j <= i ){
return 0.0;
}else {
}
}
return 1.0;
}
public static void main(String [] args ){
dreiecksmatrix test = new dreiecksmatrix();
System.out.println(test.get(2,3));
}
}
Here is the sample code calculating the value of top-triange. No corner cases check like i,j >= 1 yet, but it's easy to add them.
arr = [[0, 1, 2, 3, 4],
[0, 0, 5, 6, 7],
[0, 0, 0, 8, 9],
[0, 0, 0, 0, 10],
[0, 0, 0, 0, 0]];
flatArr = [1,2,3,4,5,6,7,8,9,10];
n = 5; // matrix size
i = 1;
j = 3;
if (j <= i) {
alert(0);
} else {
pos = 0;
// find an offset caused by first (i - 1) lines
for (k = 1; k < i; k++) {
pos += n - k;
}
// find an offset in line x
pos += j - i;
// array index start from 0 so decrement value
pos = pos - 1;
alert('flatArr[' + pos + '] = ' + flatArr[pos]);
}
If you were instead to store the matrix by columns, there is a simple formula for the index into test of the i,j'th matrix element.
In your example you would have
double[] test = {1,2,4,3,5,6};
If Col(i) is the index pf the start of column i
then
Col(2) = 0
Col(3) = Col(2) + 1
..
Col(n) = Col(n-1) + n-1
Hence
Col(j) = ((j-1)*(j-2))/2
The i,j matrix element is stored i further on from the start of column j,
ie at Col(j)+i, so that you should add
return test[ ((j-1)*(j-2))/2 + i];
to your code
There is an analogous formula if you must store by rows rather than columns. It's a wee bit messier. The idea is to first figure out, starting with the last non-zero row, where the ends of the rows are solved.
This is the given question:
Given a non-negative number represented as an array of digits,
add 1 to the number ( increment the number represented by the digits ).
The digits are stored such that the most significant digit is at the head of the list.
Example:
If the vector has [1, 2, 3]
the returned vector should be [1, 2, 4]
as 123 + 1 = 124.
This is my code:
public class Solution {
public ArrayList<Integer> plusOne(ArrayList<Integer> A) {
int carry = 1;
int length = A.size();
ArrayList result = new ArrayList();
for( int i = length - 1; i >=0; i-- ){
int val = A.get(i) + carry;
result.add(0,val % 10);
carry = val / 10;
}
if (carry == 1){
result.add(0,1);
}
for (int j = 0; j < result.size(); j++){
if(result.get(j).equals(0))
result.remove(j);
else
break;
}
return result;
}
}
However, in the test case:
A : [ 0, 6, 0, 6, 4, 8, 8, 1 ]
it says my function returns
6 6 4 8 8 2
while the correct answer is
6 0 6 4 8 8 2
I have no idea what is wrong with my code.
Thanks!
if(result.get(j).equals(0))
result.remove(j);
else
break;
This will fail if every other index contains a 0. Here's what happens:
0 6 0 6 4 8 8 2
^ (j = 0)
The 0 will be removed, and j is incremented by one.
6 0 6 4 8 8 2
^ (j = 1)
Then this 0 is removed as well, skipping the first 6 in your array. To fix this, change the snippet to:
if(result.get(j).equals(0))
result.remove(j--);
else
break;
This compensates for when an index is removed so that j will not skip the number immediately after any removed 0s.
Check out a similar question at Looping through and arraylist and removing elements at specified index
simpler to do just
while (!result.isEmpty() && result.get(0).equals(0)) {
result.remove(0);
}
This will keep removing the left most 0 until there is no more left most zero to be deleted.
Your last for loop is removing 0 from your result ArrayList<Integer>. After removing that loop, you will get perfect output
public static ArrayList<Integer> plusOne(ArrayList<Integer> A) {
int carry = 1;
int length = A.size();
ArrayList result = new ArrayList();
for (int i = length - 1; i >= 0; i--) {
int val = A.get(i) + carry; //2 8
result.add(0, val % 10); // 2 8
carry = val / 10;
}
if (carry == 1) {
result.add(0, 1);
}
// for (int j = 0; j < result.size(); j++) {
// if (result.get(j).equals(0))
// result.remove(j);
// else
// break;
// }
for (boolean isZero = true; isZero; ) {
isZero = result.get(0).equals(0);
if(isZero)
result.remove(0);
}
return result;
}
I have an integer array: int[] numbers = new int[...n]; // n being limitless.
Where all the numbers are between 0 and 100.
Say numbers[] was equal to: [52, 67, 32, 43, 32, 21, 12, 5, 0, 3, 2, 0, 0];
I want to count how often each of those numbers occur.
I've got a second array: int[] occurrences = new int[100];.
I'd like to be able to store the amounts like such:
for(int i = 0; i < numbers.length; i++) {
// Store amount of 0's in numbers[] to occurrences[0]
// Store amount of 1's in numbers[] to occurrences[1]
}
So that occurrences[0] would be equal to 3, occurrences[1] would be equal to 0 etc.
Is there any efficient way of doing this without having to resort to external libraries? thanks.
You can simply do something like this:
for (int a : numbers) {
occurrences[a]++;
}
Also, if you mean 0 to 100 inclusive then occurrences will need to be of size 101 (i.e. 100 will need to be the maximum index).
You might also want to perform an "assertion" to ensure that each element of numbers is indeed in the valid range before you update occurrences.
Updated to put results in the 100-array.
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
<P>{#code java IntOccurancesInArray}</P>
**/
public class IntOccurancesInArray {
public static final void main(String[] igno_red) {
int[] ai = new int[]{52, 67, 32, 43, 32, 21, 12, 5, 0, 3, 2, 0, 0};
Map<Integer,Integer> mpNumWHits = new TreeMap<Integer,Integer>();
for(int i = 0; i < ai.length; i++) {
int iValue = ai[i];
if(!mpNumWHits.containsKey(iValue)) {
mpNumWHits.put(iValue, 1);
} else {
mpNumWHits.put(iValue, (mpNumWHits.get(iValue) + 1));
}
}
Set<Integer> stInts = mpNumWHits.keySet();
Iterator<Integer> itrInts = stInts.iterator();
int[] ai100 = new int[100];
int i = 0;
while(itrInts.hasNext()) {
int iValue = itrInts.next();
int iHits = mpNumWHits.get(iValue);
System.out.println(iValue + " found " + iHits + " times");
ai100[iValue] = iHits;
}
for(int j = 0; j < ai100.length; j++) {
if(ai100[j] > 0) {
System.out.println("ai100[" + j + "]=" + ai100[j]);
}
}
}
}
Output:
[C:\java_code\]java IntOccurancesInArray
0 found 3 times
2 found 1 times
3 found 1 times
5 found 1 times
12 found 1 times
21 found 1 times
32 found 2 times
43 found 1 times
52 found 1 times
67 found 1 times
ai100[0]=3
ai100[2]=1
ai100[3]=1
ai100[5]=1
ai100[12]=1
ai100[21]=1
ai100[32]=2
ai100[43]=1
ai100[52]=1
ai100[67]=1
This method is useful for knowing occurrences of all elements
You can reduce the space by finding the length of new array using sorting and taking value of last element + 1
import java.util.Arrays;
public class ArrayMain {
public static void main(String[] args) {
int a[] = {52, 67, 32, 43, 32, 21, 12, 5, 0, 3, 2, 0, 0};
Arrays.sort(a);
int len=a[a.length-1]+1;
int count[]=new int[len];
for(int n:a){
count[n]++;
}
for(int j=0;j<count.length;j++){
if(count[j]>=1){
System.out.println("count:"+j+"---"+count[j]);
}
}
}
}
Time Complexity : O(n)
Space Complexity : O(R) // last element value +1
Note : Creating new array may not be good idea if you have extreme numbers like 1, 2 and 96, 99 etc in terms of space.
For this case sorting and comparing next element is better approach
import java.util.Scanner;
public class CountNumOccurences {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int[] frequency = new int[100];
System.out.println("Enter the first integer: ");
int number = input.nextInt();
//Enter up to 100 integers, 0 to terminate
while (number != 0){
++frequency[number];
//read the next integer
System.out.print(
"Enter the next int value (zero to exit): ");
number = input.nextInt();
}
input.close();
System.out.println("Value\tFrequency");
for (int i = 0; i < frequency.length; i++) {
if (frequency[i] > 0){
if (frequency[i] > 1)
System.out.println(i + " occurs " + frequency[i] + " times");
else
System.out.println(i + " occurs " + frequency[i] + " time");
}
}
}
}
UVA link: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=464
I'm lost as to what I'm doing now. I don't know why I'm producing incorrect values. I printed out the array after I looked for shortest path. And it produces this:
[0, 3, 8, 8, 4]
[3, 0, 5, 11, 7]
[8, 5, 0, 9, 12]
[8, 11, 9, 0, 4]
[4, 7, 12, 4, 0]
The sample input is:
1
0 3 22 -1 4
3 0 5 -1 -1
22 5 0 9 20
-1 -1 9 0 4
4 -1 20 4 0
5 17 8 3 1
1 3
3 5
2 4
With the sample input, I produce the output:
From 1 to 3 :
Path: 1-->2-->3
Total cost :8
From 3 to 5 :
Path: 3-->2-->5
Total cost :12
From 2 to 4 :
Path: 2-->5-->4
Total cost :11
If I look at my array, it seems to be correct. But the correct answer is:
From 1 to 3 :
Path: 1-->5-->4-->3
Total cost : 21
From 3 to 5 :
Path: 3-->4-->5
Total cost : 16
From 2 to 4 :
Path: 2-->1-->5-->4
Total cost : 17
I think I missed adding the tax, but I don't know where to add it. I tried adding tax[j] to the path[i][j] while doing the shortest path, and then subtracting the tax[x-1] and tax[y-1] (x-1 is my source, y-1 is my destination). It doesn't work, and messes up my path array (it gives value to loops; I don't really need that). I really don't know where to put the tax.
Here is my code for reference:
import java.util.*;
public class Main{
public static final int INF = 9999999;
public static int[][] path;
public static int[][] next;
public static int[] tax;
public static void main(String[] adsf){
Scanner pp = new Scanner(System.in);
int testCases = pp.nextInt();
boolean first = true;
pp.nextLine();
pp.nextLine();
while(testCases-- >0){
String[] s1 = pp.nextLine().split(" ");
int size = s1.length;
path = new int[size][size];
next = new int[size][size];
for(int i = 0; i < path.length; i++)
Arrays.fill(path[i],INF);
tax = new int[size];
for(int j = 0; j < path[0].length; j++){
path[0][j] = Integer.parseInt(s1[j]);
if(path[0][j]==-1)
path[0][j]=INF;
}
for(int i = 1; i < path.length;i++){
s1 = pp.nextLine().split(" ");
for(int j = 0; j < path[0].length; j++){
path[i][j] = Integer.parseInt(s1[j]);
if(path[i][j]==-1)
path[i][j]=INF;
}
}
for(int k=0; k<tax.length;k++){
tax[k] = pp.nextInt();
} pp.nextLine();
apsp();
int x,y;
//for(int i = 0; i < size; i++)
//System.out.println(Arrays.toString(path[i]));
while(pp.hasNextInt()){
if(!first)
System.out.println();
x=pp.nextInt();
y=pp.nextInt();
int cost = path[x-1][y-1];
System.out.println("From "+x+" to "+y+" :");
System.out.print("Path: ");
ArrayList<Integer> print = getpath(x-1,y-1);
for(int l = 0; l < print.size(); l++){
System.out.print(print.get(l)+1);
if(l!=print.size()-1) System.out.print("-->");
else System.out.println();
}
System.out.println("Total cost :"+cost);
first = false;
}
}
}
public static void apsp(){
for(int k=0;k<path.length;k++){
for(int i=0;i<path.length;i++){
for(int j=0;j<path.length;j++){
if (path[i][k] + path[k][j] + tax[j] < path[i][j] + tax[j]) {
path[i][j] = path[i][k]+path[k][j];
next[i][j] = k;
} else{
path[i][j] = path[i][j];
}
}
}
}
}
public static ArrayList<Integer> getpath (int i, int j) {
ArrayList<Integer> pat = getMidPath(i,j);
pat.add(0,i);
pat.add(j);
return pat;
}
public static ArrayList<Integer> getMidPath(int i, int j){
if(next[i][j]==0)
return new ArrayList<Integer>();
ArrayList<Integer> pat = new ArrayList<Integer>();
pat.addAll(getMidPath(i,next[i][j]));
pat.add(next[i][j]);
pat.addAll(getMidPath(next[i][j],j));
return pat;
}
}
The tax is applied:
whenever any cargo passing through one city, except for the source and the destination cities.
So you if you have a path:
a -> b -> c -> d
Then you should include the cost of the path (a,b) + tax(b) + (b,c) + tax(c) + (c,d).
For implementing that into your algorithm, you should be able to add the city taxes to the path lengths like this:
If you know you're starting at a and ending at d, then any directed path to a city x, where x isn't a or b, should be treated as the cost of x + the tax at city x.
You will need to revert the path cost values back to the original ones for the next path you want to calculate the value of and re-add the tax values in for the new starting point and destination.