Substitution in an Array List - java

I have to list out 10 unique numbers between 1 and 20, but before storing the numbers, the program should check whether the number is in the list or not. If the number is already in the list, it should generate a new number. Also, the amount of numbers replaced must be counted.
This is what I have so far:
public static void main(String[] args)
{
int[] arrayA = {16, 14, 20, 3, 6, 3, 9, 1, 11, 2};
System.out.print("List: ");
for(int w = 0; w < arrayA.length; w++)
{
System.out.print(arrayA[w] + " ");
}
}
As you can see, there are two "3"s on the list, I have to output the same list but change one of the "3"s. Plus it has to be counted.

This is not hard to do, but what do you mean by change one of the threes?
You can add a boolean flag outside of your for loop that can tell if you've encountered a 3 or not and what the index of that 3 is.
Try something like this:
boolean changedThree = false;
int threeIndex = -1;
for(int i = 0; i < arrayA.length; i++){
if(arrayA[i] == 3 && !changedThree){
arrayA[i] = 4;
threeIndex = i;
changedThree = true;
}
System.out.println(arrayA[i] + " ");
}
I don't know for sure if that captures the information you need, but hopefully can give you a push in the right direction. Let me know if you have questions.
EDIT
To avoid any duplicate values, I recommend you create an array list, and add the unique values to it. Then, you can use the ArrayList.contains() method to see if a value exists already. So, I would recommend changing your code to this:
ArrayList<int> usedCharacters = new ArrayList<int>();
int changedCounter = 0;
Random rand = new Random();
for(int i = 0; i < arrayA.length; i++){
if(!usedCharacters.contains(arrayA[i])){ // If we haven't used this number yet
usedCharacters.add(arrayA[i]);
} else{
// Generate a new number - make sure we aren't creating a duplicate
int temp = rand.nextInt(20) + 1;
while(usedCharacters.contains(temp)){
temp = rand.nextInt(20) + 1;
}
// Assign new variable, increment counter
arrayA[i] = temp;
changedCounter++;
}
}
If you're not familiar with the random.nextInt() method, read this.

so if I understand you correctly you have to save the arrayA, right?
If that is the case, you can just make a new array, targetArray where you can save to numbers to, and then check using a for-loop if you already added it, and if so you can generate a new, random number.
The result would look something like this:
public static void main(String[] args) {
int[] arrayA = {16, 14, 20, 3, 6, 3, 9, 1, 11, 2};
int[] targetArray = new int[10];
int numbersReplaced = 0;
System.out.print("List: ");
for (int i = 0; i < arrayA.length; i++) {
for (int j = 0; j < targetArray.length; j++) {
if (arrayA[i] == targetArray[j]) {
targetArray[j] = (int)(Math.random() * 100);
numbersReplaced++;
} else {
targetArray[j] = arrayA[i];
}
}
}
System.out.println("Numbers replaced: " + numbersReplaced);
}
Hope that helped

You could use recursion to achieve your result.
This will keep looping until all values are unique
private void removeDoubles(int[] arr) {
for(int i = 0; i < arr.length; i++)
{
// iterate over the same list
for(int j = 0; j < arr.length; j++) {
// Now if both indexes are different, but the values are the same, you generate a new random and repeat the process
if(j != i && arr[i] == arr[j]) {
// Generate new random
arr[j] = random.nextInt(20);
// Repeat
removeDoubles(arr);
}
}
}
}

Note: This is the sort of question I prefer to give guidance answers rather than just paste in code.
You could walk the array backward looking at the preceding sublist. If it contain the current number you replace with a new one.
Get the sublist with something like Arrays.asList(array).subList(0, i) and then use .contains().
You logic for finding what number to add depends on lots of stuff, but at it simplest, you might need to walk the array once first to find the "available" numbers--and store them in a new list. Pull a new number from that list each time you need to replace.
EDIT: As suggested in the comments you can make use of Java Set here as well. See the Set docs.

Related

Counting the number of common elements in integer arrays located at different positions

For my assignment, I need to write a method that returns the number of cows (see definition below) found between 2 arrays. If the input arrays have a different number of elements, then the method should throw an IllegalArgumentException with an appropriate message.
A bull is a common number in int arrays found at the same position while a cow is a common number in int arrays found at different position. Note that if a number is already a bull, it cannot be considered as a cow.
For example, considering the following arrays:
int[] secret = {2, 0, 6, 9};
int[] guessOne = {9, 5, 6, 2};
int[] guessTwo = {2, 0, 6, 2};
int[] guessThree = {1, 2, 3, 4, 5, 6};
int[] guessFour = {1, 3, 4, 4, 0, 5};
1) getNumOfCows(secret, guessOne) returns 2
2) getNumOfCows(secret, guessTwo) returns 0
3) getNumOfCows(secret, guessThree) returns an exception
4) getNumOfCows(guessThree, guessFour) returns 2
My method seen below works perfectly for examples 1 and 3, but there is a problem with examples 2 and 4 such that getNumOfCows(secret, guessTwo) returns 1 instead of 0 because the element at secret[0] and guessTwo[3] is considered a cow. Could anybody help me fix my code?
// A method that gets the number of cows in a guess --- TO BE FIXED
public static int getNumOfCows(int[] secretNumber, int[] guessedNumber) {
// Initialize and declare a variable that acts as a counter
int numberOfCows = 0;
// Initialize and declare an array
int[] verified = new int[secretNumber.length];
if (guessedNumber.length == secretNumber.length) {
// Loop through all the elements of both arrays to see if there is any matching digit
for (int i = 0; i < guessedNumber.length; i++) {
// Check if the digits represent a bull
if (guessedNumber[i] == secretNumber[i]) {
verified[i] = 1;
}
}
for (int i = 0; i < guessedNumber.length; i++) {
// Continue to the next iteration if the digits represent a bull
if (verified[i] == 1) {
continue;
}
else {
for (int j = 0; j < secretNumber.length; j++) {
if (guessedNumber[i] == secretNumber[j] && i != j) {
// Update the variable
numberOfCows++;
verified[i] = 1;
}
}
}
}
}
else {
// Throw an IllegalArgumentException
throw new IllegalArgumentException ("Both array must contain the same number of elements");
}
return numberOfCows;
}
First go through and mark all bulls using a separate array to make sure a position that is a bull also get counted as a cow
public static int getNumOfCows(int[] secretNumber, int[] guessedNumber) {
int max = secretNumber.length;
int cows = 0;
int[] checked = new int[max];
for (int i = 0; i < max; i++) {
if (secretNumber[i] == guessedNumber[i]) {
checked[i] = 1;
}
}
for (int i = 0; i < max; i++) {
if (checked[i] == 1) {
continue;
}
for (int j = 0; j < max; j++) {
if (secretNumber[i] == guessedNumber[j]) {
cows++;
checked[i] = 1;
}
}
}
return cows;
}
Now that this answer is accepted the original question can be voted to be closed as a duplicate
I am posting my answer from a duplicate question here and if this get approved then the other one can get closed as a duplicate.
The problem is that an element that is multiple times in at least one array will not be handled correctly.
A possible solution idea might be this one:
Create a cow list.
Iterate through both arrays and add every element that is in both arrays and has not been added yet. (note: complexity is n²)
Now that all possible cows are in the list, iterate through the array positions with the same index and if you find a bull, remove the number from the cow list.
Now the cow list contains only cows.
This solution might be a bit slower than your current one, but I think it's working properly.

Find All Possible Paths Algorithm

Hello there StackOverFlow! I am posting here today because I have a problem here in Java where I am trying to compute the all the possible combinations of pogo sticks that my character may use to move. The character uses pogo sticks which all have a distance, given by user input.
Likewise, the total distance is also given via user input and all possible paths are to be found. I have shown my function below with the output and the desired output that I can't seem to get quite right.
I have been stuck on this problem for a while and I am really hoping somebody can help me out here!
/*
* First integer in input
*/
int totalDistance;
/*
* The remaining integers in the input
*/
ArrayList<Integer> pogoSticks = new ArrayList<Integer>();
private void findPaths() {
ArrayList<ArrayList<Integer>> possibleSticks = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < pogoSticks.size(); i++) {
int pogoStickDistance = pogoSticks.get(i);
if (pogoStickDistance == totalDistance) {
if (!possibleSticks.contains(new ArrayList<Integer>(pogoStickDistance))) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(pogoStickDistance);
possibleSticks.add(list);
}
} else if (pogoStickDistance < totalDistance) {
int remainingDistance = totalDistance;
ArrayList<Integer> possibleSubSticks = new ArrayList<Integer>();
possibleSubSticks.add(pogoStickDistance);
remainingDistance -= pogoStickDistance;
for (int j = 0; j < pogoSticks.size(); j++) {
int pogoStickDistance1 = pogoSticks.get(j);
if (pogoStickDistance1 == remainingDistance) {
possibleSubSticks.add(pogoStickDistance1);
possibleSticks.add(possibleSubSticks);
break;
} else if (pogoStickDistance1 < remainingDistance) {
possibleSubSticks.add(pogoStickDistance1);
remainingDistance -= pogoStickDistance1;
}
if (j == (pogoSticks.size() - 1) && pogoStickDistance1 != remainingDistance) {
j = 0;
}
}
}
}
System.out.println(possibleSticks);
}
Here is the output that I get from running the function above:
Enter input: 5 10 4 1 2
[[4,1], [1,4], [2,1,2]]
Note that 5 is the distance, and 10, 4, 1, and 2 are the distances that a pogo stick may travel.
The issue is that these are not all the possible paths! For example, it is missing the paths such as [1, 1, 1, 1, 1] or [2, 2, 1].
Can anybody please help me modify my function to include these? I believe it is happening because once my loop finds the first occurrence of a pogo stick distance that's less than the remaining distance it will immediately use that path and ignore other possibilities.
for(int i = 0;i < pogoSticks.size();i++){
//part to calculate small enough
int[] temps = new int[pogoSticks.size];
int temp1 = 0;
for(int j; j< pogoStricks.size();i++){
if(pogoSticks.getIndex(j) + k <= totalDisatnce){
temps[temp1] = pogoSticks.getIndex(j);
}
//code to calculate number of paths to get to TotalDistance
This should do half the job, now you just need a method to calculate the distance from all the temps variables. I suggest you subtract each value from the TotalDistance and see which numbers added up would equal that.

Printing Java array -- only last element's value is shown, why?

Just to keep my skills sharp, I decided to write a small programme that prints out the values of an array, after being given two variables that each contain a different value.
My expectation was that each value would show onscreen, but this did not happen. Instead, only the last element's value was displayed onscreen (in the code below, being the number "2" --> That is an integer, not a string).
Why is this?
Also, why does dynamic initialisation produce the result I wish, but not the way I do it in the code?
Many thanks.
int[] arrayOne;
arrayOne = new int[2];
int numOne = 1;`
int numTwo = 2;`
for (int i = 0; i < arrayOne.length; i++) {`
arrayOne[i] = numOne;
arrayOne[i] = numTwo;
System.out.println(arrayOne[i]);
}
If you want to put the values of two variables into an array, you need to use two assignments:
arrayOne[0] = numOne;
arrayTwo[1] = numTwo;
Now you can use a for loop to print out the contents of the array.
This kind of defeats the purpose of using an array, though.
You're setting different values to same location, causing only last value to be saved.
Your code similar to doing:
arrayOne[0] = 1;
arrayOne[0] = 2;
After these two lines, arrayOne[0] will hold the value of 2.
If you want to put these two values, you need to put them in different places:
arrayOne[0] = 1;
arrayOne[1] = 2;
In Java (and in almost any language I know), an array can only contain one vale per cell i.e. if you do "array[i] = 1" and after "array[i] = 2" , then the i-cell will CHANGE its value from 1 to 2, not append the value 2 after the 1. In the end, youre array will contain numTwo in every single cell.
If you want to initialize the array with a different value in each cell, I'm afraid you need to do it manually, not using the loop.
You need to do the population of your array before you iterate through it with the loop.
arrayOne[0] = numOne;
arrayOne[1] = numTwo;
Then do your loop:
for (int i = 0; i < arrayOne.length; i++)
{
System.out.println(arrayOne[i]);
}
Many ways to initialize an array...
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
Or:
int[] a = new int[2];
for( int i = 0; i < a.length; i++ ){
a[i] = i + 1;
}
Or:
int[] a = new int[]{ 1, 2 };
Or.
int valOne = 1;
int valTwo = 2;
int[] a = new int[]{ valOne, valTwo };
Take care when you see more than one assignment to the same array element in a loop as you have it before the println. Is this what you want? The second one wins and sets the current (i-th) element to 2.
You need to do something like this:
public class demo{
private static int i = 0;
private static int[] demo = new int[10];
public static void main(String[] args){
for(int i = 0; i < 10; i++){
addElementToArray(i);
}
for(int i = 0; i < demo.length; i++){
System.out.println(demo[i]);
}
addElementToArray(i);
}
public static void addElementToArray(int input){
try{
demo[i] = input;
i++;
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
}
}
Don't set the values inside the for-loop either, that is (imo) plain stupid, for what you are trying to achieve

Iterating over a sorted array and storing the count of distinct integers

Can somebody PLEASE answer my specific question, I cannot use material not covered in class yet and must do it this way.
I'm trying to iterate over a sorted array and if the previous number == the current number it stores the count in possiton n of a new array; when the previous number != the current number, it then moves to n+1 on the new array and starts counting again.
I'm debugging it now but having trouble working out what it isn't work. Any help is much appreciated.
// Get the count of instances.
int[] countOfNumbers = new int[50]; // Array to store count
int sizeOfArray = 0; // Last position of array filled
int instanceCounter = 1; // Counts number of instances
int previousNumber = 0; // Number stored at [k-1]
for (int k=1; k < finalArrayOfNumbers.length; k++) {
previousNumber = finalArrayOfNumbers[k-0];
if (previousNumber == finalArrayOfNumbers[k]) {
instanceCounter++;
countOfNumbers[sizeOfArray] = instanceCounter;
}
instanceCounter = 1;
sizeOfArray++;
countOfNumbers[sizeOfArray] = instanceCounter;
Don't worry about mapping or anything, I just need to know how If I have an array of:
[20, 20, 40, 40, 50]
I can get back
[2, 2, 1]
There's lots of neat tools in the Java API so you can avoid doing a lot of this yourself:
List<Integer> list = Arrays.asList(20, 20, 40, 40, 50);
Map<Integer, Integer> freq = new LinkedHashMap<>();
for (int i: list) {
freq.put(i, Collections.frequency(list, i));
}
System.out.println(freq.values());
That'll print [2, 2, 1] like you wanted.
Alternatively if you'd like a list of only the distinct values in the list, you can use an implementation of Set.
But since you're restricted because this is a class assignment, you could do something like this instead:
int[] a = { 20, 20, 40, 40, 50 };
int[] freq = new int[a.length];
// count frequencies
for (int i = 1, j = 0, count = 1; i <= a.length; i++, count++) {
if (i == a.length || a[i] != a[i - 1]) {
freq[j++] = count;
count = 0;
}
}
// print
for (int i = 0; i < freq.length && freq[i] != 0; i++) {
System.out.println(freq[i]);
}
And the output is still the same.
I put comments in the two places you were off, here's your fixed code.
for (int k = 1; k < finalArrayOfNumbers.length; k++) {
previousNumber = finalArrayOfNumbers[k - 1]; // changed 0 to 1
if (previousNumber == finalArrayOfNumbers[k]) {
instanceCounter++;
countOfNumbers[sizeOfArray] = instanceCounter;
} else { // put this last bit in an else block
instanceCounter = 1;
sizeOfArray++;
countOfNumbers[sizeOfArray] = instanceCounter;
}
}
I'm debugging it now but having trouble working out what it isn't work. Any help is much appreciated.
Here's a clue for you:
previousNumber = finalArrayOfNumbers[k-0];
if (previousNumber == finalArrayOfNumbers[k]) {
Clue: 'k - 0' has the same value as 'k' in the above.
Clue 2: If your intention is that previousNumber contains the number you are currently counting, then it needs to be initialized outside of the loop, and updates when the current number changes.
Clue 3: You should not increment sizeOfArray on every loop iteration ...
Based on your Question, I'd say that your thinking about / understanding of the code that you have written is woolly. And this is why you are having difficulty debugging it.
In order to debug a piece of code effectively, you first need a mental model of how it ought to work. Then you use the debugger to watch what is happening at key points to confirm that the program is behaving as you expect it to.
(If you come into the debugging process without a mental model, all you see is statements executing, variables changing, etcetera ... with nothing to tell you if the right thing is happening. It is like watching the flashing lights on a computer in an old movie ... not enlightening.)
I would opt for a hashmap where the key is the number and its value the count. This way you have a unique number and count. Your solution runs into a problem where you don't really know at index i, what count that number belongs to, unless your list has no duplicates and is in order with no gaps, like 1, 2, 3, 4, 5 as opposed to the case of 1, 1, 1, 1, 5, 5, 5, 5
HashMap<Integer, Integer> occurances = new HashMap>Integer, Integer>();
int[] someSortedArray = new int[10];
//fill up a sorted array
for(int index = 0; index < someSortedArray.length; index++)
{
someSortedArray[index] = index+1;
}
int current = someSortedArray[0];
int count = 1;
for(int index = 1; index < someSortedArray.length; index++)
{
if(someSortedArray[index] != current)
{
occurances.put(current, count);
current = someSortedArray[index];
count = 1;
}else
{
count++;
}
}
System.out.println(occurances);
I think this should do it (haven't compiled).
You where not increasing sizeOfArray anywhere in your for loop.
// Get the count of instances.
int[] countOfNumbers = new int[50]; // Array to store count
int sizeOfArray = 0; // Last position of array filled
int instanceCounter = 1; // Counts number of instances
int previousNumber = finalArrayOfNumbers[0]; // Number stored at [k-1]
for (int k=1; k < finalArrayOfNumbers.length; k++) {
if (previousNumber == finalArrayOfNumbers[k]) {
instanceCounter++;
}
else
{
countOfNumbers[sizeOfArray] = instanceCounter;
instanceCounter = 1;
sizeOfArray++;
previousNumber = finalArrayOfNumbers[k]
}
}
countOfNumbers[sizeOfArray] = instanceCounter;

I'm getting strange output from java program

I've some strange situation here and i thought that you may help me. I have an int array populated with numbers from 1 to 10. I want to generate random number from this array and save it to another int array. I used class Random to pick any number and since random throws 0 also i modify it like that ( so it throws numbers from 1 to 10 )
randNum = rand.nextInt(numbers.length-min+1)+min;
Following code makes sure that if it generates same random number, it skips it. Program is actually working and i'm getting in another array randomly positioned numbers from 1 to 10. That's what i wanted. But sometimes i'm missing one number from 1 - 10 AND iam Getting ZERO instead. Why??
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
int[] usednum = new int[10];
Random rand = new Random();
int randNum;
int min = 1;
for (int x = 0; x<numbers.length; x++) {
for (int i = 0; i<usednum.length; i++) {
randNum = rand.nextInt(numbers.length-min+1) + min;
for (int f = 0; f<usednum.length; f++) {
if (usednum[f] == randNum) {
break;
} else if (usednum[f] == 0) {
usednum[x] = randNum;
}
}
}
}
for (int c = 0; c<usednum.length; c++) {
System.out.println(usednum[c]);
}
You're inner-most for loop only checks if the current random number is in the usednum[] array. And the for loop immediately outer of that only checks 10 times total. It gives up too quickly because it only tries 10 random numbers. If all 10 are already used, nothing will get stored in that slot of usednum[] (thus it will be 0), try adding a while loop around that and get rid of the extraneous outer-most for loop:
for(int i = 0; i<usednum.length; i++) {
while(usednum[i]==0) {
randNum = rand.nextInt(numbers.length-min+1)+min;
for(int f = 0; f<usednum.length; f++) {
if(usednum[f] == randNum) {
break;
} //if
else if (usednum[f] == 0) {
usednum[i] = randNum;
}
}
}
}
Also note that the assignment is for usednum[i] = randNum;.
This is essentially replacing the middle for loop (the one that goes from i=0 to 9) with the while loop.
If your goal is simply to shuffle an array of numbers, try this instead:
Integer[] numbers = {1,2,3,4,5,6,7,8,9,10};
Collections.shuffle(Arrays.asList(numbers));
It will have the same effect. Unless you are completing a homework assignment that forces you to solve the issue in a more manual fashion, just make use of the standard Java libraries.
The shuffle method writes changes through to the underlying Integer array, thanks to the special type of List returned by Arrays.asList(...). Note you have to use an array of Integer not int (see Why does Collections.shuffle() fail for my array?).
You are generating used numbers through an entire pass, so it doesn't generate a zero is just fails to generate a value it should.
you have one for loop too much.
remove the loop with the i iterator and the program should do what you want.
Oh and remove the -min+1 from the random generator, -1+1=0
Your array usednum is consisted of zeros at the beginning. In some cases, your program doesn't change that initial value, but breaks before at the line:
if(usednum[f] == randNum)
and does that during all iterations with same value x. X increments and there goes your chance to change the zero value.
Edit - followed it and re-wrote it:
List<Integer> numbers = new LinkedList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }));
int[] usednum = new int[10];
Random rand = new Random();
int n = numbers.size();
for (int i = 0; i < n; i++) {
int randNum = rand.nextInt(numbers.size());
usednum[i]=numbers.get(randNum);
numbers.remove(randNum);
}
for (int c:usednum) {
System.out.println(c);
}
Actually, you are never using the content of the array numbers. Try changing the array to something like int[] numbers = { 10, 22, 23, 42, 53, 18, 7, 8, 93, 10 };. You will get similar output.
Jon Lin's answer describe why your code is not working but does not address this issue. I think you will want to change your code to something like:
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] usednum = new int[10];
Random rand = new Random();
int selectedCount = 0;
while (selectedCount < numbers.length) {
int randNum = numbers[rand.nextInt(numbers.length)];
boolean contains = false;
for (int x = 0; x < selectedCount; x++) {
if (usednum[x] == randNum) {
contains = true;
break;
}
}
if (!contains) {
usednum[selectedCount] = randNum;
selectedCount++;
}
}
for (int c = 0; c < usednum.length; c++) {
System.out.println(usednum[c]);
}

Categories

Resources