I'm writing these algorithms for a style-correcting program which makes adjustments to a java source file, that can compile without error. It is currently set to read the file line-by-line.
Right now, I'm having trouble writing 2 methods/algorithms which
Determine if the current line (string) has comments, and
finds where the comment starts
I currently have:
public static int FindComment (String TextLine) {
int EndOfCode = TextLine.lastIndexOf("; ");
return TextLine.indexOf("//", EndOfCode);
}
public static boolean HasComment (String TextLine) {
if (TextLine.contains("//"))
{
return true;
}
else
{
return false;
}
}
I know this is incorrect because I can have code, and comments, which contain " ; // ; //" as well as comments. I tried other conditional statements without success.
Hello you don't explain what problem do you have but I think you should escape with backslash characters when working with indexOf function.
Related
I have a collection of Strings saved in 2d array.
the string has a shape of horn-clause and the complete one string can be in the form of patient(?x) as well as hasdoctor(?x,?y)
if i write the ?x=alex and ?y=john then the above string takes a structure of
patient(alex)
hasdoctor(alex, john)
Now the Question is when is use the below code it finds the ?x, but in the hasdoctor(?x,?y) it skips the ?y .
void find_var(String[][] temp)
{
System.out.println(temp.length);
System.out.println(temp[0].length);
for(int i=0;i<temp.length;i++)
for(int j=1;j<temp[0].length-1;j++)
{
String text_to_parse=temp[i][j];
Pattern y = Pattern.compile("[?]\\w[,)]");
Matcher z= y.matcher(text_to_parse);
if(z.find())
{
System.out.println("Found at::"+temp[i][j]);
System.out.println(z.group());
}
else
{
System.out.println("Not found at::"+temp[i][j]);
}
}}
the pesudo code i can explain that i want in java is
if([?]\\w[,) is found in array[][])
if([?]\\w[,) is already in other_array[]
Then skip;
else
save [?]\\w[,) to other_array[]
Can't say that I completely understand what you're trying to achieve, but I think the problem is that you're using
if (z.find()) { /* ... */ }
instead of
while (z.find()) { /* ... */ }
Using if, the string will not be completely consumed and it will return after the first match is found.
[]this is a brief explanation of my program:
1- I made a listview of drug names(+8000 name)
2-Every name has a unique html document in assets folder
3- I made a search bar that search in the listview
[]problem: i wanted to imoprove the search function so that it can search inside every html file .
and this is my code :
// Filter Class to search in titles and inside html files
public void filter(String charText) throws FileNotFoundException {
charText = charText.toLowerCase(Locale.getDefault());
druglist.clear();
if (charText.length() == 0) {
druglist.addAll(arraylist);
} else {
int i=-1;
for (drugPopulation wp : arraylist) {
i++;
if (wp.getitem().toLowerCase(Locale.getDefault()).contains(charText)||Searchfor(charText, arraylisthtml.get(i).getitem())) {
druglist.add(wp);
}
}
}
notifyDataSetChanged();
}
*and this is my searchfor function :
private boolean Searchfor(String search, String s ) throws FileNotFoundException {
String path = "file:///android_asset/"+s;
Boolean yes=false;
final Scanner scanner = new Scanner(path);
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(search)) {
// a match!
yes=true;
break;
}
}
return yes;
}
[*]Results and questions :
1-When i run the app and try this search utility it doesn't return true results(i think the searchfor function always returns false ) ,is there a difference between searching in html files and searching in txt files and what can be the cause of these wrong results ?
2-the search is extremely slow , is there a way to improve it ?
Thanks in advance .
I can see that you only check if the file contains the certain word String search in this case, so you don't actually have to read the file line by line, you can just read it as a single string and then call .contains(search) on it, this should make the search a lot faster
Also:
Searchfor(charText, arraylisthtml.get(i).getitem())
Instead of Searchfor(charText, arraylisthtml.get(i).getitem()) you can just call Searchfor(charText, wp.getitem()) and get rid of the i.
But most of all, you should probably "preprocess" your data, by that I mean that if you have a way to group and order the files your are going to search trough, do so, and then search them with an optimized algorithm , i.e. alphabetical order - binary search.
You should really try doing that if you want to improve the speed of your search. Good luck! hope I was helpful.
I'm trying to create a method, that deletes empty lines at the end of a string:
public static String deleteBlankLinesAtEnd(String input)
{
input = trimToEmptyString(input);
return input.replaceFirst("\\n{2,}\\z", "");
}
However, it seems to also delete empty lines in the beginning of the input.
I got a little unit test:
#Test
public void testDeleteBlankLinesAtEnd()
{
assertEquals("hej", TextUtils.deleteBlankLinesAtEnd("hej\n\n"));
assertEquals("hej\nhej", TextUtils.deleteBlankLinesAtEnd("hej\nhej\n\n"));
assertEquals("hej\n\nhej", TextUtils.deleteBlankLinesAtEnd("hej\n\nhej\n\n"));
assertEquals("\n\nhej\n\nhej", TextUtils.deleteBlankLinesAtEnd("\n\nhej\n\nhej\n\n"));
}
The 3 first runs fine, the last one fails.
Update: Of course, the trimToEmptyString() was my problem, since it also trims the beginning..
public static String trimToEmptyString(String input)
{
if (input == null)
{
return "";
}
return input.trim();
}
So everything with the regex, was working fine.
The regex looks OK; I suspect there's a problem with trimToEmptyString().
You could do something like so:
public static String deleteBlankLinesAtEnd(String input)
{
input = trimToEmptyString(input);
return input.replaceFirst("\\n{2,}\\z$", "");
}
The $ should instruct the regex to match anything just before the end of the string. In this case, it should match any new lines which are just prior to the end of the string.
How about to replace all blank lines including lines full of spaces.
input.replaceFirst("\\n\\s+$", "\n")
As an exercise, the code block below intends to recursively go through a string and remove all the of the "x" characters. It does that, but I would like to keep track of the newStr without passing it as a parameter in the method. Is there anyway to move it into the method body?
Thanks!
public static String deathToX(String str, String newStr) {
//look for x char
if(str.substring(0, 1).equals("x")) {
//do nothing
} else {
//add non-x char to newStr
newStr += str.charAt(0);
}
if(str.length() == 1) {
return newStr;
}
return deathToX(str.substring(1), newStr);
}
public static void main(String[] args) {
System.out.println("Return: " + deathToX("xnoxmore", ""));
}
Well, you could change the code to:
public static String deathToX(String str)
{
// Termination case
if (str.length() == 0)
{
return str;
}
// Work out whether or not we want the first character
String prefix = str.startsWith("x") ? "" : str.substring(0, 1);
// Let the recursive call handle the rest of the string, and return
// the prefix (empty string or the first character) followed by the
// x-stripped remainder.
return prefix + deathToX(str.substring(1));
}
Is that the sort of thing you were thinking of?
Of course, this is a horribly inefficient way of doing string manipulation, but I assume you're more interested in the recursive nature of things.
I would like to keep track of the newStr without passing it as a parameter in the method.
Why? Passing the intermediary result into the function is often required in functional-style recursive programming. What I do is make a function that handles the bulk of the work and accepts the accumulator, and make a wrapper function that calls the previous one with the required starter value:
private static String deathToX0(String str, String newStr) {
// the original implementation
}
public static String deathToX(String str) {
return deathToX(str, "");
}
As an aside, you might not want to use a String for the intermediate result because of the copying involved. A StringBuilder would be faster.
The short answer is yes... with recursion typically on the way down the tree you work out the bit at each level in this case blank or the current character. So the return statement should call itself recursively then at the bottom of the tree the answer you wanted is reconstructed by adding together the sections at each level.
public static String deathToX(String str){
if (!str.isEmpty()){
return (str.substring(0, 1).equals("x") ? "" : str.substring(0, 1)) + deathToX(str.substring(1));
}else{
return "";
}
}
public static void main(String[] args){
System.out.println("Return: " + deathToX("xnoxmore"));
}
In the sample above I used the shorthand if format to put it all on one line but you could expand it out. You should be able to see that the recursive function recurses on the return statement and I put in a special case for the last level. If you were to split it and put this levels answer in a local variable e.g. tmp then you would use:
return tmp + deathToX(str.substring(1));
Remember recursion means that the current execution is only paused until the lower ones finish so you can happily store info to recover on your way back up. Hope this helps :)
public class solution {
// Return the changed string
public static String removeX(String input){
if(input.equals("") || input.equals("x"))
return "";
String returnStr="";
removeX(input.substring(1));
for(int i=0;i<input.length();i++)
{
if(input.charAt(i)=='x')
continue;
else
returnStr+=input.charAt(i);
}
return returnStr;
}
}
This is my approach. This code goes to the end of the string, if it gets X as last string, it returns ""(nothing), then it checks the whole substring for "x", if its present in the string, it will continue, else it will append rest character to that string and it goes on.
Finally returns the updated string.!
Hope this helps..!! well, this is my first contribution here :)
I know there are plenty of upper() methods in Java and other frameworks like Apache commons lang, which convert a String to all upper case.
Are there any common libraries that provide a method like isUpper(String s) and isLower(String s), to check if all the characters in the String are upper or lower case?
EDIT:
Many good answers about converting to Upper and comparing to this. I guess I should have been a bit more specific, and said that I already had thought of that, but I was hoping to be able to use an existing method for this.
Good comment about possible inclusion of this in apache.commons.lang.StringUtils.
Someone has even submitted a patch (20090310). Hopefully we will see this soon.
https://issues.apache.org/jira/browse/LANG-471
EDIT:
What I needed this method for, was to capitalize names of hotels that sometimes came in all uppercase. I only wanted to capitalize them if they were all lower or upper case.
I did run in to the problems with non letter chars mentioned in some of the posts, and ended up doing something like this:
private static boolean isAllUpper(String s) {
for(char c : s.toCharArray()) {
if(Character.isLetter(c) && Character.isLowerCase(c)) {
return false;
}
}
return true;
}
This discussion and differing solutions (with different problems), clearly shows that there is a need for a good solid isAllUpper(String s) method in commons.lang
Until then I guess that the myString.toUpperCase().equals(myString) is the best way to go.
Now in StringUtils isAllUpperCase
This if condition can get the expected result:
String input = "ANYINPUT";
if(input.equals(input.toUpperCase())
{
// input is all upper case
}
else if (input.equals(input.toLowerCase())
{
// input is all lower case
}
else
{
// input is mixed case
}
Not a library function unfortunately, but it's fairly easy to roll your own. If efficiency is a concern, this might be faster than s.toUpperCase().equals(s) because it can bail out early.
public static boolean isUpperCase(String s)
{
for (int i=0; i<s.length(); i++)
{
if (!Character.isUpperCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Edit: As other posters and commenters have noted, we need to consider the behaviour when the string contains non-letter characters: should isUpperCase("HELLO1") return true or false? The function above will return false because '1' is not an upper case character, but this is possibly not the behaviour you want. An alternative definition which would return true in this case would be:
public static boolean isUpperCase2(String s)
{
for (int i=0; i<s.length(); i++)
{
if (Character.isLowerCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Not that i know.
You can copy the string and convert the copy to lower/upper case and compare to the original one.
Or create a loop which checks the single characters if the are lower or upper case.
This method might be faster than comparing a String to its upper-case version as it requires only 1 pass:
public static boolean isUpper(String s)
{
for(char c : s.toCharArray())
{
if(! Character.isUpperCase(c))
return false;
}
return true;
}
Please note that there might be some localization issues with different character sets. I don't have any first hand experience but I think there are some languages (like Turkish) where different lower case letters can map to the same upper case letter.
Guava's CharMatchers tend to offer very expressive and efficient solutions to this kind of problem.
CharMatcher.javaUpperCase().matchesAllOf("AAA"); // true
CharMatcher.javaUpperCase().matchesAllOf("A SENTENCE"); // false
CharMatcher.javaUpperCase().or(CharMatcher.whitespace()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaUpperCase().or(CharMatcher.javaLetter().negate()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaLowerCase().matchesNoneOf("A SENTENCE"); // true
A static import for com.google.common.base.CharMatcher.* can help make these more succinct.
javaLowerCase().matchesNoneOf("A SENTENCE"); // true
Try this, may help.
import java.util.regex.Pattern;
private static final String regex ="^[A-Z0-9]"; //alpha-numeric uppercase
public static boolean isUpperCase(String str){
return Pattern.compile(regex).matcher(str).find();
}
with this code, we just change the regex.
I realise that this question is quite old, but the accepted answer uses a deprecated API, and there's a question about how to do it using ICU4J. This is how I did it:
s.chars().filter(UCharacter::isLetter).allMatch(UCharacter::isUpperCase)
If you expect your input string to be short, you could go with myString.toUpperCase().equals(myString) as you suggested. It's short and expressive.
But you can also use streams:
boolean allUpper = myString.chars().noneMatch(Character::isLowerCase);
You can use java.lang.Character.isUpperCase()
Then you can easily write a method that check if your string is uppercase (with a simple loop).
Sending the message toUpperCase() to your string and then checking if the result is equal to your string will be probably slower.
Here's a solution I came up with that's a bit universal as it doesn't require any libraries or special imports, should work with any version of Java, requires only a single pass, and should be much faster than any regex based solutions:
public static final boolean isUnicaseString(String input) {
char[] carr = input.toCharArray();
// Get the index of the first letter
int i = 0;
for (; i < carr.length; i++) {
if (Character.isLetter(carr[i])) {
break;
}
}
// If we went all the way to the end above, then return true; no case at all is technically unicase
if (i == carr.length) {
return true;
}
// Determine if first letter is uppercase
boolean firstUpper = Character.isUpperCase(carr[i]);
for (; i < carr.length; i++) {
// Check each remaining letter, stopping when the case doesn't match the first
if (Character.isLetter(carr[i]) && Character.isUpperCase(carr[i]) != firstUpper) {
return false;
}
}
// If we didn't stop above, then it's unicase
return true;
}