Tracing a bug in a "reverse domain" program in Java - java

My code is supposed to reverse a domain. For example, if the input is www.google.com.uk, it should print uk.com.google.www
My problem is that my code prints uk.com..google.www
I can't figure where the extra . comes from or how to remove it. I did some tracing and found that www.stack.com.edu.uk would return uk.edu..com..stack.www
import java.util.*;
public class Domainreverse {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String domain = sc.nextLine();
int x;
int start = 0;
String reversed_domain = "";
boolean flag = false;
do{
x = domain.indexOf(".",start+1);
if(x==-1){
flag = true;
break;
}
reversed_domain = domain.substring(start,x+1) +reversed_domain;
start = x;
} while(flag==false);
int length = domain.length();
int z = domain.lastIndexOf(".");
String enddomain = domain.substring(z+1,length);
reversed_domain = enddomain+reversed_domain;
int p = reversed_domain.lastIndexOf(".");
reversed_domain = reversed_domain.substring(0,p);
System.out.print(reversed_domain);
}
}

Related

Couldn't get correct Output

You give your guess and programm compare the result with random word from the list. If the the programm could find equal symbouls, there will be shown, if not you will see "#"-symbol. Now, I can't understand why "#" didn't dysplayed. Here is a full code.
Example:
apple – random word
apricot - answer of customer
ap############# (15 syllables, because of customer don't have to know
the lenght of word)
import java.util.Random;
import java.util.Scanner;
public class Main {
private static Scanner scan = new Scanner(System.in);
public static final int N = 30;
public static void main(String[] args) {
String ranWord;
Random rand = new Random();
String[] words = new String[N];
words[0] = "appricot";
words[1] = "orange";
words[2] = "cucumber";
words[3] = "potato";
words[4] = "tomato";
words[5] = "cherry";
words[6] = "banana";
words[7] = "carrot";
words[8] = "were";
words[10] = "very";
words[11] = "tasty";
words[12] = "as";
words[13] = "usual";
words[14] = "and";
words[15] = "fresh";
words[16] = "and";
words[17] = "tasty";
words[18] = "passed";
words[19] = "for";
words[20] = "cooking";
words[21] = "a";
words[22] = "chicken";
words[23] = "it";
words[24] = "isn't";
words[25] = "necessary";
words[26] = "cook";
words[27] = "chicken";
words[28] = "every";
words[29] = "day";
System.out.println("Try to guess the word, call Your variant?" + "\n");
ranWord = words[rand.nextInt(N)];
System.out.println("Computer guess the word: " + ranWord);
Computer computer = new Computer(ranWord);
String customWord = scan.nextLine();
Customer customer = new Customer(customWord);
boolean finish = true;
while (!finish) {
//customWord = scan.nextLine();
if (customer.word.equals(computer.ranWord)) {
System.out.println("Succsesful prompt!");
finish = true;
} else {
checkIsFinish(customWord, ranWord);
finish = false;
}
}
}
static void checkIsFinish(String customWord, String ranWord) {
int minLenghtWord = customWord.length() < ranWord.length() ? customWord.length() : ranWord.length();
for (int i = 0; i < minLenghtWord; i++) {
if (customWord.charAt(i) == ranWord.charAt(i)) {
System.out.print(ranWord.charAt(i));
} else {
System.out.print("#");
}
}
for (int i = 0; i < 15 - minLenghtWord; i++) {
System.out.print("#");
}
System.out.println(customWord.length());
}
}
It is a silly mistake you made. You never enter while because finish = true at the start.
Do this,
finish = true;
while (finish) {
//customWord = scan.nextLine();
if (customer.word.equals(computer.ranWord)) {
System.out.println("Succsesful prompt!");
} else {
checkIsFinish(customWord, ranWord);
}
finish = false;
}
Or,
finish = false;
while (!finish) {
//customWord = scan.nextLine();
if (customWord.equals(ranWord)) {
System.out.println("Succsesful prompt!");
} else {
checkIsFinish(customWord, ranWord);
}
finish = true;
}

Why is my class variable rewriting itself after an unrelated method runs?

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.)

How should I parse this in Java?

I'm having trouble understanding how to parse text documents with unknown amounts of 'students'. All my solutions are coming up strange and I'm having trouble with the Scanner. Breaking down the input, the first integer represents how many classes there are, the first string is the class name, the following are students with respective dates and variables that need to be stored along with the student, with an unknown amount of students. I want to store each student along with the class they are in.
My code is extremely messy and confusing so far:
String filename = "input.txt";
File file = new File(filename);
Scanner sc = new Scanner(file);
Student[] studArr = new Student[100];
int studCounter = 0;
boolean breaker = false;
boolean firstRun = true;
int numClasses = sc.nextInt();
System.out.println(numClasses);
while(sc.hasNextLine()){
String className = sc.nextLine();
System.out.println("Name: " + className);
String test = null;
breaker = false;
sc.nextLine();
// Breaks the while loop when a new class is found
while (breaker == false){
Student temp = null;
// Boolean to tell when the first run of the loop
if (firstRun == true){
temp.name = sc.nextLine();
}
else
temp.name = test;
System.out.println(temp.name);
temp.date = sc.nextLine();
if (temp.date.isEmpty()){
System.out.println("shit is empty yo");
}
temp.timeSpent = sc.nextInt();
temp.videosWatched = sc.nextInt();
temp.className = className;
studArr[studCounter] = temp;
studCounter++;
sc.nextLine();
test = sc.nextLine();
firstRun = false;
}
}
}
}
class Student {
public String name;
public String date;
public String className;
public int timeSpent;
public int videosWatched;
}
I don't need an exact answer, but should I be looking into a different tool then Scanner? Is there a method I can research?
Thanks for any assistance.
I came up with the following solution. Scanner is a fine tool for the job. The tricky part is that you have to sort of look ahead to see if you have a blank line or a date to know if you have a student or a class.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Parser {
private static String nextLine(Scanner sc) {
String line;
while (sc.hasNext()) {
if (!(line = sc.nextLine()).isEmpty()) {
return line;
}
}
return null;
}
public static ArrayList<Student>[] parseFile(String fileName) {
File file = new File(fileName);
try (Scanner sc = new Scanner(file)) {
int numClasses = sc.nextInt();
String className = nextLine(sc);
ArrayList<Student>[] classList = new ArrayList[numClasses];
for (int i = 0; i < numClasses; i++) {
classList[i] = new ArrayList<>();
while (true) {
String studentOrClassName = nextLine(sc);
if (studentOrClassName == null) {
break;
}
String dateOrBlankLine = sc.nextLine();
if (dateOrBlankLine.isEmpty()) {
className = studentOrClassName;
break;
}
int timeSpent = sc.nextInt();
int videosWatched = sc.nextInt();
classList[i].add(new Student(className, dateOrBlankLine, studentOrClassName, timeSpent,
videosWatched));
}
}
return classList;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new ArrayList[0];
}
public static void main(String[] args) {
for (ArrayList<Student> students : parseFile("classList.txt")) {
if (!students.isEmpty()) {
System.out.println(students.get(0).className);
}
for (Student student : students) {
System.out.println(student);
}
}
}
static class Student {
public String className;
public String date;
public String name;
public int timeSpent;
public int videosWatched;
public Student(String className, String date, String name, int timeSpent,
int videosWatched) {
this.className = className;
this.date = date;
this.name = name;
this.timeSpent = timeSpent;
this.videosWatched = videosWatched;
}
public String toString() {
return name + '\n' + date + '\n' + timeSpent + '\n' + videosWatched + '\n';
}
}
}
Ask yourself, what does a Student contain? A name, date, number and number. So you want to do the following (not actual code) (format written in Lua code, very understandable. This means this will not run in Lua :P)
if line is not empty then
if followingLine is date then
parseStudent() // also skips the lines etc
else
parseClass() // also skips lines
end
end

Why am I getting a NullPointerException when I try to add an instance of a class into this 2D array of the class?

Trying to make a program to read a text file of a maze, convert each char of it to a string and print into a console. Can't get the 2D array to work. What is it I am doing wrong? Is there something I am not catching else where? I am fairly new to programming and Java so this may be all kinds of wrong. Also keep in mind this is not finished yet at all, still very much in progress, so other errors are probably present.
Enumerated type Square
public enum Square{
WALLS, OPENSPACE, START, FINISH;
private String str;
private Square(String str){
this.str = str;
}
public String toString(){
return str;
}
public static final Square fromChar(char ch){
switch(ch){
case '#':
return WALLS;
case '.':
return OPENSPACE;
case 'o':
return START;
case '*':
return FINISH;
}
return null;
}
}
Maze Class
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Maze {
private Square[][] mazeArray = new Square[10][10];
public Maze(Square[][] mazeArray){
this.mazeArray = mazeArray;
}
public void readMaze() throws FileNotFoundException {
File reader = new File("testMaze.txt");
Scanner input = new Scanner(reader);
String line = "";
line = input.nextLine();
System.out.println(line);
String array[] = line.split(" ");
int width = Integer.parseInt(array[0]);
int height = Integer.parseInt(array[1]);
System.out.println(width);
char[] cArray = new char[10];
while (input.hasNextLine()){
line = input.nextLine();
cArray = line.toCharArray();
System.out.println(cArray);
for (int i = 0; i < height; i++)
for (int x = 0; x < cArray.length; x++){
Square sq = Square.fromChar(cArray[x]);
System.out.println(sq);``
mazeArray[i][x] = sq ; //This is where it gives me a nullPointerException
}
}
mazeArray.toString();
}
}
Main Method
public class MazeMain {
public static void main(String[] args) throws FileNotFoundException {
Maze myMaze = new Maze(null);
myMaze.readMaze();
}
}
testMaze.txt
7 4 ;
####### ;
#...#o# ;
#*#...# ;
####### ;

Java - while loop not working as expected

I am working with a fairly basic programming task in Java. We are asked to create a chat-robot, where the robot is to answer randomly from a set of given strings until the user writes "Bye!", where the robot will simply reply with "Bye!" and end the program. I've written the following code:
import java.util.Scanner;
import java.util.Random;
public class Robot {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random random = new Random();
String[] answer = new String[6];
answer[0] = "blabla1";
answer[1] = "blabla2";
answer[2] = "blabla3";
answer[3] = "blabla4";
answer[4] = "blabla5";
answer[5] = "blabla6";
boolean keepGoing = true;
System.out.println("Hello, how can I help you?");
while (keepGoing) {
String input = in.next();
int output = random.nextInt(6);
System.out.println(answer[output]);
if (input.equals("Bye!")){
keepGoing = false;
System.out.println("Bye!");
}
}
}
I have two issues with the program:
At times, seemingly at random, the program will answer with multiple strings.
When writing "Bye!", the program throws in another string before writing "Bye!". I do know that this may be resolved by adding "break;", but I'd consider this bad practice seeing as I am already using a boolean. (I'd like to keep using it.)
I have no idea as to why these errors occur.
Check the condition for exit before printing anything. That will resolve the 2nd issue
while (true) {
String input = in.next();
if (input.equals("Bye!")){
System.out.println("Bye!");
break;
}
int output = random.nextInt(6);
System.out.println(answer[output]);
}
Change your program like this
import java.util.Scanner;
import java.util.Random;
public class Robot {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random random = new Random();
String[] answer = new String[6];
answer[0] = "blabla1";
answer[1] = "blabla2";
answer[2] = "blabla3";
answer[3] = "blabla4";
answer[4] = "blabla5";
answer[5] = "blabla6";
boolean continue1 = true;
System.out.println("Hello, how can I help you?");
while (continue1) {
String input = in.next();
int output = random.nextInt(6);
if (input.equals("Bye!")){
continue1 = false;
System.out.println("Bye!");
}else
{
System.out.println(answer[output]);
}
}
}
}
Use below code snappet to solve Issue2:
while (keepGoing) {
String input = in.next();
int output = random.nextInt(6);
if(!input.equals("Bye!"))
System.out.println(answer[output]);
if (input.equals("Bye!")){
keepGoing = false;
System.out.println("Bye!");
}
}
Scanner in = new Scanner(System.in);
Random random = new Random();
String[] answer = new String[6];
answer[0] = "blabla1";
answer[1] = "blabla2";
answer[2] = "blabla3";
answer[3] = "blabla4";
answer[4] = "blabla5";
answer[5] = "blabla6";
boolean keepGoing = true;
System.out.println("Hello, how can I help you?");
while (keepGoing) {
String input = in.next();
if ("Bye!".equals(input)) {
keepGoing = false;
System.out.println("Bye!");
} else {
int output = random.nextInt(6);
System.out.println(answer[output]);
}
}
import java.util.Scanner;
import java.util.Random;
public class Robot
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
Random random = new Random();
String[] answer = new String[6];
answer[0] = "blabla1";
answer[1] = "blabla2";
answer[2] = "blabla3";
answer[3] = "blabla4";
answer[4] = "blabla5";
answer[5] = "blabla6";
boolean keepGoing = true;
System.out.println("Hello, how can I help you?");
while (keepGoing)
{
String input = in.next();
int output = random.nextInt(6);
System.out.println(answer[output]);
if (input.equals("Bye!"))
{
keepGoing = false;
System.out.println("Bye!");
} //This bracket is the only thing missing in your code.
}// End of while loop
} // End of main method
}// End of class

Categories

Resources