I am trying to get it to return a compressed word. For example, reaction should be #act$. But it is getting returned as react$. I feel like my issue is not including the original word in the return statement. Can anyone help? Thanks!
public static String compress (String word) {
String newWord = "";
int the = word.indexOf("the");
if (the >= 0) {
newWord = word.substring(0,the) + "&" + word.substring(the+3);
}
int ion = newWord.indexOf("ion");
if (ion >= 0) {
newWord = newWord.substring(0,ion) + "$" + word.substring(ion+3);
}
int ing = newWord.indexOf("ing");
if (ing >= 0) {
newWord = newWord.substring(0,ing) + "~" + word.substring(ing+3);
}
int an = newWord.indexOf("an");
if (an >= 0) {
newWord = newWord.substring(0,an) + "#" + word.substring(an+2);
}
int re = newWord.indexOf("re");
if (re >= 0) {
newWord = newWord.substring(0,re) + "#" + word.substring(re+2);
}
int con = newWord.indexOf("con");
if (con >= 0) {
newWord = newWord.substring(0,con) + "%" + word.substring(con+3);
}
return newWord;
}
A compressed version also:
public static String compress(String word) {
word = word.replace("the", "&");
word = word.replace("ion", "$");
word = word.replace("ing", "~");
word = word.replace("an", "#");
word = word.replace("re","#");
word = word.replace("con","%");
return word;
}
You're mixing up your uses of newWord and word in a confusing way. If the first if clause doesn't fire, newWord will still be an empty string and none of the other conditions will fire. On the other hand, if newWord does get set to something, you still go on using word substrings, in ways that don't make any sense.
You would be better off just using one variable through the whole method.
public static String compress(String word) {
int the = word.indexOf("the");
if (the >= 0) {
word = word.substring(0,the) + "&" + word.substring(the+3);
}
int ion = word.indexOf("ion");
if (ion >= 0) {
word = word.substring(0,ion) + "$" + word.substring(ion+3);
}
int ing = word.indexOf("ing");
if (ing >= 0) {
word = word.substring(0,ing) + "~" + word.substring(ing+3);
}
int an = word.indexOf("an");
if (an >= 0) {
word = word.substring(0,an) + "#" + word.substring(an+2);
}
int re = word.indexOf("re");
if (re >= 0) {
word = word.substring(0,re) + "#" + word.substring(re+2);
}
int con = word.indexOf("con");
if (con >= 0) {
word = word.substring(0,con) + "%" + word.substring(con+3);
}
return word;
}
Note also that, written this way, you can only use each replacement once per word: if you have "thethe" you will compress it to "&the", not "&&". If you want use replacements multiple times, you would have to use a loop. Or, easier still, use String.replace.
Related
For context, the method needs to insert dashes into a string in a 1, 2, 4, 1, 2, 4... pattern. For example, a string that holds "Overflow" would be output as "O-ve-rflo-w". Would I use nested for loops in this situation?
The other answer using a pattern is a great solution, however, you could also use a recursive method. This may not be a compact solution, but the logic is easy to follow:
//Process the string in chunks of 7 characters
public static String addFormatting(String input){
String formatted = "";
//Add first character
if(input.length() >= 1) formatted = input.substring(0, 1);
//Add dash and the next 2 characters, else the remainder of the string
if(input.length() >= 3) formatted += "-" + input.substring(1,3);
else if (input.length() > 1) formatted += "-" + input.substring(1);
//Add dash and the next 4 characters, else the remainder of the string
if(input.length() >= 7) formatted += "-" + input.substring(3,7);
else if (input.length() > 3) formatted += "-" + input.substring(3);
//Add dash and recursivly format the next chunk
if(input.length() > 7){
formatted += "-";
return formatted + addFormatting(input.substring(7));
}
//else return the complete formatted once it has been fully processed
else return formatted;
}
To call the method simply use addFormatting("OverflowisagreatQnAsite!"); the printed output would O-ve-rflo-w-is-agre-a-tQ-nAsi-t-e!
You can do the following:
private static String applyPattern(List<Integer> pattern, String str) {
int currentPatternIndex = 0;
int iterationsTillNextDash = pattern.get(currentPatternIndex);
StringBuilder stringBuilder = new StringBuilder();
for (char aChar : str.toCharArray()) {
if (iterationsTillNextDash == 0) {
stringBuilder.append('-');
iterationsTillNextDash = pattern.get(++currentPatternIndex % pattern.size());
}
iterationsTillNextDash--;
stringBuilder.append(aChar);
}
return stringBuilder.toString();
}
Usage:
String strWithDashes = applyPattern(Arrays.asList(1, 2, 4), "Overflow");
System.out.println(strWithDashes);
Output:
O-ve-rflo-w
Here is a simple hard-coded example for your situation. Perhaps you can figure out a way to use modulus % in your code for words longer than "overflow".
class Main {
public static String addDashes(String s)
{
String s_with_dashes = "";
for(int i = 0; i < s.length(); i++)
{
if(i == 1 || i == 3 || i == 7)
{
s_with_dashes += '-';
}
s_with_dashes += s.charAt(i);
}
return s_with_dashes;
}
public static void main(String[] args)
{
String s = "Overflow";
String s_with_dashes = addDashes(s);
System.out.println(s_with_dashes);
}
}
Method:
private static String addDashes(String string, int... pattern) {
String output = "";
int index = 0;
while (true)
for (int p : pattern) {
if (index + p >= string.length())
return output += string.substring(index);
output += string.substring(index, index += p) + "-";
}
}
Call Method:
System.out.println(addDashes("Overflow", 1,2,4));
Output:
O-ve-rflo-w
I have been trying to fix this for a while now and I just can't seem to get it. I'm trying to get the phone number from the user so I can display it but when I get all the users info the error occurs. Any help would be appreciated. Thank you.
Here is the code:
import java.util.Scanner;
public class Event
{
public static double pricePerGuestHigh = 35.00;
public static double pricePerGuestLow = 32.00;
public static final int LARGE_EVENT_MAX = 50;
public String phone = "";
public String eventNumber;
private int guests;
private double pricePerEvent;
public void setPhone()
{
Scanner input = new Scanner(System.in);
int count = 0;
System.out.println("Enter your phone number: ");
String phone = input.nextLine();
int len = phone.length();
for(int i=0; i<1; i++)
{
char c = phone.charAt(i);
if(Character.isDigit(c))
{
count++;
String ss = Character.toString(c);
phone = phone.concat(ss);
}
}
if(count != 10)
{
phone = "0000000000";
}
}
public String getPhone()
{
// The error occurs in this method
String ret = "(" + this.phone.charAt(0) + "" + this.phone.charAt(1)
+ "" + this.phone.charAt(2) + ")" + this.phone.charAt(3)
+ "" + this.phone.charAt(4) + "" + this.phone.charAt(5)
+ "" + this.phone.charAt(6) + "" + this.phone.charAt(7)
+ "" + this.phone.charAt(8) + "" + this.phone.charAt(9);
return ret;
}
public void setEventNumber()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the event number: ");
eventNumber = input.nextLine();
}
public void setGuests(int guests)
{
this.guests=guests;
if(isLargeEvent())
pricePerEvent = pricePerGuestHigh;
else
pricePerEvent = pricePerGuestLow;
}
public int getGuestsCount()
{
return guests;
}
public boolean isLargeEvent()
{
if(guests >= LARGE_EVENT_MAX)
{
return true;
}
else if(guests < LARGE_EVENT_MAX)
{
return false;
}
return isLargeEvent();
}
public String getEventNumber()
{
String ret1 = "Event Number: " + this.eventNumber;
return ret1;
}
public int getGuests(boolean largeEvent)
{
return guests;
}
}
The code where the error occurs has been marked with a comment.
The error means that you are trying to access the phone's character at an index that does not exists.
Precisely, your phone field is never set inside your code so it's an empty String.
Anyway, you should also fix the for loop by using the len variable:
int len = phone.length();
for(int i = 0; i < len; i++)
{
...
}
By doing that, you cannot concern about StringIndexOutOfBoundsException because now the for automatically traverse only the chars present in the String.
The StringOutOfBoundsException is thrown whenever you're attempting to access a character in the string that doesn't exist at the given index.
From the code you've provided it seems as though you're accessing an empty string in the method getPhone().
You can fix this by first checking if the string is empty with phone.isEmpty().
public String getPhone() {
if (phone == null || /*this.*/phone.isEmpty()) {
// Handle the error accordingly.
return null; // example
}
String ret = "(" + this.phone.charAt(0) + "" + this.phone.charAt(1)
+ "" + this.phone.charAt(2) + ")" + this.phone.charAt(3)
+ "" + this.phone.charAt(4) + "" + this.phone.charAt(5)
+ "" + this.phone.charAt(6) + "" + this.phone.charAt(7)
+ "" + this.phone.charAt(8) + "" + this.phone.charAt(9);
return ret;
}
While we're at it, I'd recommend not using string concatenation, as this will produce a large amount of overhead.
Instead, use Java's string formatting.
This will not only increase the readability of your code, but it will (as mentioned before) reduce overhead, because strings in Java are immutable.
To make your code work you should make new local var (for example inputPhone) and than change phone var of Event object. Also you should change condition in for loop.
public void setPhone()
{
Scanner input = new Scanner(System.in);
int count = 0;
System.out.println("Enter your phone number: ");
String inputPhone = input.nextLine();
int len = inputPhone.length();
for(int i=0; i<len; i++)
{
char c = inputPhone.charAt(i);
if(Character.isDigit(c))
{
count++;
String ss = Character.toString(c);
phone = phone.concat(ss);
}
}
if(count != 10)
{
phone = "0000000000";
}
}
I am trying to replace all occurrences of a word in a string. However with this code I can only find the first occurrence of it and replace it. Is there any way to expand this code to replace the words in the entire string? I am attempting to do this without using the replace built in methods in Java since I already know how to use those function, I was wondering if there was another way to go about it.
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord + partAfter;
}
First, you need a loop of some kind. Probably a while.
In the loop, since you're replacing the "old" string, you could just keep looping until you don't find it anymore. But if you want to avoid re-searching the first part of the string, or if you want to allow the replacement to contain the string it's replacing (without then looping infinitely), then once you've done each replacement, use String#indexOf(String str, int fromIndex), which lets you continue from the middle of the string.
There is a simple solution that uses recursion. Once you have replaced the word for the first time in the string, you can then replace the word in the partAfter part of the string by calling the replace method again:
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord +
replace(old, newWord, partAfter); // <<-- Note recursion here
}
This only changes one line from your original source.
public static String replace(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0) {
return input;
}
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return partBefore + newWord + replace(old, newWord, partAfter );
}
However, it's more efficient to collect the bits and pieces in a StringBuilder.
public static String replace(String oldStr, String newStr, String input) {
StringBuilder sb = new StringBuilder();
int i;
int prev = 0;
while( (i = input.indexOf(oldStr, prev)) >= 0 ){
sb.append( input.substring(prev, i) ).append( newStr );
prev = i + oldStr.length();
}
sb.append(input.substring(prev));
return sb.toString();
}
First of all, don't use new for a variable name. It's a reserved word.
Second of all, in order to replace multiple occurences, you should have a loop.
Finally, it's better to create the new String using a StringBuilder, not String concatenation.
This is untested, but something like this should work:
public static String replace(String oldStr, String newStr, String input) {
int i = input.indexOf(oldStr);
if (i < 0) {
return input;
}
StringBuilder buffer = new StringBuilder();
int prev = 0;
while (i >= 0) {
String partBefore = input.substring(prev, i);
prev = i + oldStr.length();
buffer.append(partBefore);
buffer.append(newStr);
i = input.indexOf(oldStr, i + oldStr.length());
}
buffer.append(input.substring(i+oldStr.length()));
return buffer.toString();
}
Use Recursion:
public static String replaceAll(String old, String newWord, String input) {
int i = input.indexOf(old);
if (i < 0)
return input;
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
return replaceAll(old, newWord, partBefore + newWord + partAfter);
}
Use do-While and go on replacing words:
public static String replaceAll(String old, String newWord, String input) {
boolean loop = true;
do {
int i = input.indexOf(old);
if (i > 0) {
String partBefore = input.substring(0, i);
String partAfter = input.substring(i + old.length());
input = partBefore + newWord + partAfter;
} else
loop = false;
} while (loop);
return input;
}
Here is the Code
import java.util.Scanner;
public class replacechar {
String line;
String s = "";
char from ;
char to ;
public replacechar()
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter The String");
line = scan.nextLine();
System.out.println("Enter The Character you want to changer");
from = scan.nextLine().charAt(0);
System.out.println("Enter the Character you want to replace with");
to = scan.nextLine().charAt(0);
replacecharacter(from,to);
}
public void replacecharacter(char f,char t)
{
for(int i =0;i< line.length();i++)
{
if(line.charAt(i) == f)
{
s += t;
}
else
{
s += line.charAt(i);
}
}
System.out.println(s);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
replacechar obj = new replacechar();
}
}
Not too sure if OP is still looking for answers but it might help others. Here is my code with just for loop and java's substring method...
public static void main(String ar[])
{
String str = "This is some string. replace lower case is with IS";
String pattern = "is";
String replaceWith = "IS"; // word to replace with
System.out.println(replaceString(str, pattern, replaceWith));
}
static String replaceString(String str, String pattern, String replaceWith) {
String temp = "";
String replacedString = ""; // Replaced String
int remainingString = 0; // append the rest of the string after last
// occurance of pattern.
for (int i = 0; i <= str.length() - pattern.length(); i++) {
temp = str.substring(i, i + 1);
if (str.substring(i, i + pattern.length()).equals(pattern)) {
temp = replaceWith + " ";
i += pattern.length();
}
remainingString = i;
replacedString += temp;
}
replacedString += str.substring(remainingString + 1, str.length());
return replacedString;
}
}
Posting this here incase somebody needs an implementation without using StringUtils helper methods.
static String replaceAll(String str, String oldW, String newW) {
// code here
char[] ch = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length;i++) {
if (ch[i] == oldW.charAt(0) && checkForString(i+1,oldW,str)) {
sb.append(newW);
i += oldW.length() -1;
}
else
sb.append(ch[i]);
}
return sb.toString();
}
static boolean checkForString(int i, String str,String ogStr) {
int start = i;
for (int j = 1; j < str.length() && i < ogStr.length(); j++, i++) {
if (ogStr.charAt(i) != str.charAt(j))
return false;
}
return (i-start+1) == str.length()?true:false;
}
OK, so I'm doing this project that requires that I have the first and last setters of a string appear with the number of letters in between them counted, and output. I've tried repurposing some reverse a string code I had handy, but I cannot get the output to appear in my IDE.
Can anyone look over my code, and make some suggestions?
public static void main(String[] args) {
String countWord;
countWord = JOptionPane.showInputDialog(null,
"Enter the string you wish to have formatted:");
}
static String countMe(String countWord) {
int count = 1;
char first = countWord.charAt (0);
char last = countWord.charAt(-1);
StringBuilder word = new StringBuilder();
for(int i = countWord.length() - 1; i >= 0; --i)
if (countWord.charAt(i) != first ) {
if (countWord.charAt(i) != last) {
count++;
}
}
return countWord + first + count + last;
}
}
Just build it using charAt():
return "" + str.charAt(0) + (str.length() - 2) + str.charAt(str.length() - 1);
The "" at the front causes the numeric values that follow to be concatenated as Strings (instead of added arithmetically).
A slightly more terse alternative is:
return countWord.replaceAll("(.).*(.)", "$1" + (str.length() - 2) + "$2")
Once you determined the first and last chars, it is no need for unnecessary conditions. Just try this:
static String countMe(String countWord) {
char first = countWord.charAt(0);
char last = countWord.charAt(countWord.length()-1);
int count=0;
for (int i = 1; i < countWord.length()-1; i++)
{
count++;
}
return first + String.valueOf(count) + last;
}
Or, if it is not mandatory to use for loop, you can make it simple as this
static String countMe(String countWord) {
char first = countWord.charAt(0);
char last = countWord.charAt(countWord.length()-1);
int count = countWord.substring(1, countWord.length()-1).length();
return first + String.valueOf(count) + last;
}
You could use the string.length() method to obtain the total length of the string. Your code would be something like:
int totalLength = countWord.length();
int betweenLength = totalLength - 2; // This gives the count of characters between first and last letters
char first = countWord.charAt(0);
char last = countWord.charAt(str.length() - 1);
String answer = first + betweenLength + last;
import javax.swing.JOptionPane;
public class Main{
public static void main(String[] args) {
String countWord;
countWord = JOptionPane.showInputDialog(null,
"Enter the word you wish to have formatted:");
JOptionPane.showMessageDialog(null, countMe(countWord));
}
static String countMe(String countWord) {
int count = 0;
String first = String.valueOf(countWord.charAt(0));
String last = String.valueOf(countWord.charAt(countWord.length() - 1));
for(int i = 1; i < countWord.length() - 1; i++) {
if (String.valueOf(countWord.charAt(i)) != first ) {
count++;
}
}
return first + count + last;
}
}
I want to allow the user use a "*" metachar in search and would like to use the pattern entered by user with Pattern.compile. So I would have to escape all the other metachars that user enters except the *. I am doing it with the below code, is there a better way of doing this?
private String escapePattern(String pattern) {
final String PATTERN_MATCH_ALL = ".*";
if(null == pattern || "".equals(pattern.trim())) {
return PATTERN_MATCH_ALL;
}
String remaining = pattern;
String result = "";
int index;
while((index = remaining.indexOf("*")) >= 0) {
if(index > 0) {
result += Pattern.quote(remaining.substring(0, index)) + PATTERN_MATCH_ALL;
}
if(index < remaining.length()-1) {
remaining = remaining.substring(index + 1);
} else
remaining = "";
}
return result + Pattern.quote(remaining) + PATTERN_MATCH_ALL;
}
How about
"\\Q" + pattern.replace("*", "\\E.*\\Q") + "\\E";