I realize a program in java that allows to generate this succession with a chain of the following way:
Input:
Hello World
good vibes
chain with succession:
hElLo wOrLd
gOoD vIbEs
Try to do it transforming the String input to an array type string with a split, then with an if, go checking the even positions, and transforming the letter that is in that lowercase position, and with the odd positions, the same, only that converting to capital letters ... The problem is that the array also saves the blanks, which causes a lag in the sequence, and I can not remove it, since I must show the text with the inputtext format, What can I do to fulfill the succession, without altering the spaces and line breaks that it has?
program give me:
hElLo wOrLd
GoOd vIbEs
code:
public String cambiar(String cadena1)
{
cambiar= cadena1.split("");
for(int i=0; i<cambiar.length; i++)
{
if(i%2==0)
{
cambiar[i]=cambiar[i].toLowerCase();
}
else
{
cambiar[i]=cambiar[i].toUpperCase();
}
}
for(int i=0; i<cambiar.length; i++)
{
textocambiado+=cambiar[i];
}
return textocambiado;
}
NOTE: I am not allowed to use arraylist
The problem: https://drive.google.com/open?id=15VOlyhGtyvZ_0vcFype2o1sjiKkj7Hzn
You have the right idea, you just need to skip incrementing the counter for non-letters.
Another two performance improvements you could consider:
Using a StringBuilder instead of concatenating to a string
Using a boolean that you flip around instead of checking if the counter i is odd or even:
public String cambiar(String input) {
boolean isLower = true;
StringBuilder result = new StringBuilder(input.length());
for (int i = 0; i < input.length(); ++i) {
char ch = input.charAt(i);
if (Character.isLetter(ch)) {
if (isLower) {
result.append(Character.toLowerCase(ch));
} else {
result.append(Character.toUpperCase(ch));
}
isLower = !isLower;
} else {
result.append(ch);
}
}
return result.toString();
}
Related
My problem is that I need to identify characters which differ between the two given strings in a visually striking way. Output the two input strings on two lines, and then identify the differences on the line below using periods (for identical characters) and asterisks (for differing characters). For example:
ATCCGCTTAGAGGGATT
GTCCGTTTAGAAGGTTT
*....*.....*..*..
I have tried to write two string with each other but I dont know how to make the program check for every character in the string and see if those match
This is what I have done so far :/
System.out.println("String 1: ");
String var1 = Scanner.nextLine();
System.out.println("String 2: ");
String var2 = Scanner.nextLine();
if (same (var1, var2))
System.out.println(".........");
else
System.out.println("********");
public static boolean same (String var1, String var2){
if (var1.equals(var2))
{
return true;
}
else
{
return false;
}
Can anyone help me with this?
You need to loop through your Strings and compare characters one by one. To run through your list you can make a for-loop. Use an int as counter and use the method length() to obtain your string size.
for(int i=0; i<string1.length(); i++ {
// do stuff
}
Then since you have a counter going through all position of your string, you can obtain the character at a specific position in this string using the method charAt()
char char1 = string1.charAt(i);
Then compare the character to check if they are the same. If they are print a dot . if they're not print an asterisk *
if(char1 == char2) {
System.out.print(".");
} else {
System.out.print("*");
}
In the above part I supposed your two string have the same size. If it's not the case, you can first determine which one is the smallest (and so which is the biggest) :
String smallestString;
String biggestString;
if(string1.size() > string2.sise()) {
smallestString = string2;
biggestString = string1;
else {
smallestString = string1;
biggestString = string2;
}
Then make your for loop go through the smallest String, otherwise you will face IndexOutOfBoundsException.
for(int i=0; i<smallestString.length(); i++ {
// do stuff
}
And the end of this for loop print asterisks for the characters that left in the biggest String
for(int j=smallestString.length(); j<biggestString.length(); j++) {
System.out.print("*");
}
This is what I've come up with.Mind you there are better ways to do this and I've just written it with as much effort as you put in your question.
public class AskBetterQuestion{
public static void main(String[] args) {
// TODO Auto-generated method stub
String w1="ATCCGCTTAGAGGGATT";
String w2="GTCCGTTTAGAAGGTTT";
char[] first = w1.toCharArray();
char[] second = w2.toCharArray();
int minLength = Math.min(first.length, second.length);
char[] out=new char[minLength];
for(int i = 0; i < minLength; i++)
{
if (first[i] != second[i])
{
out[i]='.';
}
else out[i]='*';
}
System.out.println(w1);
System.out.println(w2);
System.out.print(out);
}
}
I am trying to generate a String as a hint for the solution to a world solve.
This is what I have for generating the hint, but I am unsure of how to correct these errors. If the guess has the correct character guessed in the right place, the hint displays that character. If it has the letter in the word, it displays a "+" in the respective position. If the letter isn't in the word, a "*" gets returned.
For instance, if the solution to the puzzle is "HARPS", and the guess is "HELLO", the hint will be "H****". Likewise if the guess is "HEART", the hint will be "H*++*".
Also, wordLength is generated from another method that gives the amount of characters in the solution.
public String getHint(String theGuess) {
for (int index = 0; index < wordLength; index++) {
if **(theGuess.charAt(index)** = solution.charAt(index)) {
hint.**setCharAt**(index, theGuess.charAt(index));
} else if **(theGuess.charAt(index)** = solution.indexOf(solution)) {
**hint.setCharAt**(index, "+");
} else {
**hint.setCharAt**(index, "*");
}
}
return hint;
}
Errors are double starred.
For (theGuess.charAt(index) Eclipse is showing the following error message:
The left-hand side of an assignment must be a variable.
For hint.setCharAt, it tells me:
The method setCharAt(int, String) is undefined for the type String.
There are numerous problems in your code that need to be fixed:
= is used when you want to assign a new value to a variable. You want to use == when comparing two values.
setCharAt() is a method for StringBuilder, not String. This simplest solution is to just concatinate your new charater to the String using +=.
If you want to use StringBuilder, the following parts need to be fixed:
The second parameter for setCharAt() should be a character, not a string. You need to change the double quotes around "*" and "+" to single quotes like '*'
setCharAt() tries to replace a character at a specifc index. This will throw an error if the StringBuilder is shorter than the index position you are trying to replace. You can solve this by right away setting your StringBuilder to a string that is the correct length like
hint = new StringBuilder("*****").
Since you are always adding the the end of the builder though, you should really just use append() instead of setCharAt() and you won't need to worry about this index position problem.
(theGuess.charAt(index) == solution.indexOf(solution) does not search the entire solution string to see if it contains the current character. Instead, you can use indexOf() to check if the string contains the character. This link might help: How can I check if a single character appears in a string?
Here is a complete program with the code working:
public class HelloWorld
{
public static void main(String[] args)
{
OtherClass myObject = new OtherClass();
System.out.print(myObject.getHint("HEART"));
}
}
Option 1 - Add to the String using +=:
public class OtherClass
{
private String solution = "HARPS";
private int wordLength = 5;
public String getHint(String theGuess) {
String hint = "";
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hint += theGuess.charAt(index);
} else if (solution.indexOf(theGuess.charAt(index)) > 0) {
hint += "+";
} else {
hint += "*";
}
}
return hint;
}
}
Option 2 - Use StringBuilder:
public class OtherClass
{
private StringBuilder hint;
private String solution = "HARPS";
private int wordLength = 5;
public String getHint(String theGuess) {
hint = new StringBuilder();
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hint.append(theGuess.charAt(index));
} else if(solution.indexOf(theGuess.charAt(index)) > 0) {
hint.append('+');
} else {
hint.append('*');
}
}
return hint.toString();
}
}
This code should work:
public String getHint(String theGuess) {
StringBuilder hintBuilder = new StringBuilder(hint);
for (int index = 0; index < wordLength; index++) {
if (theGuess.charAt(index) == solution.charAt(index)) {
hintBuilder.setCharAt(index, theGuess.charAt(index));
} else if(theGuess.charAt(index) == solution.indexOf(string)) {
hintBuilder.setCharAt(index, "+");
} else {
hintBuilder.setCharAt(index, "*");
}
}
return hintBuilder;
}
Basically, you have to use a 'StringBuilder' because Strings are immutable, meaning that they cannot be altered once they are built.
Also, when comparing two values, use == or === to compare, not =.
UPDATED
I forgot that Strings are immutable in Java, and have updated the code so that it should work.
I have a bug in this block of code. The debugger suggest it´s cause is this line of code char chr = getSecretWord.charAt(i);
What this code does is look for a match between userInput and secretWord. I have the for loop to go through the length of the secretWord letters one by one, and if there is a letter matching return true. If not, return false... but the program crashes when it is suppose to just return false... I guess it is something with this line, but do not know exactly what getSecretWord.charAt(i);
private boolean isMatchingSecretWord(String userInput)
{
String secretWord = "";
String getSecretWord = getSecretWord();
for (int i = 0; i <= getSecretWord.length();i++)
{
char chr = getSecretWord.charAt(i);
secretWord = ""+chr;
if (secretWord.equals(userInput))
{
println("is true");
return true;
}
}
return false;
}
As an side note, is what I´ve done with this code correct, assigning the getSecretWorld() Method to a String so I can use the Strings method length()?
String getSecretWord = getSecretWord();
for (int i = 0; i <= getSecretWord.length();i++)
Debug code:
Exception in thread "Thread-4" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:686)
at Hangman.isMatchingSecretWord(Hangman.java:49)
at Hangman.userInput(Hangman.java:34)
at Hangman.run(Hangman.java:20)*
for (int i = 0; i <= getSecretWord.length(); i++)
should be:
for (int i = 0; i < getSecretWord.length(); i++)
// ^^^
// see here
The valid indexes for an n-character string (or an n-element array) are 0 through n-1 inclusive.
So, if your secret word is xyyzy, the valid indexes are zero through four. Your original loop iterates with i set to zero through five, hence the problem.
But there seems to be a lot of unnecessary code in there, when you could get away with something simple.
First, I would remove a source of confusion - the function name sounds like the user input and the secret word have to match completely whereas your comment indicates otherwise:
Thanks, this works. But the reason for the loops is that the user enters one letter, I want to see if that letter is within the SecretWord. (it´s a hangman game).
In that case, you simply want to see if the single character exists in the secret word. I would change the function name to suit and, even then, it can be done with a lot less code:
private boolean isInSecretWord (String userInput) {
String secretWord = getSecretWord();
return secretWord.contains(userInput);
}
You were getting out of bounds error as your for loop wasn't looping correctly, I have modified it so that the loop doesn't go out of bounds and also your secretWord variable wasn't populating correctly, the code should now work as intended :)
private boolean isMatchingSecretWord(String userInput)
{
String secretWord = "";
String getSecretWord = getSecretWord();
for (int i = 0; i < getSecretWord.length();i++)
{
char chr = getSecretWord.charAt(i);
secretWord = secretWord + chr;
if (secretWord.equals(userInput))
{
println("is true");
return true;
}
}
return false;
}
String handling in Java is something I'm trying to learn to do well. Currently I want to take in a string and replace any characters I find.
Here is my current inefficient (and kinda silly IMO) function. It was written to just work.
public String convertWord(String word)
{
return word.toLowerCase().replace('á', 'a')
.replace('é', 'e')
.replace('í', 'i')
.replace('ú', 'u')
.replace('ý', 'y')
.replace('ð', 'd')
.replace('ó', 'o')
.replace('ö', 'o')
.replaceAll("[-]", "")
.replaceAll("[.]", "")
.replaceAll("[/]", "")
.replaceAll("[æ]", "ae")
.replaceAll("[þ]", "th");
}
I ran 1.000.000 runs of it and it took 8182ms. So how should I proceed in changing this function to make it more efficient?
Solution found:
Converting the function to this
public String convertWord(String word)
{
StringBuilder sb = new StringBuilder();
char[] charArr = word.toLowerCase().toCharArray();
for(int i = 0; i < charArr.length; i++)
{
// Single character case
if(charArr[i] == 'á')
{
sb.append('a');
}
// Char to two characters
else if(charArr[i] == 'þ')
{
sb.append("th");
}
// Remove
else if(charArr[i] == '-')
{
}
// Base case
else
{
sb.append(word.charAt(i));
}
}
return sb.toString();
}
Running this function 1.000.000 times takes 518ms. So I think that is efficient enough. Thanks for the help guys :)
You could create a table of String[] which is Character.MAX_VALUE in length. (Including the mapping to lower case)
As the replacements got more complex, the time to perform them would remain the same.
private static final String[] REPLACEMENT = new String[Character.MAX_VALUE+1];
static {
for(int i=Character.MIN_VALUE;i<=Character.MAX_VALUE;i++)
REPLACEMENT[i] = Character.toString(Character.toLowerCase((char) i));
// substitute
REPLACEMENT['á'] = "a";
// remove
REPLACEMENT['-'] = "";
// expand
REPLACEMENT['æ'] = "ae";
}
public String convertWord(String word) {
StringBuilder sb = new StringBuilder(word.length());
for(int i=0;i<word.length();i++)
sb.append(REPLACEMENT[word.charAt(i)]);
return sb.toString();
}
My suggestion would be:
Convert the String to a char[] array
Run through the array, testing each character one by one (e.g. with a switch statement) and replacing it if needed
Convert the char[] array back to a String
I think this is probably the fastest performance you will get in pure Java.
EDIT: I notice you are doing some changes that change the length of the string. In this case, the same principle applies, however you need to keep two arrays and increment both a source index and a destination index separately. You might also need to resize the destination array if you run out of target space (i.e. reallocate a larger array and arraycopy the existing destination array into it)
My implementation is based on look up table.
public static String convertWord(String str) {
char[] words = str.toCharArray();
char[] find = {'á','é','ú','ý','ð','ó','ö','æ','þ','-','.',
'/'};
String[] replace = {"a","e","u","y","d","o","o","ae","th"};
StringBuilder out = new StringBuilder(str.length());
for (int i = 0; i < words.length; i++) {
boolean matchFailed = true;
for(int w = 0; w < find.length; w++) {
if(words[i] == find[w]) {
if(w < replace.length) {
out.append(replace[w]);
}
matchFailed = false;
break;
}
}
if(matchFailed) out.append(words[i]);
}
return out.toString();
}
My first choice would be to use a StringBuilder because you need to remove some chars from the string.
Second choice would be to iterate throw the array of chars and add the treated char to another array of the inicial size of the string. Then you would need to copy the array to trim the possible unused positions.
After that, I would make some performance tests to see witch one is better.
I doubt, that you can speed up the 'character replacement' at all really. As for the case of regular expression replacement, you may compile the regexs beforehand
Use the function String.replaceAll.
Nice article similar with what you want: link
Any time we have problems like this we use regular expressions are they are by far the fastest way to deal with what you are trying to do.
Have you already tried regular expressions?
What i see being inefficient is that you are gonna check again characters that have already been replaced, which is useless.
I would get the charArray of the String instance, iterate over it, and for each character spam a series of if-else like this:
char[] array = word.toCharArray();
for(int i=0; i<array.length; ++i){
char currentChar = array[i];
if(currentChar.equals('é'))
array[i] = 'e';
else if(currentChar.equals('ö'))
array[i] = 'o';
else if(//...
}
I just implemented this utility class that replaces a char or a group of chars of a String. It is equivalent to bash tr and perl tr///, aka, transliterate. I hope it helps someone!
package your.package.name;
/**
* Utility class that replaces chars of a String, aka, transliterate.
*
* It's equivalent to bash 'tr' and perl 'tr///'.
*
*/
public class ReplaceChars {
public static String replace(String string, String from, String to) {
return new String(replace(string.toCharArray(), from.toCharArray(), to.toCharArray()));
}
public static char[] replace(char[] chars, char[] from, char[] to) {
char[] output = chars.clone();
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < from.length; j++) {
if (output[i] == from[j]) {
output[i] = to[j];
break;
}
}
}
return output;
}
/**
* For tests!
*/
public static void main(String[] args) {
// Example from: https://en.wikipedia.org/wiki/Caesar_cipher
String string = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
String from = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String to = "XYZABCDEFGHIJKLMNOPQRSTUVW";
System.out.println();
System.out.println("Cesar cypher: " + string);
System.out.println("Result: " + ReplaceChars.replace(string, from, to));
}
}
This is the output:
Cesar cypher: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Result: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD
The Problem is simple Find "ABC" in "ABCDSGDABCSAGAABCCCCAAABAABC" without using String.split("ABC")
Here is the solution I propose, I'm looking for any solutions that might be better than this one.
public static void main(String[] args) {
String haystack = "ABCDSGDABCSAGAABCCCCAAABAABC";
String needle = "ABC";
char [] needl = needle.toCharArray();
int needleLen = needle.length();
int found=0;
char hay[] = haystack.toCharArray();
int index =0;
int chMatched =0;
for (int i=0; i<hay.length; i++){
if (index >= needleLen || chMatched==0)
index=0;
System.out.print("\nchar-->"+hay[i] + ", with->"+needl[index]);
if(hay[i] == needl[index]){
chMatched++;
System.out.println(", matched");
}else {
chMatched=0;
index=0;
if(hay[i] == needl[index]){
chMatched++;
System.out.print("\nchar->"+hay[i] + ", with->"+needl[index]);
System.out.print(", matched");
}else
continue;
}
if(chMatched == needleLen){
found++;
System.out.println("found. Total ->"+found);
}
index++;
}
System.out.println("Result Found-->"+found);
}
It took me a while creating this one. Can someone suggest a better solution (if any)
P.S. Drop the sysouts if they look messy to you.
How about:
boolean found = haystack.indexOf("ABC") >= 0;
**Edit - The question asks for number of occurences, so here's a modified version of the above:
public static void main(String[] args)
{
String needle = "ABC";
String haystack = "ABCDSGDABCSAGAABCCCCAAABAABC";
int numberOfOccurences = 0;
int index = haystack.indexOf(needle);
while (index != -1)
{
numberOfOccurences++;
haystack = haystack.substring(index+needle.length());
index = haystack.indexOf(needle);
}
System.out.println("" + numberOfOccurences);
}
If you're looking for an algorithm, google for "Boyer-Moore". You can do this in sub-linear time.
edit to clarify and hopefully make all the purists happy: the time bound on Boyer-Moore is, formally speaking, linear. However the effective performance is often such that you do many fewer comparisons than you would with a simpler approach, and in particular you can often skip through the "haystack" string without having to check each character.
You say your challenge is to find ABC within a string. If all you need is to know if ABC exists within the string, a simple indexOf() test will suffice.
If you need to know the number of occurrences, as your posted code tries to find, a simple approach would be to use a regex:
public static int countOccurrences(string haystack, string regexToFind) {
Pattern p = Pattern.compile(regexToFind);
Matcher m = p.matcher(haystack); // get a matcher object
int count = 0;
while(m.find()) {
count++;
}
return count;
}
Have a look at http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
public class NeedleCount
{
public static void main(String[] args)
{
String s="AVBVDABCHJHDFABCJKHKHF",ned="ABC";
int nedIndex=-1,count=0,totalNed=0;
for(int i=0;i<s.length();i++)
{
if(i>ned.length()-1)
nedIndex++;
else
nedIndex=i;
if(s.charAt(i)==ned.charAt(nedIndex))
count++;
else
{
nedIndex=0;
count=0;
if(s.charAt(i)==ned.charAt(nedIndex))
count++;
else
nedIndex=-1;
}
if(count==ned.length())
{
nedIndex=-1;
count=0;
totalNed++;
System.out.println(totalNed+" needle found at index="+(i-(ned.length()-1)));
}
}
System.out.print("Total Ned="+totalNed);
}
}
Asked by others, better in what sense? A regexp based solution will be the most concise and readable (:-) ). Boyer-Moore (http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm) will be the most efficient in terms of time (O(N)).
If you don't mind implementing a new datastructure as replacement for strings, have a look at Tries: http://c2.com/cgi/wiki?StringTrie or http://en.wikipedia.org/wiki/Trie
If you don't look for a regular expression but an exact match they should provide the fastest solution (proportional to length of search string).
public class FindNeedleInHaystack {
String hayStack="ASDVKDBGKBCDGFLBJADLBCNFVKVBCDXKBXCVJXBCVKFALDKBJAFFXBCD";
String needle="BCD";
boolean flag=false;
public void findNeedle() {
//Below for loop iterates the string by each character till reaches max length
for(int i=0;i<hayStack.length();i++) {
//When i=n (0,1,2... ) then we are at nth character of hayStack. Let's start comparing nth char of hayStach with first char of needle
if(hayStack.charAt(i)==needle.charAt(0)) {
//if condition return true, we reach forloop which iterates needle by lenghth.
//Now needle(BCD) first char is 'B' and nth char of hayStack is 'B'. Then let's compare remaining characters of needle with haystack using below loop.
for(int j=0;j<needle.length();j++) {
//for example at i=9 is 'B', i+j is i+0,i+1,i+2...
//if condition return true, loop continues or else it will break and goes to i+1
if(hayStack.charAt(i+j)==needle.charAt(j)) {
flag=true;
} else {
flag=false;
break;
}
}
if(flag) {
System.out.print(i+" ");
}
}
}
}
}
Below code will perform exactly O(n) complexity because we are looping n chars of haystack. If you want to capture start and end index's of needle uncomment below commented code. Solution is around playing with characters and no Java String functions (Pattern matching, IndexOf, substring etc.,) are used as they may bring extra space/time complexity
char[] needleArray = needle.toCharArray();
char[] hayStackArray = hayStack.toCharArray();
//java.util.LinkedList<Pair<Integer,Integer>> indexList = new LinkedList<>();
int head;
int tail = 0;
int needleCount = 0;
while(tail<hayStackArray.length){
head = tail;
boolean proceed = false;
for(int j=0;j<needleArray.length;j++){
if(head+j<hayStackArray.length && hayStackArray[head+j]==needleArray[j]){
tail = head+j;
proceed = true;
}else{
proceed = false;
break;
}
}
if(proceed){
// indexList.add(new Pair<>(head,tail));
needleCount++;
}
++tail;
}
System.out.println(needleCount);
//System.out.println(indexList);