Trouble with asList().contains() comparing variables - java

I'm making an app where the user has to choose a 4 digit number, and this will be compared to a randomly chosen hidden 4 digit number, but when ever I run the code which should check my array for a comparison between the chosen numbers and the random numbers the 'Arrays.asList().contains())' doesn't seem to pickup on the fact that the array it is checking does have the value it is checking for, any advice?
The code that compares the two variables:-
guess.v1 = code.int1;
guess.v2 = code.int2;
guess.v3 = code.int3;
guess.v4 = code.int4;
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
if (Arrays.asList(guess_list).contains(home.value1)) {
if (code.int1 == home.value1) {
X1.setText("V");
guess.c1 = GuessStatus.V;
} else {
X1.setText("S");
guess.c1 = GuessStatus.S;
}
} else {
X1.setText("X");
guess.c1 = GuessStatus.X;
}
The code that generates the random numbers:-
Code.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent openCode = new Intent(b, code.class);
// adventure_time checks whether there is a saved game already,
// if 1, saved game,
adventure_time = 0;
// random number generation LET THE NUMBER GAMES BEGIN///
Random a1 = new Random();
random1 = new ArrayList<Integer>();
check.fudge = 0;
for (int index = 0; index < 4; index++) {
random1.add(a1.nextInt(5) + 1);
Log.v("MM", "" + random1.get(index));
}
value1 = random1.get(0);
value2 = random1.get(1);
value3 = random1.get(2);
value4 = random1.get(3);
startActivity(openCode);
}
});

You're not calling the Arrays.asList call you think you are. You're actually creating a List<int[]>, not a List<Integer> are you're probably expecting. (There's no such type as List<int> in Java, as it doesn't support generics over primitive types.)
The simplest fix would be to change this:
int[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
to this:
Integer[] guess_list = { guess.v1, guess.v2, guess.v3, guess.v4 };
You'll then end up creating a List<Integer> which will work appropriately.

Related

Using a Method to update a 2D Array by finding a matching value and then updating with a different input variable

Lets say I have a public class called GameBoard that will be a two dimensional array with 4 rows and 5 columns. The spaces in the array are filed with String values from 1 to 20. A card will be drawn that has a name (King of Spades for example) . If the user inputs 15 I will store it in a String variable called userLocation. What would be the most efficient way to create a method that takes the input location and updates the array with the name of the Card? Would a for loop be most efficient?
public GameBoard() {
square = new String[4][5];
square[0][0] = new String("1");
square[0][1] = new String("2");
square[0][2] = new String("3");
square[0][3] = new String("4");
square[0][4] = new String("5");
square[1][0] = new String("6");
square[1][1] = new String("7");
square[1][2] = new String("8");
square[1][3] = new String("9");
square[1][4] = new String("10");
square[2][1] = new String("11");
square[2][2] = new String("12");
square[2][3] = new String("13");
square[3][1] = new String("14");
square[3][2] = new String("15");
square[3][3] = new String("16");
square[2][0] = new String(17);
square[3][0] = new String(18);
square[2][4] = new String(19);
square[3][4] = new String(20);
}
My preferred method as of now would look something like this but it gives me the error code "type mismatch:cannot convert string to boolean" under userLocation = board[i][j]
public String[][] updateBoard(String userLocation, Card card, String[][] board) {
for (int i = 0; i <4; i++)
{
for (int j = 0; j < 5; j++)
{
if(userLocation = board[i][j]) {
board[i][j] = card.name;
}
}
}
return board;
}
So the reason it will not compile is your = does not return a boolean expression. == would, but it's still not what you want, since you want to check if the String contents are the same, not if they're the same object, so use .equals.
But, no, I think you don't want to depend on strings to identify locations. What if you want to replace a card? And why look through everything when you need not?
Rather if i is some number between 1 and 20, identify the corresponding spot in the array by square[(i-1)/5][(i-1)%5]
That should bypass the issue you are having with matching strings.
So for example, your constructor becomes:
public GameBoard() {
square = new String[4][5];
for (int i=1; i<=20;i++){
square[(i-1)/5][(i-1)%5]=""+i;//initialize with 1 to 20 if you like
}
and userLocation is an int.

Need Help sorting out nested for loops

I'm trying to make a trivia game for my English class that will randomly pick a question, but will not pick the same one twice. I currently have a prototype set up, but I can't figure out what is going wrong that is preventing it from actually printing the questions.
Here's the behemoth:
import java.io.*;
import java.util.*;
public class qpicker
{
public static void main (String args[])
{
int qs = 0;
boolean q1checker, q2checker, q3checker, q4checker, q5checker,
q6checker, q7checker, q8checker, q9checker, q10checker, q11checker,
q12checker,q13checker, q14checker, q15checker, q16checker, q17checker,
q18checker, q19checker, q20checker; //this disaster is where i declared my
q1checker = false; //booleans
q2checker = false;
q3checker = false;
q4checker = false;
q5checker = false;
q6checker = false;
q7checker = false;
q8checker = false;
q9checker = false;
q10checker = false;
q1checker = false;
q12checker = false;
q13checker = false;
q14checker = false;
q15checker = false;
q16checker = false;
q17checker = false;
q18checker = false;
q19checker = false;
q20checker = false; //here i tried to set all booleans to false,
//thinking maybe that was the issue
do
{
qs++;
Random random = new Random();
double rng = random.nextDouble();
double selecter = rng * 10;//makes the random number easier to read
if(rng <=.5)
{
if(q1checker = false)
{
System.out.println("Put first q in here");
q1checker = true;
break;
}
}
System.out.print("cheese");//code progress tracker
if(rng <=1 && rng >.5)//this is where the question would be pulled
{
if(q2checker = false)//this ensures questions aren't repeated
{
System.out.println("Put second q in here");//display quest.
q2checker = true;
break;
}
}
System.out.print("e");
if(rng <=1.5 && rng > 1)//question picked
{
if(q3checker = false)//ensures questions aren't repeated
{
System.out.println("Put third q in here");//display quest.
q3checker = true;
break;
}
}
System.out.print("y");
if(rng <=2 && rng > 1.5 )
{
if(q4checker = false)
{
System.out.println("Put fourth q in here");
q4checker = true;
break;
}
else if (q4checker = true)
{continue;}
System.out.print(" ");
}if(rng <=2.5 && rng > 2)
{
if(q5checker = false)
{
System.out.println("Put fifth q in here");
q5checker = true;
break;
}
}
System.out.print("good");
if(rng <=3 && rng > 2.5)
{
if(q6checker = false)
{
System.out.println("Put sixth q in here");
q6checker = true;
break;
}
}
System.out.print("ness");//spells out "cheesey goodness" 20 times
}while (qs < 20);//ensures all questions are printed (in final product)
}
}
static void shuffleArray(string[] ar)
{
//set the seed for the random variable
Random rnd = ThreadLocalRandom.current();
//go from the last element to the first one.
for (int i = ar.size()- 1; i > 0; i--)
{
//get a random number till the current position and simply swap elements
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
This way you shuffle the entire array and get the values in a random order but NO duplicate at all. Every single element changes position, so that no matter what element (position) you pick, you get a country from a random position. You can return the entire vector, the positions are random.
You could try this method, for shuffling your array and returning the entire array in random order since it mixes the elements.
From what I see you are trying to allow them to choose questions until they are exhausted, choosing randomly. You can do this easily with an ArrayList, where you pick randomly an index from the list to pull your question, remove the question from your list, so it is no longer available to choose from. Note that after you remove and use it from the list, the list will be smaller by 1
String[] questionArray = ["Question 1","Question 2","Question 3","Question 4","Question 5"];
ArrayList<String> questionList = Arrays.asList(questionArray);
//Get a random number within the range of 0..questionList.size()
int chosenIndex = 1; //Made up for simplicity
String chosen = questionList.remove(chosenIndex);
//Now that you have chosen a question, and it was removed from the list
//The list is one element smaller. Next time you get a random number
//make sure you use the range: 0..chosen.size()
System.out.println(chosen);
I believe this is what you are looking for.
You should use arrays.
Also remember that = is an assignment operator while == is comparation
This:
if(rng <=.5)
{
if(q1checker = false)
Is wrong, it should be:
if(rng <=.5)
{
if(q1checker == false)
Or better:
if(rng <=.5)
{
if(!q1checker)

Java: sort 1d array of objects by full or not

I'm trying to compress an array of objects that will have empty items interspersed with complete items. I want to put all the full elements at the start in the same order they started with, and the empty elements on the end.
The object in question uses a String field, "name", and an int field, "weight". An empty version has "no name" and 0 respectively. So an array of the type the method needs to deal with will contain something like:
Fred | 4
Bob | 3
no name | 0
Gina | 9
no name | 0
Yuki | 7
After feeding through the method, the array should go Fred, Bob, Gina, Yuki, no name, no name.
My thought for step one was to just figure out which were full and which weren't, so I came up with this:
public void consolidate() {
boolean[] fullSlots = new boolean[spaces.length];
// pass 1: find empties
for (int i = 0; i < spaces.length; i++) {
fullSlots[i] = spaces[i].getName().equals("no name");
}
}
spaces is the array of objects, getName() retrieves the name field from the object.
I'm not sure where to go from here. Suggestions?
EDIT: Okay, here's what Infested came up with:
public void consolidate()
{
int numberOfEmpties = 0, spacesLength = spaces.length;
Chicken[] spaces2 = new Chicken[spacesLength];
for(int i = 0; i < spaces.length; i++)
{
spaces2[i] = new Chicken(spaces[i].getName(),
spaces[i].getWeight());
}
// pass 1: find empties
for (int i = 0, j = 0; i < spacesLength; i++)
{
if (spaces2[i].getName().equals("no name") == false)
{
spaces[j] = new Chicken(spaces2[i].getName(),
spaces2[i].getWeight());
j++;
}
else
{
numberOfEmpties++;
}
}
for (int i = spacesLength - 1; numberOfEmpties > 0 ; numberOfEmpties--, i--)
{
spaces[i] = new Chicken("no name", 0);
}
}
Tested and working.
Java's Arrays.sort is stable, meaning that the relative order of equal elements is not going to change.
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
You can use this property of the sorting algorithm to sort all your elements with a simple comparator:
Arrays.sort(
spaces
, new Comparator() {
public int compare(Object o1, Object o2) {
MyClass a = (MyClass)o1;
MyClass b = (MyClass)o2;
boolean aIsEmpty = "no name".equals(a.getName());
boolean bIsEmpty = "no name".equals(b.getName());
if (aIsEmpty && !bIsEmpty) {
return 1;
}
if (!aIsEmpty && bIsEmpty) {
return -1;
}
return 0;
}
}
);
This will sort all items with non-empty names ahead of the items with empty names, leaving the relative order of both groups of objects unchanged within their respective group.
If your space constraints allow you to create a new array of MyClass, you can go for a simpler algorithm: go through the original array once, and make a count of non-empty items. Then create a new array, and make two indexes: idxNonEmpty = 0, and idxEmpty = NonEmptyCount+1. Then go through the original array one more time, writing non-empty objects to idxNonEmpty++, and empty objects to idxEmpty++.
ill assume its a method of the class:
public void consolidate()
{
int lengthOfSpaces = spaces.length , i, numberOfEmpties = 0;
Type[] spacesNumberTwo = new Type[lengthOfSpaces ];
// pass 1: find empties
for (i = 0; i < lengthOfSpaces ; i++)
{
if(spaces[i].getName().equals("no name") == false)
spacesNumberTwo[i] = new Type(spaces[i].getName(), spaces[i].getInt());
else
numberOfEmpties++;
}
for (i = lengthOfSpaces - 1; numberOfEmpties > 0 ; numberOfEmpties--, i--)
{
spacesNumberTwo[i] = new Type("no name", 0);
}
spaces = spacesNumberTwo
}

Java array sorting in reverse! Need to reverse the reverse

Right now I have my array sorting (which is better than getting an error) except it is sorting in the reverse than what I want it to sort in.
public static void sortDatabase(int numRecords, String[] sDeptArr,
int[] iCourseNumArr, int[] iEnrollmentArr)
{
System.out.println("\nSort the database. \n");
String sTemp = null;
int iTemp = 0;
int eTemp = 0;
String a, b = null;
for(int i=0; i<numRecords; i++)
{
int iPosMin = i+1;
for(int j=iPosMin; j<numRecords; j++)
{
a = sDeptArr[i];
b = sDeptArr[iPosMin];
if(a.compareTo(b) > 0)
{
sTemp= sDeptArr[j];
sDeptArr[j] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[j];
iCourseNumArr[j] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[j];
iEnrollmentArr[j] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else if(sDeptArr[j].equals(sDeptArr[iPosMin]) && !(iCourseNumArr[j] < iCourseNumArr[iPosMin]))
{
sTemp= sDeptArr[i];
sDeptArr[i] = sDeptArr[iPosMin];
sDeptArr[iPosMin] = sTemp;
iTemp = iCourseNumArr[i];
iCourseNumArr[i] = iCourseNumArr[iPosMin];
iCourseNumArr[iPosMin] = iTemp;
eTemp = iEnrollmentArr[i];
iEnrollmentArr[i] = iEnrollmentArr[iPosMin];
iEnrollmentArr[iPosMin] = eTemp;
}
else continue;
}
}
}
Again, no array lists or array.sorts. I need just to reverse how this is sorting but I have no idea how.
just do a.compareTo(b) < 0 instead of the > 0
EDIT: I've figured out the problem. But since this is homework (thanks for being honest), I won't post my solution, but here are a few tips:
You are doing selection sort. The algorithm isn't as complicated as you made it. You only have to swap if the two elements you are checking are in the wrong order. I see you have 3 branches there, no need.
Take a look at when you are assigning a and b. Through the inner loop, where j is changing, a and b never change, because i and iPosMin stay the same. I hope that helps.
It's always good to break your algorithm down to discreet parts that you know works by extracting methods. You repeat the same swap code twice, but with different arguments for indices. Take that out and just make a:
-
// swaps the object at position i with position j in all arrays
private static void swap(String[] sDeptArr, int[] iCourseNumArr, int[] iEnrollmentArr, int i, int j)
Then you'll see you're code get a lot cleaner.
First I'd say you need to build a data structure to encapsulate the information in your program. So let's call it Course.
public class Course {
public String department;
public Integer courseNumber;
public Integer enrollment;
}
Why not use the built in sort capabilities of Java?
List<Course> someArray = new ArrayList<Course>();
...
Collections.sort( someArray, new Comparator<Course>() {
public int compare( Course c1, Course c2 ) {
int r = c1.compareTo( c2 );
if( r == 0 ) { /* the strings are the same sort by something else */
/* using Integer instead of int allows us
* to compare the two numbers as objects since Integer implement Comparable
*/
r = c1.courseNumber.compareTo( c2.courseNumber );
}
return r;
}
});
Hope that gets you an A on your homework. Oh and ditch the static Jr. Maybe one day your prof can go over why statics are poor form.
Hmm... I wonder what would happen of you altered the line that reads if(a.compareTo(b) > 0)?

getting duplicate array output - java

Can someone could be kind and help me out here. Thanks in advance...
My code below outputs the string as duplicates. I don't want to use Sets or ArrayList. I am using java.util.Random. I am trying to write a code that checks if string has already been randomly outputted and if it does, then it won't display. Where I am going wrong and how do I fix this.
public class Worldcountries
{
private static Random nums = new Random();
private static String[] countries =
{
"America", "Candada", "Chile", "Argentina"
};
public static int Dice()
{
return (generator.nums.nextInt(6) + 1);
}
public String randomCounties()
{
String aTemp = " ";
int numOfTimes = Dice();
int dup = 0;
for(int i=0 ; i<numOfTimes; i++)
{
// I think it's in the if statement where I am going wrong.
if (!countries[i].equals(countries[i]))
{
i = i + 1;
}
else
{
dup--;
}
// and maybe here
aTemp = aTemp + countries[nums.nextInt(countries.length)];
aTemp = aTemp + ",";
}
return aTemp;
}
}
So the output I am getting (randomly) is, "America, America, Chile" when it should be "America, Chile".
When do you expect this to be false?
countries[i].equals(countries[i])
Edit:
Here's a skeleton solution. I'll leave filling in the helper methods to you.
public String[] countries;
public boolean contains(String[] arr, String value) {
//return true if value is already in arr, false otherwise
}
public String chooseRandomCountry() {
//chooses a random country from countries
}
//...
int diceRoll = rollDice();
String[] selection = new String[diceRoll];
for ( int i = 0; i < selection.length; i++ ) {
while (true) {
String randomCountry = chooseRandomCountry();
if ( !contains(selection, randomCountry ) {
selection[i] = randomCountry;
break;
}
}
}
//...then build the string here
This doesn't check important things like the number of unique countries.
You need a data structure which allows you to answer the question "does it already contain item X?"
Try the collection API, for example. In your case, a good candidate is either HashSet() or LinkedHashSet() (the latter preserves the insert order).
You'd probably be better of using another structure where you save the strings you have printed. Since you don't want to use a set you could use an array instead. Something like
/*
...
*/
bool[] printed = new bool[countries.length];
for(int i=0 ; i<numOfTimes ; /*noop*/ )
{
int r = nums.nextInt(countries.length);
if (printed[r] == false)
{
i = i + 1;
printed[r] = true;
aTemp = aTemp + countries[r];
aTemp = aTemp + ",";
}
}
return aTemp;
Consider what you're comparing it to:
if (!countries[i].equals(countries[i]))
are you comparing c[i] to c[i]? or c[i] to c[i-1]? Or do you need to check the whole array for a particular string? Perhaps you need a list of countries that get output.
make list uniqueCountries
for each string called country in countries
if country is not in uniqueCountries
add country to uniqueCountries
print each country in uniqueCountries
When you do this, watch out for index out of bounds, and adjust accordingly
Much faster way to do it then using HashSets and other creepy stuff. Takes less code too:
public String randomCounties() {
List<String> results = Arrays.asList(countries);
Collections.shuffle(results);
int numOfTimes = Dice();
String result = " ";
for(int i=0 ; i<numOfTimes; i++) {
result = result + countries[i] + ", ";
}
return result;
}
If you want to avoid outputting duplicate values, you need to record what values have already been listed or remove values from the pool of possibilities when they get selected.
You mention that you do not want to use Sets or ArrayList (I assume you mean Lists in general), I assume that is a requirement of the assignment. If so, you can accomplish this by building arrays and copying data between them the same way that an ArrayList would.
one note, your current implementation chooses between 1 and 6 entries from and array of 4 entries. If you force the selections to be unique you need to decide how to handle the case when you have no more unique selections.

Categories

Resources