I am reworking a class problem on For Loops and cannot gain a total out of a running score. I attempted to use the string comparisons, but that may be where the problem is. The assignment is:
"Simon Says" is a memory game where "Simon" outputs a sequence of 10 characters (R, G, B, Y) and the user must repeat the sequence. Create a for loop that compares the two strings starting from index 0. For each match, add one point to userScore. Upon a mismatch, exit the loop using a break statement. Ex: The following patterns yield a userScore of 4:
simonPattern: RRGBRYYBGY
userPattern: RRGBBRYBGY
import java.util.Scanner;
public class SimonSays {
public static void main (String [] args) {
String simonPattern = "";
String userPattern = "";
int userScore = 0;
int i = 0;
userScore = 0;
simonPattern = "RRGBRYYBGY";
userPattern = "RRGBBRYBGY";
/* Your solution begins here */
String ss1 = simonPattern.substring(0, 2);
String us1 = userPattern.substring(0, 2);
String ss2 = simonPattern.substring(2, 3);
String us2 = userPattern.substring(2, 3);
String ss3 = simonPattern.substring(4, 5);
String us3 = userPattern.substring(4, 5);
String ss4 = simonPattern.substring(6, 7);
String us4 = userPattern.substring(6, 7);
String ss5 = simonPattern.substring(8, 9);
String us5 = userPattern.substring(8, 9);
for (i = 0; i < simonPattern.length(); i++) {
if (ss1.equals(us1)) {
userScore = userScore + 1;
}
if (ss2.equals(us2)){
userScore = userScore + 1;
}
if (ss3.equals(us3)){
userScore = userScore + 1;
}
if (ss4.equals(us4)){
userScore = userScore + 1;
}
if (ss5.equals(us5)){
userScore = userScore + 1;
}
else{
break;
}
}
/* ^ Your solution goes here ^ */
System.out.println("userScore: " + userScore);
return;
}
}
your problem is in your for loop change if (ss1 == us1) to if (ss1.equals(us1)) same with the else if stucture because String is a reference type and not a primitive data type
primitive data types are int,double,long,float,byte,short,boolean,char and all objects are reference type
public static void main (String [] args)
{
String simonPattern = "";
String userPattern = "";
int userScore = 0;
userScore = 0;
simonPattern = "RRGBRYYBGY";
userPattern = "RRGBBRYBGY";
String[] simons = new String[5];
String[] users = new String[5];
int adder=2;
int location=0;
for(int i=0;i<simonPattern.length();i+=2)
{
simons[location]=simonPattern.substring(i,adder);
location++;
adder+=2;
}
adder=2;
location=0;
for(int i=0;i<userPattern.length();i+=2)
{
users[location]=userPattern.substring(i,adder);
location++;
adder+=2;
}
for (int i = 0; i < simonPattern.length(); i++)
{
if(users[i].equals(simons[i]))
userScore++;
}
System.out.println(userScore);
}
You might want to consider doing it by iterating through the userPattern instead like this:
int userScore = 0;
String simonPattern = "RRGBRYYBGY";
String userPattern = "RRGBBYYBGY";
for (int i = 0; i < userPattern.length(); i++) {
String p = userPattern.substring(0, 1 + i);
if (simonPattern.startsWith(p)) {
userScore = userScore + 1;
}
}
if (userScore < simonPattern.length()) {
System.out.println("You got " + userScore + " letters deep out of " +
simonPattern.length() + " before you made a mistake.");
}
else {
System.out.println("YOU WIN!");
}
You correctly changed the loop to iterate length of simonPattern. Now you just need to throw away the code inside the loop and actually use the iterator variable i.
To extract a single character from a string, you could continue to use substring(i, i+1) to get a String value, but for single characters it's better to use charAt(i).
Also, to increment a variable by 1, it's better to use userScore++, instead of userScore = userScore + 1, although that does work too.
This means that your code should be:
String simonPattern = "RRGBRYYBGY";
String userPattern = "RRGBBRYBGY";
int userScore = 0;
for (int i = 0; i < simonPattern.length(); i++) {
char c1 = simonPattern.charAt(i);
char c2 = userPattern.charAt(i);
if (c1 != c2)
break;
userScore++;
}
System.out.println("userScore: " + userScore); // prints 4
Related
I am working on this simple program that adds two polynomials. However, I am getting wrong results and could not spot the mistake.
import java.util.LinkedList;
public class Polynomial {
private LinkedList<Term> terms = new LinkedList<Term>();
private class Term {
private int coef;
private int exp;
public Term(int coef, int exp) {
this.coef = coef;
this.exp = exp;
}
public int getCoef() {
return coef;
}
public int getExp() {
return exp;
}
public String toString() {
return (this.coef + "x^" + this.exp);
}
}
public String addPoly(String first, String second) {
LinkedList<Term> otherTerms = new LinkedList<Term>();
String result = "";
String [] termsArray1 = first.split(";");
String [] termsArray2 = second.split(";");
for (int i = 0; i < termsArray1.length; i++) {
String [] temp = termsArray1[i].split("x\\^");
int currentCoef = Integer.parseInt(temp[0]);
int currentExp = Integer.parseInt(temp[1]);
Term currentTerm = new Term(currentCoef, currentExp);
terms.add(currentTerm);
}
for (int i = 0; i < termsArray2.length; i++) {
String [] temp = termsArray2[i].split("x\\^");
int currentCoef = Integer.parseInt(temp[0]);
int currentExp = Integer.parseInt(temp[1]);
Term currentTerm = new Term(currentCoef, currentExp);
otherTerms.add(currentTerm);
}
int i = 0;
int j = 0;
while (true){
if(i == terms.size() || j == otherTerms.size()) {
break;
}
if(terms.get(i).getExp() < otherTerms.get(j).getExp()) {
result += (otherTerms.get(j).toString() + ";");
j++;
}
if(terms.get(i).getExp() > otherTerms.get(j).getExp()) {
result += (terms.get(i).toString() + ";");
i++;
}
if(terms.get(i).getExp() == otherTerms.get(j).getExp()) {
Term temp = new Term((terms.get(i).getCoef() + otherTerms.get(j).getCoef()), terms.get(i).getExp());
result += (temp.toString() + ";");
i++;
j++;
}
}
result = result.substring(0, result.length()-1);
return result;
}
}
::Test::
String s3 = "5x^2;-4x^1;3x^0";
String s4 = "6x^4;-1x^3;3x^2";
Polynomial p = new Polynomial();
System.out.println(p.addPoly(s4, s3));
Expected result: 6x^4;-1x^3;7x^2;-4x^1;3x^0
Actual result: 3x^4;7x^2;-1x^1;10x^0
The problem is that when your loop exits, one of the following can still be true:
i < terms.size()
j < j == otherTerms.size()
And this is the case with your example input. This means that part of one of the terms has not been processed and integrated into the output.
A second problem is that your multiple if statements are not exclusive; after the first if block is executed and j++ has executed, it might well be that j is an invalid index in otherTerms when the second if is evaluated. This should be avoided by turning the second and third if into else if.
Here is a fix for that loop:
while (i < terms.size() || j < otherTerms.size()) {
if(i == terms.size() || j < otherTerms.size() && terms.get(i).getExp() < otherTerms.get(j).getExp()) {
result += (otherTerms.get(j).toString() + ";");
j++;
}
else if(j == otherTerms.size() || i < terms.size() && terms.get(i).getExp() > otherTerms.get(j).getExp()) {
result += (terms.get(i).toString() + ";");
i++;
}
else if(terms.get(i).getExp() == otherTerms.get(j).getExp()) {
Term temp = new Term((terms.get(i).getCoef() + otherTerms.get(j).getCoef()), terms.get(i).getExp());
result += (temp.toString() + ";");
i++;
j++;
}
}
Better approach
Your approach is not really OOP. Ideally, the first expression should serve to create one instance of Polynomial and the other expression should serve to create another instance of Polynomial. Then there should be a method that can add another Polynomial instance to the own instance. Finally there should be a toString method that returns the instance as a string in the required format. Your driver code would then look like this:
Polynomial a = new Polynomial("5x^2;-4x^1;3x^0");
Polynomial b = new Polynomial("6x^4;-1x^3;3x^2");
Polynomial sum = a.addPoly(b);
System.out.println(sum.toString());
This is much more object oriented, and will automatically avoid the code repetition that you currently have.
I would like to re-format a String array based on condition. Say, the array
A = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
int index = 1
Which means I will adjoin the items till index 1 with space and format the array. So, finally, it will be,
A = ["samsung chargers", "fast", "charging", "rapid", "high"]
For the index = 2, the output should be,
A = ["samsung chargers fast", "charging", "rapid", "high"]
I write the code that works, I try to find more concise (but not low performance) way.
StringBuilder builder = null;
..........
int fCount = ...
// format the array to match the string
// values = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
builder = new StringBuilder();
String formated = "";
for (int i = 0; i <= fCount; i++) {
builder.append(values[i]).append(" ");
}
formated = builder.toString().trim();
String[] fVaues = new String[values.length - fCount];
fVaues[0] = formated;
for (int i = 1; i < fVaues.length; i++) {
fVaues[i] = values[i+1];
}
What is the simple way to accomplish it?
This method does the same thing:
static String[] joinUntil(String[] original, int until) {
return Stream.concat(
Stream.of(String.join(" ", Arrays.copyOf(original, until))),
Arrays.stream(Arrays.copyOfRange(original, until, original.length))
).toArray(String[]::new);
}
private static List<String> reFormat(List<String> lst, int index){
String joined = String.join(" ", lst.subList(0, index + 1));
List<String> res = new ArrayList<String>();
res.add(joined);
res.addAll(lst.subList(index + 1, lst.size()));
return res;
}
You could just loop over it, adding the Strings to a second array:
String[] b = new String[a.length - index];
String tmp = a[0];
for(int i = 1; i < a.length; i++) {
if(i <= index) {
tmp += " " + a[i];
if(i == index) {
b[i - index] = tmp;
}
}
else {
b[i - index] = a[i];
}
}
I'm trying to code a cipher project where the objective is for a user to send in a text and shift number. The result would be printed accordingly. For instance, if I sent "Hello World" with a shift value of 1, it should print: "Gfmmp Xrsme". The problem is that I'm having trouble with the shifting because I have an arraylist of char values (the alphabet).
This is what I have so far:
import java.util.ArrayList;
public class CaesarCipher
{
int shift;
String inputText;
ArrayList<String> arr;
ArrayList<String> exchange = new ArrayList<String>();
public CaesarCipher()
{
shift = 0;
inputText = "";
}
public CaesarCipher(int s, String iT)
{
shift = s;
inputText = iT;
}
public void alphabet()
{
arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
arr.add("C");
arr.add("D");
arr.add("E");
arr.add("F");
arr.add("G");
arr.add("H");
arr.add("I");
arr.add("J");
arr.add("K");
arr.add("L");
arr.add("M");
arr.add("N");
arr.add("O");
arr.add("P");
arr.add("Q");
arr.add("R");
arr.add("S");
arr.add("T");
arr.add("U");
arr.add("V");
arr.add("W");
arr.add("X");
arr.add("Y");
arr.add("Z");
}
public void convert()
{
String revisedText = inputText.replaceAll("\\s","");
//Turn revisedText into an array and match it with array above
revisedText.toUpperCase();
int j = 1;
String letter = "";
for (int i = 0; i < revisedText.length(); i++)
{
exchange.add(revisedText.substring(i, j));
j++;
}
}
public void shift()
{
shift = shift % 26 + 26;
ArrayList<String> newArr = new ArrayList<String>(); // array with shifted values
int pos = 0;
for(int r = 0; r < exchange.size(); r++)
{
if(arr.get(r).equals(exchange.get(r)))
arr.indexOf(r) + shift = pos;
}
}
public String toString()
{
return "";
}
}
Here is quick for loop for an example
String string = "Hello World";
String newPhrase = "";
int shift = 1;
for(int i = 0; i < string.length(); i++){
if(string.charAt(i) != ' ')
newPhrase += (char)(string.charAt(i) + shift);
else
newPhrase += ' ';
}
System.out.println(string + " -> " + newPhrase);
Output
Hello World -> Ifmmp Xpsme
However you should note that there are a couple edge cases i am not checking for. Once you understand the above code you should be able to find the edge cases I am talking about.
What this program is trying to do is go through numbers starting at "000000" going all the way up to "999999" and trying to find numbers which are palindromes. (eg: 0000000000).
I am having trouble with reversing the string and creating a valid result. The system adds the next 4 numbers creating a length 10 string.
import java.util.Arrays;
public class TestPalindrome{
public static void main(String []args){
int[] intArray = new int[6];
String[] strArray = new String[99];
String nextString;
int count = 0;
int nextnum;
int thisnum;
String thisString = "";
String s = "000000";
nextString = s;
do {
for(int i=0;i<6;i++) {
intArray[i] = Integer.parseInt(String.valueOf(nextString.charAt(i)));
}
int pos1 = intArray[5];
int pos2 = intArray[4]*10;
int pos3 = intArray[3]*100;
int pos4 = intArray[2]*1000;
int pos5 = intArray[1]*10000;
int pos6 = intArray[0]*100000;
nextnum = (pos1 + 1) + pos2 + pos3 + pos4 + pos5 + pos6;
thisnum = pos1 + pos2 + pos3 + pos4 + pos5 + pos6;
// If any of below values = 10, then number is not used
int d7 = ((4*intArray[0])+(10*intArray[1])+(9*intArray[2])+(2*intArray[3])+intArray[4]+(7*intArray[5])) % 11;
int d8 = ((7*intArray[0])+(8*intArray[1])+(7*intArray[2])+(intArray[3])+9*intArray[4]+(6*intArray[5])) % 11;
int d9 = ((9*intArray[0])+(intArray[1])+(7*intArray[2])+(8*intArray[3])+7*intArray[4]+(7*intArray[5])) % 11;
int d10 = ((intArray[0])+(2*intArray[1])+(9*intArray[2])+(10*intArray[3])+4*intArray[4]+(intArray[5])) % 11;
if (d7==10) { }
else if (d8==10) { }
else if (d9==10) { }
else if (d10==10) { }
else {
String s7 = Integer.toString(d7);
String s8 = Integer.toString(d8);
String s9 = Integer.toString(d9);
String s10 = Integer.toString(d10);
thisString = String.format("%06d", thisnum);
String concat = thisString + s7 + s8 + s9 + s10;
StringBuilder input = new StringBuilder(concat);
StringBuilder value = input.reverse();
if( value == input){
System.out.println("" + concat);
strArray[count] = concat;
count = count+1;
}
else {}
}
nextString = String.format("%06d", nextnum);
}
while (nextnum < 1000000 && nextnum > 000000);{
}
}
}
The problem is that it displays all numbers and not just palindromes. Any help is very welcomed.
I would simply put the numbers into strings. Then reverse the string and see if it equals the original.
String originalString = "110011";
String newString = new StringBuilder(originalString ).reverse().toString();
if (originalString.equals(newString )) {
//Is a palindrome
}
Note: Consider how you want to handle leading zeros. "11" is a palindrome, but if you need 4 values then "0011" is not.
One funny way is to use just one for-loop :
public static void main(String [] args){
for(String s = "000000"; !s.equals("1000000"); s = String.format("%06d",Integer.parseInt(s)+1)){
if(new StringBuilder(s).reverse().toString().equals(s))
System.out.println(s);
}
}
I have a problem wherein I have two strings, the length of one of which I will know only upon execution of my function. I want to write my function such that it would take these two stings and based upon which one is longer, compute a final string as under -
finalString = longerStringChars1AND2
+ shorterStringChar1
+ longerStringChars3and4
+ shorterStringChar2
+ longerStringChars5AND6
...and so on till the time the SHORTER STRING ENDS.
Once the shorter string ends, I want to append the remaining characters of the longer string to the final string, and exit. I have written some code, but there is too much looping for my liking. Any suggestions?
Here is the code I wrote - very basic -
public static byte [] generateStringToConvert(String a, String b){
(String b's length is always known to be 14.)
StringBuffer stringToConvert = new StringBuffer();
int longer = (a.length()>14) ? a.length() : 14;
int shorter = (longer > 14) ? 14 : a.length();
int iteratorForLonger = 0;
int iteratorForShorter = 0;
while(iteratorForLonger < longer) {
int count = 2;
while(count>0){
stringToConvert.append(b.charAt(iteratorForLonger));
iteratorForLonger++;
count--;
}
if(iteratorForShorter < shorter && iteratorForLonger >= longer){
iteratorForLonger = 0;
}
if(iteratorForShorter<shorter){
stringToConvert.append(a.charAt(iteratorForShorter));
iteratorForShorter++;
}
else{
break;
}
}
if(stringToConvert.length()<32 | iteratorForLonger<b.length()){
String remainingString = b.substring(iteratorForLonger);
stringToConvert.append(remainingString);
}
System.out.println(stringToConvert);
return stringToConvert.toString().getBytes();
}
You can use StringBuilder to achieve this. Please find below source code.
public static void main(String[] args) throws InterruptedException {
int MAX_ALLOWED_LENGTH = 14;
String str1 = "yyyyyyyyyyyyyyyy";
String str2 = "xxxxxx";
StringBuilder builder = new StringBuilder(MAX_ALLOWED_LENGTH);
builder.append(str1);
char[] shortChar = str2.toCharArray();
int index = 2;
for (int charCount = 0; charCount < shortChar.length;) {
if (index < builder.length()) {
// insert 1 character from short string to long string
builder.insert(index, shortChar, charCount, 1);
}
// 2+1 as insertion index is increased after after insertion
index = index + 3;
charCount = charCount + 1;
}
String trimmedString = builder.substring(0, MAX_ALLOWED_LENGTH);
System.out.println(trimmedString);
}
Output
yyxyyxyyxyyxyy
String one = "longwordorsomething";
String two = "short";
String shortString = "";
String longString = "";
if(one.length() > two.length()) {
shortString = two;
longString = one;
} else {
shortString = one;
longString = two;
}
StringBuilder newString = new StringBuilder();
int j = 0;
for(int i = 0; i < shortString.length(); i++) {
if((j + 2) < longString.length()) {
newString.append(longString.substring(j, j + 2));
j += 2;
}
newString.append(shortString.substring(i, i + 1));
}
// Append last part
newString.append(longString.substring(j));
System.out.println(newString);