2 dimensional array & method calls - beginner - java

I'm currently working on a homework assignment for a beginner-level class and I need help building a program that tests if a sodoku solution presented as an int[][] is valid. I do this by creating helper methods that check both rows, columns and grids.
To check the column I call a method called getColumn that returns a column[]. When I test it out it works fine. I then pass it out on a method called uniqueEntries that makes sure that there are no duplicates.
Problem is, when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333). I have no idea why it does that. Here is my code:
int[][] sodokuColumns = new int[length][length];
for(int k = 0 ; k < sodokuPuzzle.length ; k++) {
sodokuColumns[k] = getColumn(sodokuPuzzle, k);
}
for (int l = 0; l < sodokuPuzzle.length; l++) {
if(uniqueEntries(sodokuColumns[l]) == false) {
columnStatus = false;
}
}
my helper is as follows
public static int[] getColumn(int[][] intArray, int index) {
int[] column = new int[intArray.length];
for(int i = 0 ; i < intArray.length ; i++) {
column[i] = intArray[i][index];
}
return column;
}
Thanks !

You said:
when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333).
I don't see any issue with your getColumn method other than the fact it's not even needed because getColumn(sodokuPuzzle, k) is the same as sodokuPuzzle[k]. If you're going to conceptualize your 2D array in such a way that your first index is the column then for your purpose of checking uniqueness you only need to write a method to get rows.
The issue you're having would seem to be with another part of your code that you did not share. I suspect there's a bug in the logic that accepts user input and that it's populating the puzzle incorrectly.
Lastly a tip for checking uniqueness (if you're allowed to use it) would be to create a Set of some kind (e.g. HashSet) and add all of your items (in your case integers) to that set. If the set has the same size as your original array of items then the items are all unique, if the size differs there are duplicates.

Related

Where is the Data Changing? - Permutations in Java

So for this extra credit problem in my calculus class, my other nerdy classmates and I decided that we would build a program to brute force a solution. One of these steps involves permutations. Through this algorithm, I managed to get it to work (I think):
public void genPermutations(int[] list, int k){
System.out.println("List: " + Arrays.toString(list));
System.out.println("----------------------");
if(k > list.length){
System.out.println("Not enough elements!");
return;
}
int[] counts = new int[list.length];
for(int i = 0; i < counts.length; i++){
counts[i] = 1;
}
int[] data = new int[k];
permutationHelper(list, counts, data, 0, k);
}
public void permutationHelper(int[] list, int[] counts, int[] data, int index, int k){
if(index == k){
//System.out.println(Arrays.toString(data));
permutations.add(data);
}else{
for(int i = 0; i < list.length; i++){
if(counts[i] == 0){
continue;
}
data[index] = list[i];
counts[i]--;
permutationHelper(list, counts, data, index + 1, k);
counts[i]++;
}
}
}
I have an ArrayList that stores all of the possible permutations (as integer arrays) that can be made from k elements of the list that I pass into the function. The problem is that if I print all of these permutations outside of the function, say after I call the genPermutations function, every permutation now is the same. But, when I print out the data where the comment is in the permutationHelper function, it correctly lists every possible permutation; I'm just unable to access them within the program later. My question is why are the values changing when I exit the function? Any help would be greatly appreciated.
Here are some pictures:
What is printed where the comment is.
What is printed later in the program.
The code used to print everything outside of the function is:
for(int i = 0; i < permutations.size(); i++){
System.out.println(Arrays.toString(permutations.get(i)));
}
I don't really know if that's necessary to know, but I just thought I'd include it just in case. Thanks in advance.
You're constantly modifying the same array object. Instead of adding different arrays to your list, you're in fact adding a reference to the same array over and over again.
To fix, instead of adding the data array to your list, you would have to add a copy of it, e.g. using Arrays.copyOf():
permutations.add(Arrays.copyOf(data, data.length));
Here the problem is that you are modifying the array after adding it to the list, you are modifying the same object again and again in different iterations. You were getting [3,2,1] in the list is because that was the outcome from last iteration. So as a fix you can use the following code. What it does is it will create a copy of data array and add that to the list.
int[] temp = Arrays.copyOf(data, data.length);
permutations.add(temp);
OR you can use clone() from array as follows.
int[] temp = data.clone();
permutations.add(temp);

Java - Improper Checking in For Loop

This is a chunk of code in Java, I'm trying to output random numbers from the tasks array, and to make sure none of the outputs are repeated, I put them through some other loops (say you have the sixth, randomly-chosen task "task[5]"; it goes through the for loop that will check it against every "tCheck" element, and while task[5] equals one of the tCheck elements, it will keep trying to find another option before going back to the start of the checking forloop... The tCheck[i] elements are changed at the end of each overall loop of output to the new random number settled on for the task element).
THE PROBLEM is that, despite supposedly checking each new random task against all tCheck elements, sometimes (not always) there are repeated tasks output (meaning, instead of putting out say 2,3,6,1,8,7,5,4, it will output something like 2,3,2,1,8,7,5,4, where "2" is repeated... NOT always in the same place, meaning it can sometimes end up like this, too, where "4" is repeated: 3,1,4,5,4,6,7,8)
int num = console.nextInt();
String[] tasks = {"1","2","3","4","5","6","7","8"};
String[] tCheck = {"","","","","","","",""};
for(int i = 0; i<= (num-1); i++){
int tNum = rand.nextInt(8);
for(int j = 0; j <=7; j++){
if(tasks[tNum].equals(tCheck[j])){
while(tasks[tNum].equals(tCheck[j])){
tNum = rand.nextInt(8);
}
j = 0;
}
}
tCheck[i] = tasks[tNum];
System.out.println(tasks[tNum]+" & "+tCheck[i]);
}
None of the other chunks of code affect this part (other than setting up Random int's, Scanners, so on; those are all done correctly). I just want it to print out each number randomly and only once. to never have any repeats. How do I make it do that?
Thanks in advance.
Firstly, don't use arrays. Use collections - they are way more programmer friendly.
Secondly, use the JDK's API to implement this idea:
randomise the order of your elements
then iterate over them linearly
In code:
List<String> tasks = Arrays.asList("1","2","3","4","5","6","7","8");
Collections.shuffle(tasks);
tasks.forEach(System.out::println);
Job done.
you can check if a certain value is inside your array with this approach.
for(int i = 0; i<= (num-1); i++){
int tNum = rand.nextInt(8);
boolean exist = Arrays.asList(tasks).contains(tNum);
while(!exist){
//your code
int tNum = rand.nextInt(8);
exist = Arrays.asList(tasks).contains(tNum);
}
}
if you are using an arraylist then you can check it with contains method since you are using an array we have to get the list from the array using asList() and then use the contains method. with the help of the while loop it will keep generating random numbers untill it generates a non duplicate value.
I used to created something similar using an ArrayList
public class Main {
public static void main(String[] args) {
String[] array = { "a", "b", "c", "d", "e" };
List<String> l = new ArrayList<String>(Arrays.asList(array));
Random r = new Random();
while(!l.isEmpty()){
String s = l.remove(r.nextInt(l.size()));
System.out.println(s);
}
}
}
I remove a random position in the list until it's empty. I don't use any check of content. I believe that is kind of effective (Even if I create a list)

ArrayLinkedList Insertion Sort

I have to do an Array List for an insertion sort and my teacher sent this back to me and gave me an F, but says I can make it up before Friday.
I do not understand why this isn't an A.L insertion sort.
Can someone help me fix this so it hits his criteria?
Thanks.
HE SAID:
After checking your first insertion sort you all did it incorrectly. I specifically said to shift the numbers and move the number into its proper place and NOT SWAP THE NUMBER INTO PLACE. In the assignment in MySA I said if you do this you will get a 0 for the assignment.
import java.util.ArrayList;
public class AListINSSORT {
private static void insertionSort(ArrayList<Integer> arr) {
insertionSort();
}
private static void insertionSort() {
ArrayList<Integer> swap = new ArrayList<Integer>();
swap.add(1);
swap.add(2);
swap.add(3);
swap.add(4);
swap.add(5);
int prior = 0;
int latter = 0;
for (int i = 2; i <= latter; i++)
{
for (int k = i; k > prior && (swap.get(k - 1) < swap.get(k - 2)); k--)
{
Integer temp = swap.get(k - 2);
swap.set(k - 2, swap.get(k - 1));
swap.set(k - 1, temp);
}
}
System.out.println(swap);
}
}
First of all, it seems your teacher asked you to use a LinkedList instead of an ArrayList. There is quite a difference between them.
Secondly, and maybe more to the point. In your inner loop you are saving a temp variable and swapping the elements at position k - 2 and k - 1 with each other. From the commentary this is not what your teacher intended. Since he wants you to solve the problem with element insertion, I recommend you look at the following method definition of LinkedList.add(int i, E e): https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#add(int,%20E).
This should point you in the right direction.
As far as I see, your code does nothing at all.
The condition of the outer for loop
for (int i = 2; i <= latter; i++)
is not fulfilled.
As you start with i = 2 and as latter = 0, it never holds i <= latter.
Thus, you never run through the outer for loop and finally just give back the input values.
If you add the input values to swap in a different order (not already ordered), you will see that your code does not re-order them.
There's a lot of stuff wrong here.
Firstly, your method:
private static void insertionSort(ArrayList<Integer> arr) {
insertionSort();
}
takes an ArrayList and completely ignores it. This should presumably be the List which requires sorting.
Then in insertionSort() you create a new ArrayList, insert some numbers already in order, and then attempt something which looks nothing like insertion sort, but slightly more like bubble sort.
So, when you call insertionSort(List) it won't actually do anything to the list at all, all the work in insertionSort() happens to a completely different List!
Since on SO we don't generally do people's homework for them, I suggest looking at the nice little animated diagram on this page
What you should have then is something like:
public void insertionSort(LinkedList<Integer> numbers) {
//do stuff with numbers, using get() and add()
}

List.add() Class Expected

I'm taking a Java class in College. My instructor is actually a teacher for languages derived from C, so she can't figure out what's going on with this piece of code. I read on this page http://docs.oracle.com/javase/6/docs/api/java/util/List.html that I could use the syntax "list[].add(int index, element)" to add specific objects or calculations into specific indexes, which reduced the amount of coding needed. The program I'm looking to create is a random stat generator for D&D, for practice. The method giving the error is below:
//StatGenrator is used with ActionListener
private String StatGenerator ()
{
int finalStat;
String returnStat;
//Creates an empty list.
int[] nums={};
//Adds a random number from 1-6 to each list element.
for (int i; i > 4; i++)
nums[].add(i, dice.random(6)+1); //Marks 'add' with "error: class expected"
//Sorts the list by decending order, then drops the
//lowest number by adding the three highest numbers
//in the list.
Arrays.sort(nums);
finalStat = nums[1] + nums[2] + nums[3];
//Converts the integer into a string to set into a
//texbox.
returnStat = finalStat.toString();
return returnStat;
}
My end goal is to use some kind of sorted list or method of removing the lowest value in a set. The point of this method is to generate 4 random numbers from 1-6, then drop the lowest and add the three highest together. The final number is going to be the text of a textbox, so it is converted to a string and returned. The remainder of the code works correctly, I am only having trouble with this method.
If anyone has any ideas, I'm all ears. I've researched a bit and found something about using ArrayList to make a new List object, but I'm not sure on the syntax for it. As a final note, I tried looking for this syntax in another question, but I couldn't find it anywhere on stackoverflow. Apologies if I missed something, somewhere.
'int nums[]' is not a List, it's an array.
List<Integer> intList = new ArrayList<>();
creates a new ArrayList for example.
You can access Elements in the list directly with the following Syntax :
intList.get(0); // Get the first Element
You can sort Lists with the Collections class :
Collections.sort(intList);
Here are some informations about Collections in Java : http://docs.oracle.com/javase/tutorial/collections/
Arrays are fixed size, so you need to allocate space for all the slots at the start. Then to put numbers into the array assign to nums[i]. No add() method needed.
int[] nums = new int[4];
for (int i = 0; i < 4; i++)
nums[i] = dice.random(6) + 1;
Arrays.sort(nums);
finalStat = nums[1] + nums[2] + nums[3];
Alternatively, if you really want a dynamically-sized array, use an ArrayList. An ArrayList can grow and shrink.
List<Integer> nums = new ArrayList<Integer>();
for (int i = 0; i < 4; i++)
nums.add(dice.random(6) + 1);
Collections.sort(nums);
finalStat = nums.get(1) + nums.get(2) + nums.get(3);
Notice how different the syntax is due to ArrayList being a class rather than a built-in type.
nums[].add(i, dice.random(6)+1); //Marks 'add' with "error: class
expected"
You are trying to use add on an array. List is a dynamic array, but that doesn't mean that array == List. you should use List instead.
List<Integer> nums=new ArrayList<Integer>();
//Adds a random number from 1-6 to each list element.
for (int i; i > 4; i++)
nums.add(i, dice.random(6)+1);
You're mixing arrays and lists.
Have a look at the tutorial:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
http://docs.oracle.com/javase/tutorial/collections/index.html

ArrayList of integer arrays

I'm trying to write a simple game where an enemy chases the player on a grid. I'm using the simple algorithm for pathfinding from the Wikipedia page on pathfinding. This involves creating two lists with each list item containing 3 integers. Here's test code I'm trying out to build and display such a list.
When I run the following code, it prints out the same numbers for each array in the ArrayList. Why does it do this?
public class ListTest {
public static void main(String[] args) {
ArrayList<Integer[]> list = new ArrayList<Integer[]>();
Integer[] point = new Integer[3];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//Added this line to confirm that Integer[] point is actually
//being filled with 3 random ints.
System.out.println(point[0] + "," + point[1] + "," + point[2]);
}
System.out.println();
//My current understanding is that this section should step through
//ArrayList list and retrieve each Integer[] point added above. It runs, but only
//the values of the last Integer[] point from above are displayed 10 times.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
}
First of all, several of the other answers are misleading and/or incorrect. Note that an array is an object. So you can use them as elements in a list, no matter whether the arrays themselves contain primitive types or object references.
Next, declaring a variable as List<int[]> list is preferred over declaring it as ArrayList<int[]>. This allows you to easily change the List to a LinkedList or some other implementation without breaking the rest of your code because it is guaranteed to use only methods available in the List interface. For more information, you should research "programming to the interface."
Now to answer your real question, which was only added as a comment. Let's look at a few lines of your code:
Integer[] point = new Integer[3];
This line creates an array of Integers, obviously.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//...
}
Here you assign values to the elements of the array and then add a reference to the array to your List. Each time the loop iterates, you assign new values to the same array and add another reference to the same array to the List. This means that the List has 10 references to the same array which has been repeatedly written over.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
Now this loop prints out the same array 10 times. The values in the array are the last ones set at the end of the previous loop.
To fix the problem, you simply need to be sure to create 10 different arrays.
One last issue: If you declare it as Iterator<Integer[]> it (or Iterator<int[]> it), you do not need to cast the return value of it.next(). In fact this is preferred because it is type-safe.
Finally, I want to ask what the ints in each array represent? You might want to revisit your program design and create a class that holds these three ints, either as an array or as three member variables.
I would highly recommend to enclose the integer array of 3 numbers into a meaningful class, that would hold, display and control an array of 3 integers.
Then in your main, you can have an growing ArrayList of objects of that class.
You have an extra ) here:
element = (int[])it.next()); //with the extra parenthesis the code will not compile
should be:
element = (int[])it.next();
Besides the problem in the other answer, you cal it.next() two times, that cause the iterator move forward two times, obviously that's not what you want. The code like this:
element = (int[])it.next());
String el = (String)element;
But actually, I don't see you used el. Although it's legal, it seems meaningless.

Categories