I'm trying to build a matrix with a static method and I return a new constructor with the built matrix, but whenever I try to get the matrix values, it all ends up being empty.
public class KeyTable {
private char[][] key;
final static int rows = 5;
final static int columns = 5;
public KeyTable(char[][] key) {
this.key = key;
}
public static KeyTable buildFromString(String keyPhrase)
{
char[][] alpha = new char[5][5];
char[] alphabet = "abcdefghiklmnopqrstuvwxyz".toCharArray();
int followingAlphabet = 0;
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < columns; c++)
{
if(followingAlphabet <= keyPhrase.length()-1)
alpha[r][c] = keyPhrase.charAt(followingAlphabet);
else
alpha[r][c] = alphabet[followingAlphabet];
followingAlphabet++;
}
}
System.out.println(Arrays.deepToString(alpha));
return new KeyTable(alpha);
}
public char[][] getKeyTable()
{
return this.key;
}
}
Main class:
package com.company;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
char[][] alpha = new char[5][5];
KeyTable key = new KeyTable(alpha);
System.out.println(Arrays.deepToString(alpha));
KeyTable.buildFromString("EXAMPLE");
key.getKeyTable();
System.out.println(Arrays.deepToString(alpha));
System.out.println(Arrays.deepToString(key.getKeyTable()));
}
}
It is because you did two separate things. First you created a KeyTable object with your array. Then you ran a bunch of other random stuff (buildfromString method). Then you ask it to return an empty key and print it. I have no clue what you are actually trying to do but it definitely won't print anything because you didn't store it anywhere. You also have it returning an empty object which makes no sense either. Something like this:
key=KeyTable.buildFromString("Example");
You then can return you results in your main application to display the information properly. I hope that this helps you. If you provide more details on what you are actually trying to do, I can help more on that.
Related
I know this has probably been an error asked about a million times but I'm really struggling to understand why I'm getting this with my one specific assignment.
I am to create a method class that will go through a String[] of words called 'list' and sort them alphabetically. I thought this would be an easy..
Here is what I have, I have no problem with the actual sorting, I just can't get Java to understand that I'm trying to call the method. I was given a specific class name, main class code, and method header, so I cannot change it or else I can't use the code runner.
class Lesson_15_Activity{
public static void sortAndPrint(String [] list){ //cant change
for (int pos = 0; pos < list.length-1; pos++){
for (int k = 0; k <= pos; k++){ //
if (list[k].compareTo(list[pos]) < 0){
list[pos] = list[k];
}
}
}
for (int a = 0; a < list.length-1; a++){
System.out.println(list[a]);
}
}
}
//the main method
class Main {
public static void main(String[] args) {
String [] list = { "against" , "forms" , "belief" , "government" , "democratic" , "movement" , "understanding"};
sortAndPrint(list);
//^this is where i get the error
}
}
I've tried adding code like this like in my earlier lessons but couldn't get it to work.
private String[] words;
public setWords(){
words = list;
}
You can go straight forward like this
import java.util.Arrays;
public class Lesson15Activity {
public static void main(String[] args) {
String[] list = {"against", "forms", "belief", "government", "democratic", "movement", "understanding"};
sortAndPrint(list);
//^this is where i get the error
}
public static void sortAndPrint(String[] list) { //cant change
Arrays.stream(list).sorted().forEach(e -> System.out.println(e));
}
}
You define two classes: Lesson_15_Activity and Main, and you're trying to use the method sortAndPrint since the class Main, when it is defined in Lesson_15_Activity.
One simple solution is join both classes:
class Lesson_15_Activity{
public static void sortAndPrint(String [] list){ //cant change
for (int pos = 0; pos < list.length-1; pos++){
for (int k = 0; k <= pos; k++){ //
if (list[k].compareTo(list[pos]) < 0){
list[pos] = list[k];
}
}
}
for (int a = 0; a < list.length-1; a++){
System.out.println(list[a]);
}
}
public static void main(String[] args) {
String [] list = { "against" , "forms" , "belief" , "government" , "democratic" , "movement" , "understanding"};
sortAndPrint(list);
//^this is where i get the error
}
}
I need to compare the roman letters and get the correct integer out of it.
If I'm correct, there should be a way to compare the hashmap key with the arraylist element and if they match, get the associated value from the key.
The return 2020 is there just for test purposes, since I wrote a JUnit test in a different class. It can be ignored for now.
I hope someone could give me a hint, since I wouldn't like to use the solutions from the web, because I need to get better with algorithms.
package com.company;
import java.util.*;
public class Main {
static HashMap<String, Integer> romanNumbers = new HashMap<String, Integer>();
static {
romanNumbers.put("I", 1);
romanNumbers.put("V", 5);
romanNumbers.put("X", 10);
romanNumbers.put("L", 50);
romanNumbers.put("C", 100);
romanNumbers.put("D", 500);
romanNumbers.put("M", 1000);
}
public static void main(String[] args) {
romanToArabic("MMXX");
}
static int romanToArabic(String roman) {
ArrayList romanLetters = new ArrayList();
roman = roman.toUpperCase();
for (int i = 0; i < roman.length(); i++) {
char c = roman.charAt(i);
romanLetters.add(c);
}
// [M, M, X, X]
System.out.println(romanLetters);
// iterates over the romanLetters
for (int i = 0; i < romanLetters.size(); i++) {
System.out.println(romanLetters.get(i));
}
// retrive keys and values
for (Map.Entry romanNumbersKey : romanNumbers.entrySet()) {
String key = (String) romanNumbersKey.getKey();
Object value = romanNumbersKey.getValue();
System.out.println(key + " " + value);
}
return 2020;
}
}
You could just Map.get each array element.
package com.company;
import java.util.ArrayList;
import java.util.HashMap;
public class Main {
static HashMap<String, Integer> romanNumbers = new HashMap<String, Integer>();
static {
romanNumbers.put("I", 1);
romanNumbers.put("V", 5);
romanNumbers.put("X", 10);
romanNumbers.put("L", 50);
romanNumbers.put("C", 100);
romanNumbers.put("D", 500);
romanNumbers.put("M", 1000);
}
public static void main(String[] args) {
System.out.println(romanToArabic("MMXX"));
}
static int romanToArabic(String roman) {
ArrayList romanLetters = new ArrayList();
roman = roman.toUpperCase();
for (int i = 0; i < roman.length(); i++) {
char c = roman.charAt(i);
romanLetters.add(c);
}
// [M, M, X, X]
System.out.println(romanLetters);
// iterates over the romanLetters
int sum = 0;
for (int i = 0; i < romanLetters.size(); i++) {
String key = String.valueOf(romanLetters.get(i));
if (romanNumbers.containsKey(key)) {
sum += romanNumbers.get(key);
}
}
return sum;
}
}
As stated in the comments, this just answers your question of how to get values from an hashmap where keys are the array elements. It is not a solution to calculate the numeric value out of a roman number. For that, you will have to look at the next letter, and join if it is larger, before consulting the map for the final value to sum.
I'd like to suggest a completly different approach using an enum.
public enum RomanNumber {
I(1), V(5), X(10), L(50), C(100), D(500), M(1000);
private final int arabic;
RomanNumber(int arabic) {
this.arabic = arabic;
}
public int getArabicNumber() {
return arabic;
}
// This is obviously broken. IV wouldn't work for example.
public static int toArabic(String romanLetters) {
romanLetters = romanLetters.toUpperCase();
int arabicResult = 0;
for (int i = 0; i < romanLetters.length(); i++) {
char romanNumber = romanLetters.charAt(i);
// valueOf(String) returns the enum based on its name. So a String of "I" returns the RomanNumber I enum.
int arabicNumber = valueOf(String.valueOf(romanNumber)).getArabicNumber();
arabicResult = arabicResult + arabicNumber;
}
return arabicResult;
}
}
Can be used like this:
String romanNumber = "MMXX";
System.out.println(RomanNumber.toArabic(romanNumber));
Btw. every enum has an ordinal() method which returns the declaration position inside the enum. (I.ordinal() == 1 or V.ordinal() == 2) I think this could help you with the IV problem aswell. :)
So I'm writing a basic MasterMind game that is... mostly functional. However, its exhibiting odd behavior and I'm unsure why.
The idea is that what defines a Code and its behavior is one file, the gameplay is another, and the Main just creates a new game and starts playing. When I initialize the game, the computer creates a new random string of 4 (the "secret code"), as expected; but then once I get input for the User guess, it seems to rewrite the secret code into whatever I've input. Further, my methods for evaluating matches don't work at all, but considering that the secret code keeps changing means that it's not being set to begin with, and I'm unsure why.
All three classes below. Why is my class variable in Game not setting properly and accessible to the other methods?
Main.java
class Main {
public static void main(String[] args) {
Game newGame = new Game();
newGame.play();
}
}
Code.java
import java.util.Random;
import java.util.HashMap;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Set;
import java.lang.Math;
import java.lang.StringBuilder;
class Code {
private static HashMap<String,String> PEGS;
private static ArrayList<String> pegStrings;
protected static String secretCodeString;
public static void main(String[] args) {
}
public Code(String input){
this.secretCodeString = input;
}
public Code(){
randomize();
}
//literally just creates the peghash
public static void setPegs(){
PEGS = new HashMap<String,String>();
PEGS.put("C","c");
PEGS.put("Y","y");
PEGS.put("R","r");
PEGS.put("P","p");
PEGS.put("O","o");
PEGS.put("G","g");
}
//turns the pegs ito something randomize can use
public static ArrayList<String> makePegArray(){
setPegs();
pegStrings = new ArrayList<String>();
Collection<String> pegValues = PEGS.values();
Object[] pegObjects = pegValues.toArray();
for (int i = 0; i < pegObjects.length; i++){
pegStrings.add(pegObjects[i].toString());
}
return pegStrings;
}
// sets Class Variable secretCode to a four letter combination
public static Code randomize(){
secretCodeString = new String();
Random rand = new Random();
int randIndex = rand.nextInt(makePegArray().size());
for (int i = 0; i < 4; i++){
randIndex = rand.nextInt(makePegArray().size());
secretCodeString = secretCodeString.concat(makePegArray().get(randIndex));
}
Code secretCode = parse(secretCodeString);
return secretCode;
}
public static Code parse(String input) {
setPegs();
makePegArray();
String[] letters = input.split("");
StringBuilder sb = new StringBuilder();
for (String letter : letters) {
if (pegStrings.contains(letter)) {
sb.append(letter);
} else {
System.out.println(letter);
throw new RuntimeException();
}
}
String pegListString = sb.toString();
Code parsedCode = new Code(pegListString);
//System.out.println(parsedCode);
return parsedCode;
}
public int countExactMatches(Code guess){
String guessString = guess.secretCodeString;
int exactMatches = 0;
String[] guessArray = guessString.split("");
String[] winningCodeArray = (this.secretCodeString).split("");
for(int i = 0; i < 4; i++){
if(guessArray[i] == winningCodeArray[i]){
exactMatches++;
}
}
return exactMatches;
}
public int countNearMatches(Code guess) {
String guessString= guess.secretCodeString;
HashMap<String,Integer> guessCount = new HashMap<String,Integer>();
HashMap<String,Integer> secretCodeCount = new HashMap<String,Integer>();
Set<String> codeKeys = guessCount.keySet();
int matches = 0;
int keys = guessCount.keySet().size();
String[] keyArray = new String[keys];
for(int i = 0; i < guessString.length(); i++) {
//removes character from string
String codeCharacter = String.valueOf(guessString.charAt(i));
String guessShort = guessString.replace(codeCharacter,"");
//counts instances of said character
int count = guessString.length() - guessShort.length();
guessCount.put(codeCharacter, count);
}
for(int i = 0; i < secretCodeString.length(); i++) {
//removes character from string
String winningString = this.secretCodeString;
String winningCodeCharacter = String.valueOf(winningString.charAt(i));
String winningCodeShort = guessString.replace(winningCodeCharacter,"");
//counts instances of said character
int count = winningString.length() - winningCodeShort.length();
secretCodeCount.put(winningCodeCharacter, count);
}
for (int i = 0; i < keys; i++) {
codeKeys.toArray(keyArray);
String keyString = keyArray[i];
if (secretCodeCount.containsKey(keyString)) {
matches += Math.min(secretCodeCount.get(keyString), guessCount.get(keyString));
}
}
int nearMatches = matches - countExactMatches(guess);
return nearMatches;
}
}
Game.java
import java.util.Scanner;
class Game {
protected static Code winningCode;
public static void main(String[] args){
}
public Game(){
winningCode = new Code();
}
protected static Code getGuess() {
Scanner userInput = new Scanner(System.in);
int count = 0;
int maxTries = 5;
while(true){
try {
String codeToParse = userInput.next();
Code guess = Code.parse(codeToParse);
return guess;
} catch(RuntimeException notACode) {
System.out.println("That's not a valid peg. You have " + (maxTries - count) + " tries left.");
if (++count == maxTries) throw notACode;
}
}
}
protected static void displayMatches(Code guess){
int nearMatches = winningCode.countNearMatches(guess);
int exactMatches = winningCode.countExactMatches(guess);
System.out.println("You have " + exactMatches + " exact matches and " + nearMatches + " near matches.");
}
protected static void play(){
int turnCount = 0;
int maxTurns = 10;
System.out.println("Greetings. Pick your code of four from Y,O,G,P,C,R.");
while(true){
Code guess = getGuess();
displayMatches(guess);
if (guess == winningCode) {
System.out.print("You win!!");
break;
} else if (++turnCount == maxTurns) {
System.out.print("You lose!!");
break;
}
}
}
}
On every guess, you call Code.parse, Code.parse creates a new Code (new Code(pegListString);) and that constructor sets the secretCodeString and because that's static, all instances of Code share the same variable. You need to avoid mutable static members.
Another tip is to either have a method return a value, or mutate state (of either its input, or its own instance, this), but avoid doing both.
"Why is my class variable rewriting itself after an unrelated method runs?"
Because, actually, it is not unrelated. The "mess" that you have created by declaring variables and methods as static has lead to unwanted coupling between different parts of your code.
It is difficult to say what the correct solution is here because your code has gotten so confused by the rewrites that it is hard to discern the original "design intent".
My advice would be to start again. You now should have a clearer idea of what functionality is required. What you need to do is to redo the object design so that each class has a clear purpose. (The Main and Game classes make sense, but Code seems to be a mashup of functionality and state that has no coherent purpose.)
I need to write a program to solve the eight queens problem and I have no idea how to do it, but I have already started with the multidimensional array. The thing is that I don't know how to call a constructor from the main class, just to check if the array was constructed properly, or how to call it from a method. Can anybody help, please? This is the code, it returns null.
import javax.swing.JOptionPane;
public class Eightqueens
{
private static int[][] board;
public static void main(String[] args)
{
JOptionPane.showMessageDialog(null,board);
}
public Eightqueens (int size)
{
size = 8;
board = new int[size][size];
int row;
int col;
for (row = 0; row < size; row++)
for (col = 0; col < size; col++)
board[row][col] = 0;
}
}
You are supposed to use the value passed to the constructor, not overwrite it :
...
private int[][] board;
...
public Eightqueens (int size)
{
size = 8; // remove this
...
}
public int[][] getBoard()
{
return board;
}
public static void main(String[] args)
{
Eightqueens equeens = new Eightqueens (8); // create an instance
JOptionPane.showMessageDialog(null,equeens.getBoard()); // use accessor to get
// board
}
In addition, it doesn't make sense to initialize a static variable (board) in the constructor, since each new instance you create would overwrite its value. I'd change it to non-static, and then you can get it from your instance by using an accessor method (equeens.getBoard()).
To call your constructor you must 'construct' a new object.
Eightqueens obj = new Eightqueens(5);
just when you instantiate your object of class with new keyword , you call your constructor.
like this :
public static void main(String[] args) {
Eightqueens eq = new Eightqueens(5);
}
You can start by calling your constructor by making a new instance of Eightqueens
int size = 1; // anything
new Eightqueens(size);
This code does not return null, it does not return anything. You never call your constructor :
public static void main(String[] args) {
Eightqueens eq = new Eightqueens(5);
}
You can't call your constructor again. It only runs at the start of the code.
You can however, create a new instance of it to run it again.
The Dialog Box is empty because the value of board is nothing, which is because it has not been initialized. The board get a value in the constructor method. So you have to call the constructor method before you show the dialog box.
public static void main(String[] args)
{
Eightqueens eq = new Eightqueens(8);
JOptionPane.showMessageDialog(null,board);
}
Also, in the constructor method, you are overwriting the value of size given by you earlier. Thus, there is practically no need to supply the variable to the method. So, either you remove the line:
size = 8;
or, change the constructor method to not input the value, like this:
public Eightqueens ()
{
int size = 8;
board = new int[size][size];
int row;
int col;
for (row = 0; row < size; row++)
for (col = 0; col < size; col++)
board[row][col] = 0;
}
I am trying to take in the user inputs into a Hashset and I need to use the hash set objects for element comparison later. How can I do this? Below is my code:
import java.util.*;
public class GemStones{
public static void main(String[] args) {
HashSet<Character> set = new HashSet<Character>();
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int i = 0; i < t; i++){
String str = in.next();
for (int j = 0; j < str.length(); j++) {
char c = str.charAt(j);
set.add(c);
}
}
in.close();
}
}
You can create an instance variable this way by declaring the set outside your method at class level. If you want to later get the contents of this set and modify from a different class
public class GemStones{
private HashSet<Character> set = new HashSet<Character>();
public HashSet<Character> getSet() {
return set;
}
public void setSet(HashSet<Character> set) {
this.set = set;
}
public static void main(String[] args) {
GemStones stoneObj = new GemStones();
.......
HashSet set = stoneObj.getSet();
set.add(c)
......
......
....
}
This gives you an outline and you need to check further on instance and local varaibles and how to access objects and naming conventions to make your code better.