Print combination of characters given a sequence - java

I was working on the recursive code to print all possible output strings for an input sequence. For simplification I am going to shorten the problem. I have a String[] array. I want to print all possible combinations of words from [0] to [N] considering only one character from a String at a time. Example: String[] a = {"abc", "def", "ghi"} I should be printing adg, adh, adi, aeg.. etc
Here is my recursive code:
void printLetters(String[] list, int count, String result)
{
if(list == null)
return;
if(count > list.length-1)
{
System.out.println(result);
return;
}
for(int i = 0; i<list[count].length(); i++)
{
printLetters(list, count++, result + list[count].charAt(i) + "");
}
}
My code is running into an infinite loop as I am getting a StackOverflowError. Can someone point out my mistake?

The problem is that you are post-incrementing here:
printLetters(list, count++, result + list[count].charAt(i) + "");
So the recursive call occurs first, then the increment, which practically means you keep calling the method with the same value of count. Use this instead:
printLetters(list, count + 1, result + list[count].charAt(i) + "");
And are you sure you want to increment count? Because when the recursive call returns you will have count + 1 also in the "parent method", which I don't think is what you need.

Related

Simple Java question using while loop, substring, and indexOf

I'm working on an exercise for learning Java where I am supposed to write a method to print to the screen all items that come after the word "category:". This is my attempt at it:
public static void main(String[] args) {
String str = "We have a large inventory of things in our warehouse falling in "
+ "the category:apperal and the slightly "
+ "more in demand category:makeup along with the category:furniture and _.";
printCategories(str);
}
public static void printCategories(String passedString) {
int startOfSubstring = passedString.indexOf(":") + 1;
int endOfSubstring = passedString.indexOf(" ", startOfSubstring);
String categories = passedString.substring(startOfSubstring,endOfSubstring);
while(startOfSubstring > 0) {
System.out.println(categories);
startOfSubstring = passedString.indexOf((":") + 1, passedString.indexOf(categories));
System.out.println(startOfSubstring);
System.out.println(categories);
}
}
So the program should print:
apperal
makeup
furniture
My attempt is that the program should print the substring where it finds the starting index as ":" and the ending index as " ". Then it does the same thing again, only except from starting the very beginning of the variable str, this time it starts from the beginning of the last category found.
Once there are no more ":" to be found, the indexOf (part of startOfSubstring) will return -1 and the loop will terminate. However, after printing the first category it keeps returning -1 and terminating before finding the next category.
The two lines:
System.out.println(startOfSubstring);
System.out.println(categories);
Confirm that it is returning -1 after printing the first category, and the last line confirms that the categories variable is still defined as "apperal". If I comment out the line:
startOfSubstring = passedString.indexOf((":") + 1, passedString.indexOf(categories));
It returns the startOfSubstring as 77. So it is something to do with that line and attempting to change the start of search position in the indexOf method that is causing it to return -1 prematurely, but I cannot figure out why this is happening. I've spent the last few hours trying to figure it out...
Please help :(
There are a couple of issues with the program:
You're searching passedString for (":") + 1 which is the string ":1", probably not what you want.
You should evaluate endOfSubstring and categories inside the loop.
This is probably close to what you want:
public static void printCategories(String passedString) {
int startOfSubstring = passedString.indexOf(":") + 1;
while(startOfSubstring > 0) {
int endOfSubstring = passedString.indexOf(" ", startOfSubstring);
// If "category:whatever" can appear at the end of the string
// without a space, adjust endOfSubstring here.
String categories = passedString.substring(startOfSubstring, endOfSubstring);
// Do something with categories here, maybe print it?
// Find next ":" starting with end of category string.
startOfSubstring = passedString.indexOf(":", endOfSubstring) + 1;
}
}
I have corrected (in a comment) where you set the new value of startOfSubstring
while(startOfSubstring > 0) { // better if you do startOfSubstring != -1 IMO
System.out.println(categories);
// this should be startOfSubstring = passedString.indexOf(":", startOfSubstring +1);
startOfSubstring = passedString.indexOf((":") + 1, passedString.indexOf(categories));
System.out.println(startOfSubstring);
System.out.println(categories);
}

How many times the word is used on the html page

I have a method that should return an integer which is the number of uses of the searchWord in the text of an HTML document:
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
if (bodyText.toLowerCase().contains(searchWord.toLowerCase())){
count++;
}
return count;
}
But my method always returns count=1, even if the word is used several times. I understand that the error should be obvious, but I’m stuck and I don’t see it.
You are currently only checking once that the text contains the search word, so the count will always be either 0 or 1. To find the total count, keep looping using String#indexOf(str, fromIndex) while the String can be found using the second argument that indicates the index to start searching from.
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
for(int idx = -1; (idx = bodyText.indexOf(searchWord, idx + 1)) != -1; count++);
return count;
}
According to the Java docs String#contains:
Returns true if and only if this string contains the specified sequence of char values.
You're asking if the word you're looking for is contained in the document, which it is.
You could:
Split the text on words (splitting it by spaces) and then count how many times it appears
Iterate the String using String#indexOf starting on index 0 and then from last index you found until the end of the String.
Iterate the String using contains but starting from a certain index (doing this logic yourself).
I'd go for the 2nd approach as it seems like the easiest one.
These are only conditional statements, you aren't looping through the HTML text, therefor, if it finds the instance of searchWord in bodyText, it'll increment it, and then exit the method with a value of 1. I suggest looping through every word in the html, adding it to an array, and counting it that way using something like this:
char[] bodyTextA = bodyText.toCharArray();
Or keep it in a string array and split it by a space, or new line, or whatever criteria you have. Example of space:
//puts hello, i'm, your, and string into their own array slots in the array
/split
str = "Hello I'm your String";
String[] split = str.split("\\s+");
Your issue here is that the if statement is checking if the text contains the word and the increments your count variable. So even if it contains the word multiple time, your logic goes basically, if it contains it at all, increase count by one. You will have to rewrite your code to check for multiple occurrences of the word. There are many ways you can go about this, you could loop through the entire body text, you could split the body text into an array of words and check that, or you could remove the search word from the text each time you find it and keep checking until it no longer contains the search word.
You can use indexOf(,) with an index for the last found word
public int searchForWord(String searchWord) {
int count = 0;
if(this.htmlDocument == null){
System.out.println("ERROR! Call crawl() before performing analysis on the document");
}
System.out.println("Searching for the word " + searchWord + "...");
String bodyText = this.htmlDocument.body().text();
int index = 0;
while ((index = bodyText.indexOf(searchWord, index + 1)) != -1) {
count++;
}
return count;
}

Java: I compare two Strings but it didn't recognize it

I have this problem:
I wrote this function because I need to get the index of the occurrence of a particular string st in a String array
static public int indicestring(String[] array, String st) {
int ret = -1;
for (int i = 0; i < array.length; i++){
if (st.equals(array[i])) {
ret=i;
break;
}
}
return ret;
}
I then called:
System.out.println("indicestring(NODO,"ET2"));
and I got the correct number.
But then when I do:
String[] arcos2 = linea.split("-");//reading from a file and separating by "-"
String aux = arcos2[1];
System.out.println(arcos2[1]);
System.out.println(aux);
if (aux.equals(arcos2[1])) {
System.out.println("Is equal 1");
}
if (aux.equals("ET2")) {
System.out.println("Is equal 2");
}
if ("ET2".equals(aux)) {
System.out.println("is equal 3");
}
The first two prints were ET2, but then it only printed of the 3 ifs is "Is equal 1".... The thing is I have nearly 200 nodes like "ET2" and only 3 are failing and giving me -1 in the first function...
My question is....Am I using wrong the arrays to save and compare the data, because if aux=arcos2[1]="ET2", why is 'aux.equals("ET2") 'or 'arcos2[1].equals("ET2)' not working
? Is ther another function you can recommend to try?(I tried changing equals with compareTo() == 0 and that didn't work either and trimming was also recommended).
Before, I had a similar error where I compare two arrays like this:
if(a[0] == b[0] && a[1] == b[1])
There was a case that clearly was correct but it was ignored...
But it got corrected when a i changed it to:
if (Arrays.equals(a, b))
Is there maybe some change like that
You should put a debug break point in the code and add expression watches to identify the root cause of the problem.

Error in creating an array that converts Strings to Doubles and stores them

I'm trying to write a code that given a sequence, (private double[] sequence mentioned earlier in the code defining a sequence), will seperate the strings into an array and then assign the string values into doubles using the Double.parseDouble. The results i get from println are so strange though.
When i enter "2,3,4" as the value for s, the result displays as:
s: 2,3,4
result: [D#1d733e1
This is my code:
...
public Sequence(String s)
{
String[] tokens = s.split(",");
System.out.println("s: " + s);
double[] result = new double[tokens.length];
int i = 0;
for(String token:tokens){
result[i++] = Double.parseDouble(token);
}
System.out.println("result: " + result);
}
}
And i don't know why it's outputting those strange results.
Following this method, i created another method to determine if the values inside the array are equal to each other. This is the code i used for it:
public boolean allEqual()
{double name = sequence[0];
for(int i = 0; i < sequence.length; i++){
if(sequence[i] != name){
return false;
}
name = sequence[i];
}
return true;
And this code keeps saying that the array index is out of bounds: 0 and i feel like it has something to do with my first code.
Any help would be greatly appreciated!
To print an array meaningfully, use the Arrays.toString(result) method. For your code:
System.out.println("result: " + Arrays.toString(result));
This needs to be done because the default toString() implementation of all primitive array objects gives the ugly output you see above. It has some meaning, but in general you will never want to print it out or log it anywhere.
If you use a static code analysis tool like FindBugs, it will warn you about these types of things. http://findbugs.sourceforge.net/
When you say System.out.println("result: " + result); you are asking Java to print out an object, but result is an array which doesn't have a default toString() method, so what it shows is the object's reference, which is not meaningful to the human eye. As mentioned by #Kon you should be more explicit about how you want the data to show up.

Array Index Out OfBounds Help (Java)

This Java program does a simple computation and it is suppose to output the numerical value of 123+1
(The output should be 124.) (Ignore the last "+" string.)
I got an error inside the if statement:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
I did a printout for arrayz[i-1] and arrayz[i+1] and it seems to printout 123 and 1 receptively, which is correct. So, I'm not sure what's wrong.
String math = "123+1+";
String arrayz[]={"123","+","1","+"};
double total =0.0;
int i=0;
while(i<=(math.length()-1)) //don't bother with the last char
{ i++;
if(arrayz[i].equals("+"))
{
total = Double.parseDouble((String)arrayz[i-1]) + Double.parseDouble((String)arrayz[i+1]);
}
}
System.out.println(total);
while(i<=(math.length()-1))
math length is 6 and and in side loop your array length is 4
You might want to write
while(i<=(arrayz.length-1))
Since you are using the index i with the array arrayz, you must use arrayz.length instead of math.length()
Edit
This should work:
public static void main(String[] args)
{
String math = "123+1+";
String arrayz[] = { "123", "+", "1", "+" };
double total = 0.0;
int i = 0;
// arrayz.length - 2 -> because you are accessing "arrayz[i + 1]",
// arrayz.length - 1 would be OK if the maximum index you were using were "arrayz[i] "
while (i <= (arrayz.length - 2)) //don't bother with the last char
{
if (arrayz[i].equals("+")) {
total = Double.parseDouble((String) arrayz[i - 1]) + Double.parseDouble((String) arrayz[i + 1]);
}
i++; // Increment at the end of the loop
}
System.out.println(total);
}
You are looping over the string math, at the same time accessing elements of arrayz inside your loop, and thinking that they have the same elements and the same length.
What I suggest you, is to use instead of math String (you can omit it in this case but I assume you can't in general for some criteria), you can use an array of type String, so that 123 in your example would be the first element arrayz[0].

Categories