-8

Edit: To those who downvote me, this question is difference from the duplicate question which you guy linked. The other question is about returning the indexes. However, for my case, I do not need the index. I just want to check whether there is duplicate.

This is my code:

        String word = "ABCDE<br>XYZABC";
        String[] keywords = word.split("<br>");
        for (int index = 0; index < keywords.length; index++) {
            if (keywords[index].toLowerCase().contains(word.toLowerCase())) {
                if (index != (keywords.length - 1)) {
                    endText = keywords[index];
                    definition.setText(endText);
                }
            }

My problem is, if the keywords is "ABC", then the string endText will only show "ABCDE". However, "XYZABC" contains "ABC" as well. How to check if the string has multiple occurrence? I would like to make the definition textview become definition.setText(endText + "More"); if there is multiple occurrence.

I tried this. The code is working, but it is making my app very slow. I guess the reason is because I got the String word through textwatcher.

        String[] keywords = word.split("<br>");
        for (int index = 0; index < keywords.length; index++) {
            if (keywords[index].toLowerCase().contains(word.toLowerCase())) {
                if (index != (keywords.length - 1)) {
                    int i = 0;
                    Pattern p = Pattern.compile(search.toLowerCase());
                    Matcher m = p.matcher( word.toLowerCase() );
                    while (m.find()) {
                        i++;
                    }
                    if (i > 1) {
                        endText = keywords[index];
                        definition.setText(endText + " More");
                    } else {
                        endText = keywords[index];
                        definition.setText(endText);
                    }
                }
            }
        }

Is there any faster way?

AesSedai101
  • 1,502
  • 2
  • 23
  • 37
user2872856
  • 2,003
  • 2
  • 21
  • 54
  • 5
    Possible duplicate of [Indexes of all occurrences of character in a string](https://stackoverflow.com/questions/5034442/indexes-of-all-occurrences-of-character-in-a-string) – Amit Vaghela Oct 07 '17 at 07:52
  • This question is difference from the duplicate question which you linked. The other question is about returning the indexes. However, for my case, I do not need the index. I just want to check whether there is duplicate. – user2872856 Oct 07 '17 at 08:34
  • if count is greater than one than it is duplicate – Amit Vaghela Oct 07 '17 at 08:35
  • Ok, so my question is how. It is simple thing for you, but difficult for self-learner like me. – user2872856 Oct 07 '17 at 08:39
  • okay. please tell me if you need further help@user2872856 – Amit Vaghela Oct 07 '17 at 08:58
  • I have edited my question. I tried pattern and matcher but it is too slow. – user2872856 Oct 07 '17 at 09:03
  • @user2872856 I didn't understood what you exactly want to do! if you want to split word "ABCDE
    XYZABC" by
    there is no double occurrence of any splited word. i.e "ABCDE" is ony one time occurred and also word "XYZABC"
    – SiSa Oct 13 '17 at 09:59
  • After the string is split, the `endText` will only show one split string, which is "ABCDE". "XYZABC" will be hidden. I need a way to let the user know there is hidden string. – user2872856 Oct 13 '17 at 12:17
  • @user2872856 if you only want to show there is more than one work you can check it by length of keywords. `String[] keywords = word.split("
    ");` `if(keywords.length > 1) { /*has more word*/ }`
    – SiSa Oct 14 '17 at 07:52
  • The problem is, if my string is "ABCDE
    XYZ", using `keywords.length > 1` will mistakenly show that there is more than one word if the search term is "ABC".
    – user2872856 Oct 14 '17 at 14:29
  • 1
    @user2872856 You are not clear in your question!!! How do you choose your search term?! And you only want to find the occurrence of search word in string?! – SiSa Oct 14 '17 at 18:02

5 Answers5

3

It's a little hard for me to understand your question, but it sounds like:

You have some string (e.g. "ABCDE<br>XYZABC"). You also have some target text (e.g. "ABC"). You want to split that string on a delimiter (e.g. "<br>", and then:

  • If exactly one substring contains the target, display that substring.
  • If more than one substring contains the target, display the last substring that contains it plus the suffix "More"

In your posted code, the performance is really slow because of the Pattern.compile() call. Re-compiling the Pattern on every loop iteration is very costly. Luckily, there's no need for regular expressions here, so you can avoid that problem entirely.

    String search = "ABC".toLowerCase();
    String word = "ABCDE<br>XYZABC";
    String[] keywords = word.split("<br>");
    int count = 0;

    for (String keyword : keywords) {
        if (keyword.toLowerCase().contains(search)) {
            ++count;
            endText = keyword;
        }
    }

    if (count > 1) {
        definition.setText(endText + " More");
    }
    else if (count == 1) {
        definition.setText(endText);
    }
Ben P.
  • 52,661
  • 6
  • 95
  • 123
1

You are doing it correctly but you are doing unnecessary check which is if (index != (keywords.length - 1)). This will ignore if there is match in the last keywords array element. Not sure is that a part of your requirement. To enhance performance when you found the match in second place break the loop. You don't need to check anymore.

public static void main(String[] args) {
    String word = "ABCDE<br>XYZABC";
    String pattern = "ABC";
    String[] keywords = word.split("<br>");

    String endText = "";
    int count = 0;

    for (int index = 0; index < keywords.length; index++) {
        if (keywords[index].toLowerCase().contains(pattern.toLowerCase())) {
            //If you come into this part mean found a match.
            if(count == 1) {
                // When you found the second match it will break to loop. No need to check anymore
                // keep the first found String and append the more part to it
                endText += " more";
                break;
            }
            endText = keywords[index];
            count++;
        }
    }
    System.out.println(endText);
}

This will print ABCDE more

Neero
  • 226
  • 2
  • 7
  • 23
0

Hi You have to use your condition statement like this

if (word.toLowerCase().contains(keywords[index].toLowerCase()))
Raja
  • 2,775
  • 2
  • 19
  • 31
0

You can use this:

String word = "ABCDE<br>XYZABC";
String[] keywords = word.split("<br>");
for (int i = 0; i < keywords.length - 1; i++) {
    int c = 0;

    Pattern p = Pattern.compile(keywords[i].toLowerCase());
    Matcher m = p.matcher(word.toLowerCase());
    while (m.find()) {
        c++;
    }

    if (c > 1) {
        definition.setText(keywords[i] + " More");
    } else {
        definition.setText(keywords[i]);
    }
}

But like what I mentioned in comment, there is no double occurrence in word "ABCDE<br>XYZABC" when you want to split it by <br>.
But if you use the word "ABCDE<br>XYZABCDE" there is two occurrence of word "ABCDE"

SiSa
  • 2,594
  • 1
  • 15
  • 33
  • You answer is same as what I have tried. As I mentioned, this method is very slow. I need a less processor consuming method. – user2872856 Oct 13 '17 at 12:12
0
void test() {
    String word = "ABCDE<br>XYZABC";
    String sequence = "ABC";

    if(word.replaceFirst(sequence,"{---}").contains(sequence)){
       int startIndex =  word.indexOf(sequence);
       int endIndex =  word.indexOf("<br>");
        Log.v("test",word.substring(startIndex,endIndex)+" More");
    }
    else{
            //your code
    }
}

Try this

shb
  • 5,957
  • 2
  • 15
  • 32