I am pretty new to Java and had a question. This is homework, so I would not like any outright answers. Thanks!
I'm working on a genetic algorithm for playing poker. I wanted to create an arrayList of string arrays. The string arrays would hold moves for each possible hand during a round. What I want to do right now to make sure it is working is run my method and print out the results. Here are my practice classes (this is only a small part of the assignment):::
import java.util.ArrayList;
import java.util.Arrays;
public class Play
{
GeneticAlg start;
ArrayList<Object> pop;
public static void main(String[] args)
{
GeneticAlg start = new GeneticAlg();
ArrayList<String[]> pop = start.initializePopulation();
for(String[] arr: pop)
{
System.out.println(Arrays.toString(arr));
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class GeneticAlg
{
ArrayList<String[]> population;
int[] populationScores;
String[] chromosome;
int generation;
int index;
public GeneticAlg()
{
}
public ArrayList<String[]> initializePopulation()
{
ArrayList<String[]> population = new ArrayList<String[]>();
for (int i = 0; i < 20; i++)
{
Random generator = new Random();
String[] choices = {"bet","raise","call","check"};
chromosome = new String[33];
for (int j = 0; j < 33; j++)
{
if (j < 6) //first and second round possible hands)
{
index = generator.nextInt((choices.length)-1);
chromosome[j] += choices[index];
}
else //third, fourth, and fifth round possible hands)
{
index = generator.nextInt(choices.length);
chromosome[j] += choices[index];
}
}
population.add(chromosome);
}
return population;
}
}
Right now, it's printing out the array, but each entry looks like this:
[nullcall, nullraise, nullbet, nullraise, nullcall, nullraise,....
I want it to just return the move without null on the front. Any advice is appreciated. Thanks!
ETA: I fixed the two lines with the concatenation error, but it is still printing "null" in front of each command. Any advice?
Code after repairing the error:
import java.util.ArrayList;
import java.util.Arrays;
public class Play
{
GeneticAlg start;
ArrayList<Object> pop;
public static void main(String[] args)
{
GeneticAlg start = new GeneticAlg();
ArrayList<String[]> pop = start.initializePopulation();
for(String[] arr: pop)
{
System.out.println(Arrays.toString(arr));
}
}
}
import java.util.ArrayList;
import java.util.Random;
public class GeneticAlg
{
ArrayList<Object> population;
String[] choices;
int[] populationScores;
String[] chromosome;
int generation;
int index;
public GeneticAlg()
{
}
public ArrayList<Object> initializePopulation()
{
population = new ArrayList<Object>();
for (int i = 0; i < 20; i++)
{
Random generator = new Random();
for (int j = 0; j < 24; j++)
{
if (j < 6) //first and second round possible hands)
{
choices[0]= "bet";
choices[1]= "raise";
choices[3]= "call";
index = generator.nextInt(choices.length);
chromosome[j] = choices[index];
}
else //third, fourth, and fifth round possible hands)
{
choices[4] = "check";
index = generator.nextInt(choices.length);
chromosome[j] = choices[index];
}
}
population.add(chromosome);
}
return population;
}
}
Arrays of objects (like Stirngs) are filled at start with null values, so doing
chromosome[j] += choices[index];
is the same as
chromosome[j] = chromosome[j] + choices[index];
which is the same as
chromosome[j] = null + choices[index];
So you are concatenating null with choices[index]; which gives you nullbet for instance.
To solve it just use = instead of +=.
Since you don't want an outright answer, look at the code that populates your String[]'s. Your printing's doing the right thing, but the Strings in the array actually are "nullbet," "nullraise," etc.
The error comes from this line here:
chromosome[j] += choices[index];
The += operator, when used with a Strings, will concatenate the right-hand string to the end of the left-hand string. In this case, it tacks on choices[index] to the existing contents of chromosome[j], which will null by default if chromosome is declared as an array of Objects.
You probably meant
chromosome[j] = choices[index];
And accidentally inserted the + because you use population.add() with your list below.
Your "fixed" code looks like it doesn't compile - you're probably still running the previous version. You don't initialize choices ("choices = new String[4]") and you're confusing its indices (0, 1, 3 and 4). Also, if you're trying to add a fourth element to the array later, don't, you can't do that with arrays. And you're assigning an ArrayList to an ArrayList without a cast. You only needed to swap += with = in your original code, it seemed fine otherwise.
Related
Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));
So for an assignment in my class, we have a lab where we have to write code that will do three things:
generate an array of 50 random numbers from 0-9.
Return how many 8's appear in the array.
Return the number of runs in the array.
We were given a .java file to start out with that is this:
package ArrayOfInts;
public class ArrayOfInts {
private int [] intArray;
private int eights;
private int runs;
//Sets intArray to the parameter and initializes all other variables
public ArrayOfInts(int [] x){
}
//Returns how many 8's are in the array.
public int findTheEights(){
return eights;
}
//Returns the number of runs in the array.
public int countTheRuns(){
return runs;
}
}
The code I've written so far is this:
package ArrayOfInts;
public class ArrayOfIntsTester {
public static void main(String [] args){
int [] testArray = new int [50];
for(int i = 0; i < testArray.length; i++){
int x = (int)(Math.random()*9);
testArray[i]= x;
System.out.print(x + ", ");
}
System.out.println();
ArrayOfInts test = new ArrayOfInts(testArray);
System.out.println(test.findTheEights());
System.out.println(test.countTheRuns());
}
}
I honestly have no idea where to start with this. Help?? The code I've written generates the correct type of array, but I don't know how to count what I need to count for it.
For the eights: iterate over the array and do eights++ everytime you find an eight.
if (testArray[i] == 8){
eights++
}
Here is some pseudo code to help you count the eights:
numberOfEights = 0;
for each element in testArray{
if (element equals 8) {
numberOfEights = nnumberOfEight + 1
} else {
nothing to do
}
}
return numberOfEights
Try to turn this to java code.
For the other part, i don't understand what is your runs.
//To count number of eights, iterate through array with a counter and increment it when we see an 8
public ArrayOfInts(int [] x){
eights = 0; //reset our count
for (int currentInt : intArray)
{
if (currentInt == 8)
eights++;
}
//Process runs here
}
To count the number of eight just use another variable which is initialized to 0 , like this :-
int c=0;
for (i=0;i<testArray.length;i++)
{
if (testArray[i] == 8)
{
c++;
}
}
Now your c has the number of 8's present in your array you cant print its value.
--> If that's what you are trying to ask
first initialize the array in constructor
public ArrayOfInts(int [] x){
intArray=x;
}
initialize the eights to 0
private int eights=0;
then update your count method
public int findTheEights(){
for(int current:intArray)
{
if(current==8){ eights++;}
}
return eights;
}
In JavaScript you could do it like the following example.
Counting of eights can be done directly at the initializaion of the array.
And if I understand you right, you'd like to count the instances of the object with the countTheRuns(). That can be done with a class variable.
If you'd like to play with the code, you'll find it here at jsFiddle.
/*So for an assignment in my class, we have a lab where we have to write code that will do three things:
generate an array of 50 random numbers from 0-9.
Return how many 8's appear in the array.
Return the number of runs in the array.
*/
(function() {
var MAX_RANDOM = 50;
var NUM_RANGE = 9; // 0 to 9
function ArrayOfInts() {
this.eights = 0;
this.numbers = [];
this.init();
// class variabe run_counter
ArrayOfInts.run_counter = (ArrayOfInts.run_counter || 0) +1;
this.getNumbers = function() {
return this.numbers;
};
this.getEights = function() {
return this.eights;
};
}
ArrayOfInts.prototype.init = function() {
for (var i=0; i< MAX_RANDOM; i++) {
var randNum = Math.floor(Math.random()*(NUM_RANGE+1));
this.numbers.push(randNum);
if (randNum == 8) this.eights++;
}
};
// demo usage code ---------------------
var array = new ArrayOfInts();
var array2 = new ArrayOfInts();
document.getElementById('output').innerHTML = array.getNumbers();
console.log(array.getNumbers());
document.getElementById('output').innerHTML += '<br/>The array has the following no. of eights: ' + array.getEights();
document.getElementById('output').innerHTML += '<br/>The number generation ran ' + ArrayOfInts.run_counter + ' times.';
})();
<div id="output"></div>
Here is my code:
import java.util.*;
import java.lang.*;
import java.io.*;
class BubbleSort {
public static int[] bubbleSort(int[]arrayInput) {
boolean swapped = true;
int tmp = 0;
while(swapped) {
swapped = false;//We don't know if the array is pre-sorted
for(int i = 0; i<(arrayInput.length)-1; i++) {
if(arrayInput[i] > arrayInput[i+1]) {
tmp = arrayInput[i];
arrayInput[i] = arrayInput[i+1];
arrayInput[i+1] = tmp;
swapped = true;//Unsorted array - check again
}
}
}
return arrayInput;
}
public static void main (String[] args) throws java.lang.Exception {
int[]unsorted = {13, 2, 11, 6, 5, 15};
int[]finalArray = bubbleSort(unsorted);
System.out.println(finalArray);
}
}
I am completely unsure as to why I am getting a bunch of nonsense returned back to me. The code compiles no problem. I am quite positive in its correctness. Can anybody help me produce an array of integers, instead of garbage. Thanks
In order to print values contained inside the Array use Arrays#toString .
Change
System.out.println(finalArray);
to
System.out.println(Arrays.toString(finalArray));
This is because you need to output them one by one. Something like this
for(int i = 0; i < arrayInput.length; i++) {
System.out.println(arrayInput[i]);
}
Right now you are printing array as an object.
Array extends Object, which have toString() method, that is called in your situation
According to javadoc
getClass().getName() + '#' + Integer.toHexString(hashCode())
import java.util.Random;
public class DotComTestDrive {
public static void main(String [] args) {
String stringOfWords[] = {"Do", "You", "Like", "Me"};
boolean correctOrder = true;
int numberOfResets = 0;
String correctString;
String realString[];
while (correctOrder == true) {
System.out.println();
for (int x = 0 ; x < 4 ; x++) {
int rand = (int) (Math.random() * 4);
System.out.print(stringOfWords[rand]);
System.out.print(" ");
numberOfResets++;
}
// Place If statement here to change correctOrder to false when the new string is "Do You Like Me "
}
System.out.println(numberOfResets);
}
}
My main goal for this is to try and get the new random four words that
it prints out into an String[] so I can then use an If statement to
see if the string matches the original. Then I will make the boolean
"correctOrder" be false, ending the loop.
I know it is simple and sorry if its not a great or clear question.
Just trying to learn the basics and anything helps, thanks!
What I would suggest is to use a list and shuffle it every time you loop.
Map<K,V> map = xxxx;
List<Map.Entry<K,V>> list = new ArrayList<Map.Entry<K,V>>(map.entrySet());
// each time you want a different order.
Collections.shuffle(list);
for(Map.Entry<K, V> entry: list) { /* ... */ }
Assuming that you want to put these Strings in realString, you should do as follows/
initialise this Array
assign one of its elements in your for loop.
For example:
String realString[] = new String[4];
while(correctOrder == true){
for(int x = 0; x < 4; x++){
int rand = (int) (Math.random()*4);
System.out.print(stringOfWords[rand]);
System.out.print(" ");
realString[x] = stringOfWords[rand];
}
}
Also, since I'm at it, I'd suggest you to change a few things in your code:
no need to specify == true: a boolean variable can be tested by itself.
the use of the Random class (instead of Math one) is often preferred. You could have a final Random r = new Random() and get a random int in the range [0, 4[ by simply using r.nextInt(4)
I am confused with passing ARRAYLIST values from one class to another.
I used the ARRAY in these classes before. I am changed those with ARRAYLISTS.
I have 2 classes. this class has an ARRAYLIST called "locationcells". This programs get 3 random digits from another class and get uses inputs and check if their inputs match the 3 digits. it's more like a guessing game.
import java.util.ArrayList;
class SimpleDotCom {
private ArrayList<String> locationcells;
public void setLocationcells(ArrayList<String> Locs)
{
locationcells = Locs;
}
public String CheckYourself(String StringGuess)
{
String result = " Miss";
int index = locationcells.indexOf(StringGuess);
if (index >= 0)
{
locationcells.remove(index);
if (locationcells.isEmpty())
{
result = "Kill";
}
else
{
result = "Hit";
}
}
return result;
}
}
this looks right.
Now the class with the main method:
import java.util.ArrayList;
class SimpleDotComGame {
public static void main(String[] args)
{
int numOfGuesses = 0;
GameHelper helper = new GameHelper();
SimpleDotCom theDotCom = new SimpleDotCom();
/*
this is the part I don't understand. I used to have the int array and generated random numbers and it worked well.
int randomNum = (int) (Math.random() * 5);
ArrayList<String> locations = new ArrayList<String>();
*/
theDotCom.setLocationcells(locations);
boolean isAlive = true;
while (isAlive == true)
{
String guess = helper.getUserInput("Enter a number");
String result = theDotCom.CheckYourself(guess);
numOfGuesses++;
if (result.equals("Kill"))
{
isAlive = false;
System.out.println("You took " + numOfGuesses + "guesses");
}
}
}
}
If you see the comments section above. That's the part I am getting confused. I used to have an array there. INT array. So I was able to pass the INT random numbers to the "simpledotcom" class. Now it is an arraylist with string type, I am not sure how to move forward.
Thank you all in advance,
int numericGuess = Integer.parseInt(helper.getUserInput("Enter a number"));
Also you can use a list of Integers too:
ArrayList<Integer> locations = new ArrayList<Integer>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(randomNum)
}
this way you can perform
locations.indexOf(numericGuess) or locations.contains(numericGuess)
OR
Conversely you can do,
String guess = helper.getUserInput("Enter a number");
ArrayList<String> locations = new ArrayList<String>();
while(//condition){
int randomNum = (int) (Math.random() * 5);
locations.add(String.valueOf(randomNum))
}
and check by
locations.indexOf(guess) or locations.contains(guess)
You can always transform the random int to a string by using Integer.toString() before inserting into your array list.
You can convert the String back to int using Integer.parseInt()
E.g.
for (int i = 0 ; i < 3 ; i++)
{
locations.add(Integer.toString((int)(Math.random() * 5));
}
If I understand well: add 3 Strings to the ArrayList:
ArrayList<String> locations = new ArrayList<String>();
for (i=0; i<3; i++)
{ locations.add(String.valueOf((int) (Math.random() * 5))); }
Anyway, you might refactor a little as well, starting with the extracting the above lines from the main method.
Another way might be to store your integer in a list, and convert the guesses to integers. Looks more logic to me anyway. In that case, you'll have an ArrayList. To convert a string to an integer:
int guessNumber = Integer.parseInt(guess);
or
Integer guessNumber = Integer.valueOf(guess);
Both will throw a NumberFormatException if 'guess' does not contain a parseble integer (see javadoc )
Why are you not using arrays like (apparently) you did before, by the way?