I wasn't able to figure this one out since I don't know how to calculate "inserting" an underscore. I included my attempt at solving this problem.
Given a string, do not let the same character repeat for n positions. If it does repeat, insert an underscore to push
it X positions down. The final output needed is just the total number of characters.
Example 1) Input "QQ",2 becomes "Q__Q", the return value is 4.
Example 2) Input "ABCA",2 becomes "ABCA" (no spaces needed), total characters is 4.
Example 3) Input "DEDEE", 1 becomes "DEDE_E", total chars is 6.
Example 4) Input "JKJK", 2 becomes "JK_JK", total characters is 5 (The toughest example).
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
// int shift = 0;
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
System.out.println(i + "=" + letter + " last saw " + hm.get(word.charAt(i)));
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
System.out.println(i + "-" + hm.get(letter) + "<=" + spaces);
if (i - hm.get(word.charAt(i)) <= spaces) {
// System.out.println("add " + (spaces + 1 - (i - hm.get(letter))));
// shift += (spaces + 1) - (i - hm.get(letter));
word = word.substring(0, i) + "_" + word.substring(i);
System.out.println(i + " word=" + word);
}
hm.put(letter, i); // update the hashmap with the last seen again
}
}
return word.length();
}
}
Your question is (mainly) about inserting underscores. A key insight that can help move forward is that the input and output strings are different, so it would be cleaner to treat them as such, using a StringBuilder for example. Additionally, it doesn't hurt at this stage to use temporary variables to capture concepts such as distance between characters. Leveraging these two ideas, you can have more self-explanatory code, for example:
public static String space(String input, int spaces) {
HashMap<Character, Integer> map = new HashMap<>();
StringBuilder result = new StringBuilder();
for( char symbol : input.toCharArray() ) {
int position = result.length();
int lastPosition = map.getOrDefault(symbol, position-spaces-1);
int distance = position - lastPosition -1;
for( int j = 0; j < Math.max( spaces - distance, 0) ; j++ ) {
result.append('_');
}
result.append(symbol);
map.put(symbol, result.length()-1);
}
return result.toString();
}
(and once this is mastered and digested, it's of course possible to in-line the temps)
The requirement doesn't ask you to display the constructed string so we need to only do calculations. The regex (.+)\1 will match any repetition of 1 or more chars and countPattern returns how many times that pattern was found.
public static void main(String[] args) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 6"); //in becomes JK__JK, ie. 4 + 2x'_'
}
private static int spacey(String word, int spaces) {
if(spaces<0){
throw new IllegalArgumentException("should be positive value");
}
if(word==null){
return 0;
}
if(spaces==0){
return word.length();
}
final Pattern repeatedCharRegex = Pattern.compile("(.+)\\1");
final int repetitions = countPattern(word, repeatedCharRegex);
return word.length() + repetitions*spaces;
}
public static int countPattern(String references, Pattern referencePattern) {
Matcher matcher = referencePattern.matcher(references);
int count = 0;
while (matcher.find()){
count++;
}
return count;
}
First of all you have an error in one of your test cases. Assuming you want to reproduce the cases in the quoted challenge, you need a 1 as second argument to the call to spacey here:
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
// ^ ^
The formula to calculate the number of underscores to insert is:
previousindex + n + 1 - i
...where previousindex is the index at which the current letter occurred before, and i is the current index.
You can repeat an underscore with the .repeat string method. Don't forget to update i afterwards, so it keeps pointing to the currently processed character (which moved forward).
So your code could work like this:
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
int underscores = hm.get(letter) + spaces + 1 - i;
if (underscores > 0) { // Need to add underscores
word = word.substring(0, i) + "_".repeat(underscores) + word.substring(i);
i += underscores; // update i so it still points to the current character
}
hm.put(letter, i);
}
}
return word.length();
}
}
i am currently running a test on a leaderboard, for every 20 entries there is a "show more" button that the user has to press to show the next 20 entries. I created a "try if catch" method but it only seems to press the button once so then i added it to the loop of the test_leaderboard_entry method but its taking a very long time after all the "show more" buttons have been pressed. How could i change this to be quicker when the test is running, or could i change the show_more method to actually press all the buttons that appear?
public void show_more() throws Exception {
try {
if (show_more_button.isDisplayed()) {
show_more_button.click();
System.out.println("Selecting show more button");
}
} catch (Exception e) {
System.out.println("Show more button not present");
}
}
public void test_player_leaderboard_entry() throws Exception {
int size = playerRows.size();
Integer previous_total = 0;
Integer previous_points = 0;
String previous_user = null;
for (int i = 0; i < size; i++) {
show_more();
//Position
String position_first_player = Drivers.getDriver().findElement(By.cssSelector("[data-qa-position-value='" + i + "']")).getText();
//Points
String points_player = Drivers.getDriver().findElement(By.cssSelector("[data-qa-points-value='" + i + "']")).getText();
//Username
String username_player = Drivers.getDriver().findElement(By.cssSelector("[data-qa-player-value='" + i + "']")).getText();
//Row Number
Integer row = i + 1;
Integer point_player = Integer.parseInt(points_player);
Integer total_of_won_and_looking_good = 0;
//PICKS
for (int pick_number = 1; pick_number < 5; pick_number++) {
String pick_status = Drivers.getDriver().findElement(By.xpath("//*[#id='root']/div/main/section[2]/section/div/ol/a[" + row + "]/li/div[3]/div[" + pick_number + "]/div")).getAttribute("data-qa-pick-state");
//System.out.println(pick_status);
if (Integer.parseInt(pick_status) == 2 || Integer.parseInt(pick_status) == 1) {
total_of_won_and_looking_good = total_of_won_and_looking_good + 1;
}
}
if (previous_total.equals(total_of_won_and_looking_good) && (previous_points > point_player)) {
//Assert.assertTrue;
System.out.println("Picks are the same, points are higher ");
} else if (previous_total.equals(total_of_won_and_looking_good) && previous_points.equals(point_player)) {
String prev_user = previous_user.toLowerCase();
String use_player = username_player.toLowerCase();
Assert.assertTrue(prev_user.compareTo(use_player) < 0);
System.out.println("Picks are the same, points are the same, alpha order is correct ");
}
previous_total = total_of_won_and_looking_good;
previous_points = point_player;
previous_user = username_player;
System.out.println("On row number " + row + " we find " + username_player + " in position " + position_first_player + " with " + total_of_won_and_looking_good + " correct picks and " + points_player + " points!");
}
}
you can skip the loop in the following way,
if ( ((i+1) % 20) == 0)
show_more();
It will click at the time of multiple of 20 and skips other time.
Also, noticed that size value is not updated after click on show more button. It will not continue after the first 20 iterations.
You can change your code as given below to updated the count or size value,
if ( ((i+1) % 20) == 0){
show_more();
size = playerRows.size();
}
insert the above inside for loop by replacing the show_more method calling. It may work for you.
For this assignment I have to count the number of operations that my program does. I have put an OpCount counter in my loops etc., but am stumped on how to do so for an if statement. Heres my code for the ifs for some context (Printing details of a specific dam from an array of objects of type dam):
public void printDam(String damName) {
boolean find = false;
for (int i = 0; i<211; i++) {
ObjDam dam = data[i];
if (dam.getDamName().equals(damName)) {
System.out.println("Dam Name: " + dam.getDamName() +
", FSC: " + dam.getFsc() +
", Dam Level: " + dam.getDamLevel());
find = true;
}
}
if (find == false) {
System.out.println("The dam " + damName + " you entered cannot be found in the file");
}
}
Any help would be greatly appreciated.
This question already has answers here:
Comparing two integer arrays in Java
(10 answers)
Closed 7 years ago.
The statement before the begining of while loop System.out.println("Value of i before loop = " + i); is not being printed and the value of i in the loop is not being printed starting from 1. Instead it starts printing from a random big int.
package main;
import java.util.Random;
public class Main {
public static void main(String args[]){
Random ran = new Random();
int[] in = {2,5,9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while(!(c_gen.equals(in))){
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for(int x : in)
System.out.print(x + " ");
System.out.print("\n" + "c_gen = ");
for(int x : c_gen)
System.out.print(x + " ");
System.out.println("\n" + "i = " + i);
}
}
You are directly comparing arrays resulting in an infinite loop. Those results are being printed but are going to be at the top of tons and tons of output. Fix your comparison.
Sotirios' intuition is correct - your bug is in the line while(!(c_gen.equals(in))). You can't compare arrays for equality using the .equals(...) method because "arrays inherit their equals-method from Object, [thus] an identity comparison will be performed for the inner arrays, which will fail, since a and b do not refer to the same arrays." (source). Thus because c_gen and in will always refer to different arrays (even if their contents are the same), your loop will go forever.
Try Arrays.equals(..) instead:
public static void main(String[] args) {
Random ran = new Random();
int[] in = {2,5,9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while(!Arrays.equals(in, c_gen)){
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for(int x : in)
System.out.print(x + " ");
System.out.print("\n" + "c_gen = ");
for(int x : c_gen)
System.out.print(x + " ");
System.out.println("\n" + "i = " + i);
}
This works (terminates in finite time) for me, with sample output:
Value of i before loop = 0
1 9 9 ..................1
5 4 1 ..................2
1 1 6 ..................3
1 3 6 ..................4
.... //Omitted because of space
6 5 8 ..................1028
2 5 9 ..................1029
in = 2 5 9
c_gen = 2 5 9
i = 1029
I get:
Value of i before loop = 0
2 2 1 ..................1
2 2 4 ..................2
...
Suggest you rebuild the project and try again.
As originally posted your code will not terminate because int[].equals(int[]) will not do what you expect.
You could try this though.
private static boolean equals(int[] a, int[] b) {
if (a == null && b == null) {
// Both null
return true;
}
if (a == null || b == null) {
// One null
return false;
}
if (a.length != b.length) {
// Differ in length.
return false;
}
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
// Mismatch
return false;
}
}
// Same.
return true;
}
public void test() {
Random ran = new Random();
int[] in = {2, 5, 9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while (!equals(c_gen, in)) {
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for (int x : in) {
System.out.print(x + " ");
}
System.out.print("\n" + "c_gen = ");
for (int x : c_gen) {
System.out.print(x + " ");
}
System.out.println("\n" + "i = " + i);
}
Here is the main problem:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at ExamAnalysis.main(ExamAnalysis.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
The program compiles and runs. It's just that I am either getting the java.util.NoSuchElementException along with my five jother errors with (answer.charAt(i) == char) near the bottom. Here is my program:
import java.io.*;
import java.util.Scanner;
class ExamAnalysis
{
public static void main(String [] args) throws FileNotFoundException
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Please type the correct answers to the exam questions, one right after the other: ");
String answers = keyboard.nextLine();
System.out.println("Where is the file with all the student responses? ");
String responses = keyboard.nextLine();
Scanner read = new Scanner(new File(responses));
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
public static void resultsByStudents(String responses, String answers)
{
System.out.println ("Student # Correct Incorrect Blank");
System.out.println ("~~~~~~~~~ ~~~~~~~ ~~~~~~~~~ ~~~~~");
int student = 0;
int correct = 0;
int incorrect = 0;
int blank = 0;
for (int i = 0; i <= 9; i++)
{
for (int j = 0; j <= responses.length(); j++)
{
if ((responses.charAt(j)) == answers.charAt(j))
correct++;
else if ((responses.charAt(j)) != answers.charAt(j))
incorrect++;
else
blank++;
}
System.out.println(student + " " + correct + " " + incorrect + " " + blank);
student++;
}
}
public static void analysis(String responses)
{
System.out.println("QUESTION ANALYSIS (* marks the correct response)");
System.out.println("~~~~~~~~~~~~~~~~~");
//stores the percentage of each choice chosen
double A = 0;
double B = 0;
double C = 0;
double D = 0;
double E = 0;
double X = 0;
// tallys every variable chosen per question
for (int i = 0; i <= 10; i++) // go through all the questions
{
for (int j = 0; j <= responses.charAt(i); j++) //go through all the student responses
{
// variable that are being tallied
int chooseA = 0;
int chooseB = 0;
int chooseC = 0;
int chooseD = 0;
int chooseE = 0;
int chooseBlank = 0;
//variables take percentage of choices that have been chosen from each student
A = chooseA/9;
B = chooseB/9;
C = chooseC/9;
D = chooseD/9;
E = chooseE/9;
X = chooseBlank/9;
// variables that will print the asterisk with certain character of correct answer
String a = "A";
String b = "B";
String c = "C";
String d = "D";
String e = "E";
String blank = "blank";
if (responses.charAt(j) == A)
chooseA++;
else if (responses.charAt(j) == B)
chooseB++;
else if (responses.charAt(j) == C)
chooseC++;
else if (responses.charAt(j) == D)
chooseD++;
else if (responses.charAt(j) == E)
chooseE++;
else
chooseBlank++;
System.out.println("Question #" + i);
if (answers.charAt(i) == 'A') a = "A*"; // answers cannot be resolved(I already made it a global variable in my main method.)
else if (answers.charAt(i) == 'B') b = "B*";// answers cannot be resolved
else if (answers.charAt(i) == 'C') c = "C*";// answers cannot be resolved
else if (answers.charAt(i) == 'D') d = "D*";// answers cannot be resolved
else if (answers.charAt(i) == 'E') e = "E*";// answers cannot be resolved
System.out.println(a + " " + b + " " + c + " " + d + " " + e + " " + blank);
System.out.println (chooseA + " " + chooseB + " " + chooseC + " " + chooseD + " " + chooseE + " " + chooseBlank );
System.out.println (A + " " + B + " " + C + " " + D + " " + E + " " + X);
}
}
}
}
while (read.hasNextLine())
{
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
int p = 1;
p += i;
System.out.println("Student " + p + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on 9 students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
}
}
Your logic here is confusing you. read.nextLine(); "Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
So you are saying, does it have a line? If so, read the next 10...well...11 lines, which isn't what you want. You don't know if there are 11 lines past this point. Don't know what that text file looks like, but you will want to restructure this part to either say, "While it has a next line", or "Read 11 lines"
Remove the for loop may resolve the issue. You are checking only once by using while(hasNextLine() ) but calling read.nextLine() 10 times in for loop.
for (int i = 0; i <= 10; i++)
{
responses = read.nextLine();
.......
}
int i = 0;
int numberOfStudents = 9;
while (i < numberOfStudents && read.hasNextLine()){
responses = read.nextLine();
i++;
System.out.println("Student " + i + " responses: " + responses.substring(0,10));
}
System.out.println("Thank you for the data on "+ numberOfStudents +" students. Here's the analysis: ");
resultsByStudents(responses, answers);
analysis(responses);
i < numberOfStudents : makes the required number of inserts
read.hasNextLine() : checks if there is input from console. If not the program waits for input.
for (int i = 0; i <= 10; i++)
count from 0 -> 10 = 11 students