How replace a phrase using charAt()? - for-loop

I am having trouble with this method. It is supposed to receive a sentence (word) and replace any instance of dang with #!.
It works in some cases but when the input is "dang boom dang" the output is #! boom da#!.
Does anyone have any suggestions on how to fix this?
Here is my code so far:
public static String deleteDang(String word)
{
StringBuffer wordSB = new StringBuffer(word);
int length = wordSB.length();
for (int i = 0; i < length; i++)
{
if (word.charAt(i)=='d'|| word.charAt(i)=='D')
if (word.charAt(i+1)=='a'|| word.charAt(i+1)=='A')
if (word.charAt(i+2)=='n'|| word.charAt(i+2)=='N')
if (word.charAt(i+3)=='g'|| word.charAt(i+3)=='G')
wordSB = wordSB.replace(i,i+4, "#!");
length = wordSB.length();
}
String newWord = wordSB.toString();
return newWord;
}

In your for loop replace all references to word with wordSB
public static String deleteDang(String word)
{
StringBuffer wordSB = new StringBuffer(word);
int length=wordSB.length();
for (int i=0; i<length; i++)
{
if (wordSB.charAt(i)=='d'|| wordSB.charAt(i)=='D')
if (wordSB.charAt(i+1)=='a'|| wordSB.charAt(i+1)=='A')
if (wordSB.charAt(i+2)=='n'|| wordSB.charAt(i+2)=='N')
if (wordSB.charAt(i+3)=='g'|| wordSB.charAt(i+3)=='G')
wordSB = wordSB.replace(i,i+4, "#!");
length=wordSB.length();
}
String newWord= wordSB.toString();
return newWord;
}
That way you reference the updated array when you do a replace

Related

Is there a way to avoid the truncation of attached properties when using Appcenter with Xamarin?

Here's my code:
Crashes.TrackError(ex,
new Dictionary<string, string> {
{"RunQuery", "Exception"},
{"sql", s },
{"Device Model", DeviceInfo.Model },
{"Exception", ex.ToString()}
});
Everything works but I find that Appcenter limits the length of the parameters to 125 characters so it's useless for me as I can never see all of the sql or the ex string.
Has anyone found a way to get around this?
I ran into the same problem. My solution was to break my string into groups of 125 character strings and iterate through while logging. I chatted with AppCenter support. They have no way of extending this length currently.
Here is a scrubbed version of my code:
var tokenChunks = LoggingHelper.SplitBy(extremelyLongString, 120);
string title = "Long string here";
var props = new Dictionary<string, string>();
int item = 0;
foreach(string chunk in tokenChunks)
{
string chunkIndex = string.Format("item: {0}", item++);
props.Add(chunkIndex, chunk);
}
Analytics.TrackEvent(title, props);
Where the LoggingHelper class is:
public static class LoggingHelper
{
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
}
I should give credit to this post https://stackoverflow.com/a/8944374/117995 by #oleksii for the SplitBy method.

No need to check this! skip

So what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute is
a single line in the text f
import java.util.Scanner;
import java.io.*;
public class hello
{
public static void main(String[] args) throws IOException
{
Scanner Keyboard = new Scanner(System.in);
System.out.print();
String response = Keyboard.nextLine();
File inFile = new File(response);
Scanner route = new Scanner(inFile);
while ()
{
System.out.print(");
String word = Keyboard.next();
String Street = route.next();
String stopNum = route.next();
You are closing your file after you read one "line" (actually, I'm not sure how many lines you're reading - you don't call nextLine). You also aren't parsing the line. Also, I'd prefer a try-with-resources over an explicit close (and many of your variables look like class names). Finally, you need to check if the line matches your criteria. That might be done like,
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter filename >> ");
String response = keyboard.nextLine();
File inFile = new File(response);
System.out.print("Enter tram tracker ID >> ");
String word = keyboard.nextLine(); // <-- read a line. Bad idea to leave trailing
// new lines.
try (Scanner route = new Scanner(inFile)) {
while (route.hasNextLine()) {
String[] line = route.nextLine().split("\\^");
String street = line[0];
String stopNum = line[1];
String trkID = line[2];
String road = line[3];
String suburb = line[4];
if (!trkID.equals(word)) {
continue;
}
System.out.printf("street: %s, stop: %s, id: %s, road: %s, suburb: %s%n",
street, stopNum, trkID, road, suburb);
}
}
Your code print everything in the file.
To print a line with an given ID:
You can first buffer all lines of the file into a ArrayList like this in the main method:
ArrayList<String> lines = new ArrayList<>();
while (route.hasNextLine())
{
lines.add(route.nextLine());
}
Then create a method to find a line with a specific ID:
public static int find(ArrayList information, int ID)
{
String idString = "" + ID;
ListIterator<String> li = information.listIterator();
String currentLine = "";
int index = 0;
while(li.hasNext())
{
currentLine = li.next();
int count = 0;
int index1 = 0;
int index2 = 0;
/*Trying to locate the string between the 2nd and 3rd ^ */
for(int i = 0; i < currentLine.length(); i++)
{
if(currentLine.substring(i, i+1).equals("^"))
{
count++;
if(count == 2)
index1 = i;
else if(count == 3)
{
index2 = i;
break;
}
}
}
if(currentLine.substring(index1+1, index2).equals (idString))
return(index);
index++;
}
//If no such ID found, return -1;
return -1;
}
In the main method:
System.out.println("enter an ID")
int ID = Integer.parseInt(Keyboard.next());
int lineNumber = find(lines, ID);
if(lineNumber == -1)
System.out.println("no information found");
else
System.out.println(lines.get(lineNumber));

Java - For loop within ArrayList<String> method only returns one element

I am trying to use an ArrayList of string values from one table, modify the strings based on whether or not the string ends with ".tif" or ".tiff", then transfer the resulting strings to a new table. However, when I invoke this method, the new table only receives the first modified string. I'm not sure what is wrong with my logic, the first element of the original table would be checked to see if it satisfies a condition (either ending in ".tif" or ".tiff") then from there that string would be modified, added to the ArrayList fData, then iterate to the next table value. I don't understand why the method doesn't return more than one element contained within fData?
public ArrayList<String> getTableData() {
StringBuilder str = new StringBuilder();
String fString = null;
ArrayList<String> fData = new ArrayList<String>();
while(filePaths != null) {
int size = filePaths.size();
for (int i = 0; i <= size; i++) {
String pathName = filePaths.get(i);
if (pathName.endsWith(".tif")) {
int pathLength = pathName.length();
str = new StringBuilder(filePaths.get(i));
str.insert(pathLength - 4, "_Data");
fString = str.toString();
fData.add(fString);
tableModel2.addRow(new String[] { fString });
return fData;
}
else if (pathName.endsWith(".tiff")) {
int pathLength = pathName.length();
str = new StringBuilder(filePaths.get(i));
str.insert(pathLength - 5, "_Data");
fString = str.toString();
fData.add(fString);
tableModel2.addRow(new String[] { fString });
return fData;
}
}
tableModel2.fireTableDataChanged();
}
return null;
}
`
It appears that you are returning from getTableData() as soon as you do a single replacement. Instead, you should return only after having iterated over every file path.
Remove the return statements inside the loops and instead replace return null at the end with return fData.

Morse code conversion on how to return a method

Please pardon me for my weak porgramming ability. I'm trying to write a method converting english to morse code. As you can see, I use hashmap to store the equivalant and then convert it and stored the morse code into the variable 'result'. My concern is I can't return the variable 'result' outside of the loop. If i return 'dataInput', isn't it just returning the original input? How can I return the correct result?
public static String morseCode(String dataInput)
{
Map<String, String> morseCode = new HashMap<String, String>();
morseCode.put("a", ".-");
morseCode.put("b", "-...");
morseCode.put("c", "-.-.");
for (int i = 0; i<dataInput.length(); i++)
{
String result = (String)morseCode.get(dataInput.charAt(i)+"");
//convert input data into morse code
}
return dataInput;
}
Try like this:
import java.lang.StringBuffer; //at the top
Map morseCode = new HashMap();
morseCode.put("a", ".-");
morseCode.put("b", "-...");
morseCode.put("c", "-.-.");
StringBuffer buff = new StringBuffer();
for (int i = 0; i<dataInput.length(); i++)
{
String result = (String)morseCode.get(dataInput.charAt(i));
//convert input data into morse code
buff.append(result+" ");
}
return buff.toString();
}

How to get a substring in some length for special chars like Chinese

For example, I can get 80 chars with {description?substring(0, 80)} if description is in English, but for Chinese chars, I can get only about 10 chars, and there is a garbage char at the end always.
How can I get 80 chars for any language?
FreeMarker relies on String#substring to do the actual (UTF-16-chars-based?) substring calculation, which doesn't work well with Chinese characters. Instead one should uses Unicode code points. Based on this post and FreeMarker's own substring builtin I hacked together a FreeMarker TemplateMethodModelEx implementation which operates on code points:
public class CodePointSubstring implements TemplateMethodModelEx {
#Override
public Object exec(List args) throws TemplateModelException {
int argCount = args.size(), left = 0, right = 0;
String s = "";
if (argCount != 3) {
throw new TemplateModelException(
"Error: Expecting 1 string and 2 numerical arguments here");
}
try {
TemplateScalarModel tsm = (TemplateScalarModel) args.get(0);
s = tsm.getAsString();
} catch (ClassCastException cce) {
String mess = "Error: Expecting numerical argument here";
throw new TemplateModelException(mess);
}
try {
TemplateNumberModel tnm = (TemplateNumberModel) args.get(1);
left = tnm.getAsNumber().intValue();
tnm = (TemplateNumberModel) args.get(2);
right = tnm.getAsNumber().intValue();
} catch (ClassCastException cce) {
String mess = "Error: Expecting numerical argument here";
throw new TemplateModelException(mess);
}
return new SimpleScalar(getSubstring(s, left, right));
}
private String getSubstring(String s, int start, int end) {
int[] codePoints = new int[end - start];
int length = s.length();
int i = 0;
for (int offset = 0; offset < length && i < codePoints.length;) {
int codepoint = s.codePointAt(offset);
if (offset >= start) {
codePoints[i] = codepoint;
i++;
}
offset += Character.charCount(codepoint);
}
return new String(codePoints, 0, i);
}
}
You can put an instance of it into your data model root, e.g.
SimpleHash root = new SimpleHash();
root.put("substring", new CodePointSubstring());
template.process(root, ...);
and use the custom substring method in FTL:
${substring(description, 0, 80)}
I tested it with non-Chinese characters, which still worked, but so far I haven't tried it with Chinese characters. Maybe you want to give it a try.

Resources