Putting data into Java arrays - java

I have a fundamental question about how arrays store data and how to properly put data into an array.
THIS PART ANSWERED
In this code the method spinWheel() is just calling an integer from 0-36.
for(cntr=0; cntr<99; cntr++)
{
spunNum=spinWheel();
all99Spun[0]=spunNum;
}
How do I adjust the array all99Spun[] so that the next time the loop executes it would put spunNum into all99Spun[1] and so forth?
Another question I have about arrays is how to check equality between 1 integer and all the integers stored in an array.
for example I have an array that stores all the red numbers of a roulette wheel.
int redNumbers[] = new int[] {1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36};
How would I check the equality of a number stored in the all99Spun array with that of the integers in the array of rednumbers?

Just change
all99Spun[0]=spunNum;
to
all99Spun[cntr]=spunNum;
To answer the second question, I think you just want to see if any one number from the spun array exists in the read array. If you want to check that just one number exists in the read array you can loop through until you find that number:
int num = all99Spun[0];
int index = -1;
for(int i = 0; i < redNumbers.length ; i++)
{
if(redNumbers[i] == num)
{
index = i;
break;
}
}
if at the end index does not equal -1, then the number was in the redNumbers array.
If you want to check it for the entire array:
for(int i = 0 ; i < all99Spun.length ; i++)
{
for(int j = 0; j < redNumbers.length; j++)
{
if(redNumbers[j] == all99Spun[i])
{
//doWork
}
}
}

Just change
all99Spun[0]=spunNum;
to
all99Spun[cntr]=spunNum;

Given the way I understand your first question, I think #Gregory's answer is right.
So I will try to answer your second question.
Another question I have about arrays is how to check equality between 1 integer and all the integers stored in an array.
There are 2 easy ways to see if an array of integers are equal.
Iterate through with a loop, keeping a reference to the previous number. The minute you find one that does not equal the previous one, you know they are not all equal.
Since you are using Java, you can add them all to a Set, which guarantees uniqueness. If they are all equal, then after adding them all to the set, the set should contain only 1 element.
Example of first:
for (int i = 0; previous = redNumbers[i]; i < redNumbers.length; i++) {
if (redNumbers[i] != previous) {
// they are not all equal.
}
previous = redNumbers[i];
}
Example of second:
Set<Integer> distinct = new TreeSet<>(Arrays.asList(redNumbers));
if (distinct.size() > 1) {
// they are not all equal.
}

Related

How to return all array permutations iteratively into a two-dimensional array?

I am trying to write a program that will iterate through all possible permutations of a String array, and return a two dimensional array with all the permutations. Specifically, I am trying to use a String array of length 4 to return a 2D array with 24 rows and 4 columns.
I have only found ways to print the Strings iteratively but not use them in an array. I have also found recursive ways of doing it, but they do not work, as I am using this code with others, and the recursive function is much more difficult.
For what I want the code to do, I know the header should be:
public class Permutation
{
public String[][] arrayPermutation(String[] str)
{
//code to return 2D array
}
}
//I tried using a recursive method with heap's algorithm, but it is very //complex with its parameters.
I am very new to programming and any help would be greatly appreciated.
Your permutation-problem is basically just an index-permutation problem.
If you can order the numbers from 0 to n - 1 in all possible variations, you can use them as indexes of your input array, and simply copy the Strings. The following algorithm is not optimal, but it is graphic enough to explain and implement iteratively.
public static String[][] getAllPermutations(String[] str) {
LinkedList<Integer> current = new LinkedList<>();
LinkedList<Integer[]> permutations = new LinkedList<>();
int length = str.length;
current.add(-1);
while (!current.isEmpty()) {
// increment from the last position.
int position = Integer.MAX_VALUE;
position = getNextUnused(current, current.pop() + 1);
while (position >= length && !current.isEmpty()) {
position = getNextUnused(current, current.pop() + 1);
}
if (position < length) {
current.push(position);
} else {
break;
}
// fill with all available indexes.
while (current.size() < length) {
// find first unused index.
int unused = getNextUnused(current, 0);
current.push(unused);
}
// record result row.
permutations.add(current.toArray(new Integer[0]));
}
// select the right String, based on the index-permutation done before.
int numPermutations = permutations.size();
String[][] result = new String[numPermutations][length];
for (int i = 0; i < numPermutations; ++i) {
Integer[] indexes = permutations.get(i);
String[] row = new String[length];
for (int d = 0; d < length; ++d) {
row[d] = str[indexes[d]];
}
result[i] = row;
}
return result;
}
public static int getNextUnused(LinkedList<Integer> used, Integer current) {
int unused = current != null ? current : 0;
while (used.contains(unused)) {
++unused;
}
return unused;
}
The getAllPermutations-method is organized in an initialization part, a loop collecting all permutations (numeric), and finally a convertion of the found index-permutation into the String-permutations.
As the convertion from int to String is trivial, I'll just explain the collection part. The loop iterates as long, as the representation is not completely depleted, or terminated from within.
First, we increment the representation (current). For that, we take the last 'digit' and increment it to the next free value. Then we pop, if we are above length, and look at the next digit (and increment it). We continue this, until we hit a legal value (one below length).
After that, we fill the remainder of the digits with all still remaining digits. That done, we store the current representation to the list of arrays.
This algorithm is not optimal in terms of runtime! Heap is faster. But implementing Heap's iteratively requires a non-trivial stack which is tiresome to implement/explain.

Two sum - Doesn't work

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
I should get output as [1,2] which are the indices for 2 and 4 respectively
public int[] twoSum(int[] nums, int target) {
int len = nums.length;
int[] arr = new int[2];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i < len; i++)
{
int value = nums[i] - target;
if(map.containsKey(value))
{
System.out.println("Hello");
arr[0] = value;
arr[1] = map.get(value);
return arr;
}
else
{
map.put(nums[i],i);
}
}
return null;
}
I don't get where the problem is, please help me out
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice. Consider input [3,2,4] and target is 6. I added (3,0) and (2,1) to the map and when I come to 4 and calculate value as 6 - 4 as 2 and when I check if 2 is a key present in map or not, it does not go in if loop.
Okay, let's take a step back for a second.
You have a list of values, [3,2,4]. You need to know which two will add up 6, well, by looking at it we know that the answer should be [1,2] (values 2 and 4)
The question now is, how do you do that programmatically
The solution is (to be honest), very simple, you need two loops, this allows you to compare each element in the list with every other element in the list
for (int outter = 0; outter < values.length; outter++) {
int outterValue = values[outter];
for (int inner = 0; inner < values.length; inner++) {
if (inner != outter) { // Don't want to compare the same index
int innerValue = values[inner];
if (innerValue + outterValue == targetValue) {
// The outter and inner indices now form the answer
}
}
}
}
While not highly efficient (yes, it would be easy to optimise the inner loop, but given the OP's current attempt, I forewent it), this is VERY simple example of how you might achieve what is actually a very common problem
int value = nums[i] - target;
Your subtraction is backwards, as nums[i] is probably smaller than target. So value is getting set to a negative number. The following would be better:
int value = target - nums[i];
(Fixing this won't fix your whole program, but it explains why you're getting the behavior that you are.)
This code for twoSum might help you. For the inputs of integer array, it will return the indices of the array if the sum of the values = target.
public static int[] twoSum(int[] nums, int target) {
int[] indices = new int[2];
outerloop:
for(int i = 0; i < nums.length; i++){
for(int j = 0; j < nums.length; j++){
if((nums[i]+nums[j]) == target){
indices[0] = i;
indices[1] = j;
break outerloop;
}
}
}
return indices;
}
You can call the function using
int[] num = {1,2,3};
int[] out = twoSum(num,4);
System.out.println(out[0]);
System.out.println(out[1]);
Output:
0
2
You should update the way you compute for the value as follows:
int value = target - nums[i];
You can also check this video if you want to better visualize it. It includes Brute force and Linear approach:

How to find first instance of element array

I'm a pretty basic programmer and I'm coding a 'Master-mind' style guessing game program.
Now the part I'm stuck with is that I want to go through an array and increase the pointer when I come across a specific number.
Now thats pretty easy and stuff, but what I want to do is ONLY increase the counter if the number is encountered for the first time. So, for example if there are two numbers (189, 999), I want the counter to increase only once, instead of 3 times, which is what my code is doing. I know why its doing that, but I can't really figure out a way to NOT do it (except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient) Here's my code:
for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
correctNumbers++;
}
}
}
Thanks for taking the time to read! I'd prefer it if you wouldn't give me a direct answer and just point me in the right direction so I can learn better. Thanks again!
Your question is quite unclear. I suppose 989 and 999 will return 1. Because you only deal with number, so the solution is:
Create a boolean array with 9 element, from 0-9, named isChecked
Initialize it with false.
Whenever you found a matching number, say 9, turn the boolean element to true, so that you don't count it again (isChecked[9] = true).
Here is the code:
var isChecked = [];
function resetArray(input) {
for (var i = 0; i < 10; i++) {
input[i + ''] = false;
}
}
resetArray(isChecked);
var firstNumber = '989',
secondNumber = '999',
correctNumbers = 0,
fNum, sNum;
for (var i = 0; i < firstNumber.length; i++) {
fNum = firstNumber.charAt(i);
// Skip already checked numbers
if (isChecked[fNum]) {
continue;
}
for (var j = 0; j < secondNumber.length; j++) {
sNum = secondNumber.charAt(j);
if (fNum == sNum && !isChecked[sNum]) {
correctNumbers++;
isChecked[sNum] = true;
}
}
}
console.log(correctNumbers);
Tested on JSFiddle.
If you find anything unclear, feel free to ask me :)
(except maybe declaring an array and putting all the repeated numbers in there and only incrementing it if none of the numbers match, but that's super inefficient)
That approach is a good one, and can be made efficient by using a HashSet of Integers. Everytime you encounter a common digit, you do a contains on the set to check for that digit (gets in HashSets are of constant-time complexitiy - O(1), i.e. super quick), and if it's present in there already, you skip it. If not, you add it into the set, and increment your correctNumbers.
I believe this would help
int found=0; for (int i = 0; i < mString.length(); i++) {
for (int j = 0; j < nString.length(); j++) {
if (mString.charAt(i) == nString.charAt(j)) {
if(found==0){
correctNumbers++;
}
}
}
}
You could try making another 1D array of
int size = nstring.length() * mstring.length();
bool[] array = new bool[size];`
and then have that store a boolean flag of whether that cell has been updated before.
you would find the unique index of the cell by using
bool flag = false
flag = array[(i % mString.length()) + j)];
if(flag == true){
<don't increment>
}else{
<increment>
array[(i % mString.length()) + j)] = true;
}
you could also do this using a 2d array that basically would act as a mirror of your existing table:
bool[][] array = new bool[mstring.length()][nString.length()];
Why not just use the new stream api? Then it's just that:
Arrays.stream(mString).flatMapToInt(s -> s.chars()).distinct().count();
I'll explain:
Arrays.stream(mString) -> Create stream of all strings.
flatMapToInt -> create single concatenated stream from many IntStreams
s -> s.chars() -> Used above to create streams of characters (as ints)
distinct -> remove all duplicates, so each character is counted only once
count -> count the (unique) characters

Why does this merge sort give incorrect results?

My assignment is to merge two arrays using int arrays that the user fills and we have to assume that there will be a maximum of 10000 inputs from the user, and the user inputs a negative number to stop. Then sort the array from least to greatest and print it out. Initially i thought that this would be quite easy but when i finished, i began getting outputs such as:
Enter the values for the first array, up to 10000 values, enter a negative number to quit: 1
3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
1
3
5
Second Array:
2
4
6
Merged Array:
6 1 2 3 4 5
as you can see, the six is out of place and i have no idea how to fix it. Here is the source code, i have included copious comments because I really want you guys to help me out to the best of your abilities. IF it's possible to use the same exact technique without implement new techniques and methods into the code please do so. I know there are methods in java that can do all of this in one line but it's for an assignment at a more basic level.
import java.util.Scanner;
public class Merge
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int [] first = new int[10000]; //first array, assume 10k inputs max
int [] second = new int[10000]; //first array, assume 10k inputs max
boolean legal = true; //WILL IMPLIMENT LATER
int end = 0; // set how many elements to put in my "both" array
int end2 = 0;// set how many elements to put in my "both" array
System.out.print("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
//get values
for(int i = 0; i<first.length; i++)
{
first[i] = scan.nextInt(); //fill first with user input
if(first[i] <0) //if negative number, stop loop
{
end = i; //get position of end of user input
break;
}
}
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
for(int i = 0; i<second.length; i++) //exact same as the first get values loop
{
second[i] = scan.nextInt();
if(second[i] <0)
{
end2 = i;
break;
}
}
System.out.print("First Array:\n");
for(int i = 0; i<first.length; i++) //print first array
{
if(i == end) //this prevents from printing thousands of zeros, only prints values that user inputed
break;
System.out.println(first[i] + " ");
}
System.out.print("Second Array:\n");
for(int i = 0; i<second.length; i++) //same as printing first array
{
if(i == end2)
break;
System.out.println(second[i] + " ");
}
int [] both = new int[(end)+(end2)]; //instanciate an int array to hold only inputted values from first[] and second[]
int [] bothF = new int[(end)+(end2)]; //this is for my simple sorter algotithm loop
for(int i = 0; i<both.length; i++) //fill both with the first array that was filled
{
both[i] = first[i];
}
int temp = end; // see below
for(int i = 0;i<both.length; i++) //fill array with the second array that was filled(starting from the end of the first array so that the first set is not overwritten
{
if(temp<both.length){ //this prevents an out of bounds
both[temp] = second[i];
temp++;}
}
//simple sorting algorithm
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
bothF[d] = both[d];
both[d] = both[i];
both[i] = bothF[d];
}
}
}
System.out.println("Merged Array:"); //print the results
for(int i = 0; i<both.length; i++)
{
System.out.print(both[i] + " ");
}
//System.out.println("ERROR: Array not in correct order");
}
Your sorting algorithm is faulty.
It's similar to selection sort, in that you take two elements and swap them if they're out of place. However, you don't stop the comparisons when you should: when the index d is less than the index i, the comparison-and-swap based on arr[d] > arr[i] is no longer valid.
The inner loop should terminate with i=d.
The logic of your sort goes something like this:
On the d-th loop, the elements at d+1 and to the right are correctly sorted (the larger numbers). This is true at the beginning, because there are 0 elements correctly sorted to the right of the right-most element.
On each of the outer loops (with the d counter), compare the d-th largest element slot with every unsorted element, and swap if the other element is larger.
This is sufficient to sort the array, but if you begin to compare the d-th largest element slot with already-sorted elements to its right, you'll end up with a larger number in the slot than should be. Therefore, the inner loop should terminate when it reaches d.
Sure, you can do it like this
for (int i = 0; i < end; i++) {
both[i] = first[i];
}
for (int i = 0; i < end2; i++) {
both[i + end] = second[i];
}
// simple sorting algorithm
for (int d = both.length - 1; d >= 0; d--) {
for (int i = 0; i < d; i++) {
if (both[i] > both[d]) {
int t = both[d];
both[d] = both[i];
both[i] = t;
}
}
}
Output(s) -
Enter the values for the first array, up to 10000 values, enter a negative number to quit3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
3
5
Second Array:
2
4
6
-1
Merged Array:
2 3 4 5 6
First I will start with some recommendations:
1.Give end1 and end2 the initial value as the array lengths.
The printing part - instead of breaking the loop - loop till i == end(if its not changed by the first part it will stay the array length).
One suggestion is to use a "while" statement on the user input to do the reading part (it seems cleaner then breaking the loop- but its OK to do it like you have done too).
Try to use more functions.
now to the main thing- why not to insert the numbers from both arrays to the join array keeping them sorted?
Guiding:
Keep a marker for each array.
Iterate over the new join array If arr1[marker1]> arr2[marker2]
insert arr2[marker2] to the joint array in the current position.
and add 1 to marker2. and the opposite.
(don't forget to choose what happens if the are equal).
This can be achieved because the arrays were sorted in the first place.
Have fun practicing!
I guess you have sort of a reverse "selection sort"-algorithm going on there. I made an class that run your code and printed out the output after every swap. Here is the code which is the same as you got in your application with the addition of print.
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
int temp = both[d];
both[d] = both[i];
both[i] = temp;
printArray(both);
}
}
}
and when we run this on an example array we get this output
[9, 8, 7, 6]=
-> 6879
-> 6789
-> 6798
-> 6978
-> 9678
The algorithm actually had the correct answer after two swaps but then it started shuffling them into wrong order. The issue is the inner for loops end parameter. When you have run the outer loop once, you can be certain that the biggest number is in the end. 'd' is here 3 and it will swap out a bigger number every time it encounters it. the if clause comparisions in the first loop is 6-9 (swap), 9-8, 9-7, 9-9. All good so far.
Potential problems comes in the second iteration with 'd' as 2. Array is now [6,8,7,9] and comparisons are 7-6, 7-8 (swap with result [6,7,8,9]), 8-8, 8-9 (swap!!) resulting in [6,7,9,8]. the last swap was the problematic one. We knew that the biggest number was already in the last spot, but we still compare against it. with every gotrough of the whole inner loop it will always find the biggest number (and all other bigger than both[d] that is already in place) and swap it to some wrong position.
As we know that the biggest number will be last after one iteration of the outer loop, we shouldn't compare against it in the second iteration. You sort of lock the 9 in the array and only try to sort the rest, being in this case [6,8,7] where d = 3, value 7. hence, your inner loop for(int i = 0; i<both.length; i++) becomes for(int i = 0; i<=d; i++). As an added bonus, you know that in the last iteration i==d, and thus the code inside it, if(both[d]<both[i]) will never be true, and you can further enhance the loop into for(int i = 0; i<d; i++).
In your algorithm you always do four comparisons in the inner loop over four iterations of the outer loop, which means there is a total of 16 comparisons. if we use the i<d we'll just do three comparisons in the inner loop on the first iteration of the outer loop, then two, then one. This brings it to a total of six comparisons.
Sorry if too rambling, just wanted to be thorough.

How do I change the order of the items in an arraylist in Java

I have an arraylist. For example
A = [1,2,3,4,5,6,7,8];
I need to change the order of the arraylist so that I can get
A = [2,1,4,3,6,5,8,7]. It means odd position item will be positioned in even positions and vice-versa.
Thanks
A simple approach that assumes
Length of A is given as A.size()
Array A can be accessed by A.get(index) and A.set(index, value)
If your array is not even, the last element is left as-is
Is to swap values in pairs - like this:
for (int index = 1; index < A.size(); index += 2) { // Swap on even indices.
// Swap values at positions index-1 and index.
Object temp = A.get(index-1); // Save value before overwrite.
A.set(index-1, A.get(index)); // First half of swap.
A.set(index, temp); // Final operation for swap.
}
Edit: Changed int to Object, and used A.size, A.get and A.set instead of [] indexers as suggested by comments.
You could do it in the following way:
int a[] = {1,2,3,4,5,6,7,8};
System.out.println("A=["+a[0]+","+a[1]+","+a[2]+","+a[3]+","+a[4]+","+a[5]+","+a[6]+","+a[7]+"]");
for (int i = 0; i < a.length/2; i++) {
int help;
help = a[i*2];
a[i*2]=a[i*2+1];
a[i*2+1] = help;
}
System.out.println("A=["+a[0]+","+a[1]+","+a[2]+","+a[3]+","+a[4]+","+a[5]+","+a[6]+","+a[7]+"]");
Ask if you have questions about the code.
Edit: I missed the arraylist, but the principle is the same.

Categories

Resources