1
\$\begingroup\$

I have various strings that contain codes, e.g. like this:

"file = new JarFile(new File()" + "\nSystem.out.println(file"

but also

"args"

Now I want to find the substring that is in the beginning and in the end of the string. E.g. in the first case the result would be file. In the second example the result has to be args

I now wrote the following method:

public static String findWord(String text) {
 String result = null;
 boolean found = false;
 for (int i = 0; i < text.length(); i++) {
 for (int j = 0; j < text.length(); j++) {
 String first = text.substring(0, i*j);
 String last = text.substring(text.length() - i*j, text.length());
 if (first.equals(last) && first.length() > 0) {
 result = first;
 found = true;
 break;
 }
 }
 if (found) {
 break;
 }
 }
 return result;
 }

This seems to work for the test cases I tested, but I'm not sure if it works for all cases. Additionally, I'm not sure if there isn't a simpler solution. I need two loops and ugly break statements. So how could I improve that?

palacsint
30.3k9 gold badges81 silver badges157 bronze badges
asked May 11, 2012 at 21:49
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I'm not completely sure about the requirements, but what about the following?

public static String findWord2(final String text) {
 for (int i = text.length() - 1; i > 0 ; i--) {
 final String first = text.substring(0, i);
 final String last = text.substring(text.length() - i);
 if (first.equals(last)) {
 return first;
 }
 }
 return text;
}

Here are my tests:

import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class FindWords2Test {
 private final String expected;
 private final String input;
 public FindWords2Test(final String expected, final String input) {
 this.expected = expected;
 this.input = input;
 }
 @Parameters
 public static Collection<String[]> data() {
 //@formatter:off
 final String[][] data = new String[][] { 
 {"file", "file = new JarFile(new File()\nSystem.out.println(file"},
 {"file ", "file = new JarFile(new File()\nSystem.out.println(file "},
 {"file = new JarFile(new File()\nSystem.out.println(", 
 "file = new JarFile(new File()\nSystem.out.println("}, 
 {"args", "args"},
 {"", ""}, 
 {"a", "a"}, 
 {"a", "aa"}};
 //@formatter:on
 return Arrays.asList(data);
 }
 @Test
 public void testFindWords() throws Exception {
 assertEquals(expected, FindWords2.findWord2(input));
 }
}
answered May 11, 2012 at 22:27
\$\endgroup\$
1
  • \$\begingroup\$ Wow, I never knew about that Parameterized runner. Looks quite useful. :) \$\endgroup\$ Commented May 12, 2012 at 22:52
1
\$\begingroup\$

Firstly, if you are actually working with code, there is a good chance whatever you are doing would be better done with a real parser then whatever string hackery you are proposing.

Secondly, I believe your code will throw exceptions for "argst".

Thirdly, your problem need a bit better defining. There may be multiple substrings that exist at the beginning and end of the string. In any case, you always have the trivial empty string and the whole string. You need to define exactly which solution you are trying to find

public static String findWord(String text) {
 String result = null;
 boolean found = false;

You don't need two variables, just check if result == null

 for (int i = 0; i < text.length(); i++) {

I don't know why you included this outer loop. At any rate for i == 0, the inner loop never succeeds.

 for (int j = 0; j < text.length(); j++) {

This loop misses the case of the whole string. It should be j <= text.length()

 String first = text.substring(0, i*j);
 String last = text.substring(text.length() - i*j, text.length());

If you elide the second parameter, it takes to the end of the list

 if (first.equals(last) && first.length() > 0) {

You can skip the second text by starting i and j at 1.

 result = first;
 found = true;
 break;

Just return. It'll make the code much cleaner

 }
 }
 if (found) {
 break;
 }
 }
 return result;
 }
answered May 12, 2012 at 5:34
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.