Searching for words in Multi-Dimension Array,Java - java

I want to search for words in a Word Puzzle in Java.
The search,as stated is in horizontal,vertical and Diagonal.
I created an Array, but I just don't know how to create a String, and search for words in my String. I need to know how can I have a String that keeps all the values of the table, and how can I be able to type a word, and search for it here.
I know that the search of the words is done with indexOf Function,but I don't know how to perform it.
import java.util.Scanner;
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int IntegerPosition;
int IntegerPosition2;
String position="";
String word="";
Scanner s = new Scanner(System.in);
String content="";
String[][] sopa = {
{"X","F","E","K","J","U","I","R","S","H"},
{"Z","H","S","W","E","R","T","G","O","T"},
{"B","R","A","B","F","B","P","M","V","U"},
{"D","W","E","R","O","O","J","L","L","W"},
{"U","T","O","N","I","R","O","B","C","R"},
{"O","P","R","O","V","I","I","K","V","B"},
{"N","I","Q","U","E","N","T","N","S","A"},
{"O","V","U","L","R","O","S","S","O","T"},
{"A","S","A","X","J","T","R","R","I","T"},
{"R","K","M","E","P","U","B","O","T","A"}
};
for (int i = 0; i < sopa[0].length; i++){
for(int j = 0; j < sopa[i].length; j++){
content += sopa[i][j];
}
System.out.println(content);
content = "";
}
System.out.println("Type the word you are looking for");
word = s.next();
for (int i = 0; i < sopa[0].length-1; i++){//t1.length
for(int j = 0; j < sopa[i].length-1; j++){
}
}
System.out.println(content);
content = "";
}
}

First, you should declare what "finding a word" means. I guess you want to find the sequence of letters in each row and column. What about diagonal? Backwards? Wrapping around?
Two solutions come to mind:
Use a String index:
Build a String of all characters. This needs to be done for each direction (horizontal, vertical, diagonal), but only in the forward order if you reverse the search term for backwards search. For an efficient implementation StringBuilder is your friend.
Use String.indexOf to find occurences of the term in your index. Finally you have to calculate row and column from the String position and, if wrapping is not allowed, check if the word crosses any row/column boundary.
I'd use this if I had to look for many terms.
Use the array
Also for each direction (horizontal, vertical, diagonal)
Look for occurences of the search term's first letter in your array (by simple iteration). Note that you can stop when the term would not fit the row/column, so for a 6-letter word, you can skip the 5 last rows/columns.
If you found an anchor (i.e. matching letter), check the subsequent letters of the word. Cancel on mismatch, otherwise you have found an occurence.
For a more sophisticated matching implementation, the Boyer-Moore algorithm may be of interest.

Related

How to read and return the second index of an array if first index matches a string?

I'm trying to write a translate method using the following parameters. However, every time I run the method it skips the first if statement and goes right to the second for loop.
/**
Translates a word according to the data in wordList then matches the case.
The parameter wordList contains the mappings for the translation. The data is
organized in an ArrayList containing String arrays of length 2. The first
cell (index 0) contains the word in the original language, called the key,
and the second cell (index 1) contains the translation.
It is assumed that the items in the wordList are sorted in ascending order
according to the keys in the first cell.
#param word
The word to translate.
#param wordList
An ArrayList containing the translation mappings.
#return The mapping in the wordList with the same case as the original. If no
match is found in wordList, it returns a string of Config.LINE_CHAR of the same length as word.
*/
public static String translate(String word, ArrayList<String[]> wordList) {
String newWord = "";
int i = 0;
for (i = 0; i < wordList.size(); i++) {
word = matchCase(wordList.get(i)[0], word); //make cases match
if (word.equals(wordList.get(i)[0])) { //check each index at 0
newWord = wordList.get(i)[1]; //update newWord to skip second for loop
return wordList.get(i)[1];
}
}
if (newWord == "") {
for (i = 0; i < word.length(); i++) {
newWord += Config.LINE_CHAR;
}
}
return newWord;
}
For the files I'm running, each word should have a translated word so no Config.LINE_CHAR should be printed. But this is the only thing that prints. How do I fix this.
You are initializing newWord to the value "". The only time newWord can possibly change is in the first loop, where it is promptly followed by a return statement, exiting your method. The only way your if statement can be reached is if you didn't return during the first loop, so if it reaches that if statement, then newWord must be unchanged since its initial assignment of "".
Some unrelated advice: You should use the equals operator when comparing strings. For example, if ("".equals(newWord)). Otherwise, you're comparing the memory address of the two String objects rather than their values.
You may need to share your matchCase method to ensure all bugs are addressed, though.

Writing method that spells word backwords and identifies number of palindromes

I'm new to java and I wrote this method to input a string word and output the word spelled backwards. The intent is to create a method and not use an already existing method such as the simple reverse. Please help point me in the direction of how to do this to reverse a word. I'm also trying to determine/count if there are palindromes. Please help! I've read other questions and I can't find anything specific enough to my case. I know that my code doesn't run, though I'm unsure how to fix it to get the correct output.
An example would be the word "backwards" to go to "sdrawkcab".
public static int reverseWord(String word) {
int palindromes = 0;
for (int i = word.length(); i >= 0; i--) {
System.out.print(i);
word.equalsIgnoreCase();
if (word.charAt(i)) == index(word.charAt(0 && 1))) {
palindromes++
System.out.println(palindromes)
}
return i;
}
}
There are multiple problems with your code.
1.The prototype of equalsIgnoreCase is
public boolean equalsIgnoreCase(String str);
So this method expect a String to be passed,but your not not passing anything here.To fix this,pass another string with whom you want to match your word like this..
word.equalsIgnoreCase("myAnotherString");
2.word.charAt(i);
Suppose word="qwerty",so indexing of each character will be like this
/* q w e r t y
0 1 2 3 4 5 */
So when you use i = word.length();i will 6 since word is of length 6.So
word.charAt(i) will search for character at index 6,but since there is not index 6,it will return an exception ArrayIndexOutOfBound.To fix this,start i from word.length()-1.
3.if (word.charAt(i));
This extra " ) ".Remove it.
Is Index() your own method?.If Yes,then check that also.
the below code prints the reverse of the input string and checks if it is a palindrome
public static void main(String[] args) {
String input = "dad";
char temp[] = input.toCharArray();//converting it to a array so that each character can be compared to the original string
char output[] = new char[temp.length];//taking another array of the same size as the input string
for (int i = temp.length - 1, j = 0; i >= 0; i--, j++) {//i variable for iterating through the input string and j variable for inserting data into output string.
System.out.print(temp[i]);//printing each variable of the input string in reverse order.
output[j] = temp[i];//inserting data into output string
}
System.out.println(String.valueOf(output));
if (String.valueOf(output).equalsIgnoreCase(input)) {//comparing the output string with the input string for palindrome check
System.out.println("palindrome");
}
}
Because your question about what is wrong with your code was already answered here is another way you could do it by using some concepts which are somewhat less low level than directly working with character arrays
public static boolean printWordAndCheckIfPalindrome(final String word) {
// Create a StringBuilder which helps when building a string
final StringBuilder reversedWordBuilder = new StringBuilder("");
// Get a stream of the character values of the word
word.chars()
// Add each character to the beginning of the reversed word,
// example for "backwards": "b", "ab", "cab", "kcab", ...
.forEach(characterOfString -> reversedWordBuilder.insert(0, (char) characterOfString));
// Generate a String out of the contents of the StringBuilder
final String reversedWord = reversedWordBuilder.toString();
// print the reversed word
System.out.println(reversedWord);
// if the reversed word equals the given word it is a palindrome
return word.equals(reversedWord);
}

search for words in an array of letters

I have a arrayList called dictionary which includes the following letters.
g,t,c,a,n,d,l,e,t,j,a,q.
I want the output to be for example,
2candle
3and etc.
the number is an offset from the start of the array being searched.
I want the output be list of locations of matches, each consisting of an offset from the beginning of the text and the string found.
Please HELP!!
If we think about this type of problem, the key is to figure out all of the different possibilities there are for places where you will find a word. Here is the skeleton of a method that I wrote that would go about this process:
public static String findWords(final char[] characters) {
String toRet = "";
// First iterate through every character in the array characters.
for (int i = 0; i < characters.length; i++) {
/*
* Then at each step in this loop, check all possible word
* combinations to see if it's a word. For example, check and see if
* characters[i], characters[i+1] forms a word. Then check and see
* if the word made by adding together characters[i],
* characters[i+1], and characters[i+2] is a word. Then check and
* see if the word formed by adding together the characters
* characters[i], characters[i+1], characters[i+2], characters[i+3]
* is a word.
*/
// Doing the above requires a nested loop inside of the original
// loop.
for (int j = 0; j < characters.length - i; j++) {
// When you do find a word that is formed, then go ahead and add
// to your string toRet the details about the word formed.
}
}
return toRet;
}
This doesn't fully answer your question, but I hope it

Sudden slow-down and java.lang.OutOfMemoryError during Java string search

I am writing a program for pattern discovery in RNA sequences that mostly works. In order to find 'patterns' in the sequences, I am generating some possible patterns and scanning through the input file of all sequences for them (there's more to the algorithm, but this is the bit that is breaking). Possible patterns generated are of a specified length given by the user.
This works well for all sequence lengths up to 8 characters long. Then at 9, the program runs for an very long time, then gives a java.lang.OutOfMemoryError. After some debugging, I found that the weak point is the pattern generation method:
/* Get elementary pattern (ep) substrings, to later combine into full patterns */
public static void init_ep_subs(int length) {
ep_subs = new ArrayList<Substring>(); // clear static ep_subs data field
/* ep subs are of the form C1...C2...C3 where C1, C2, C3 are characters in the
alphabet and the whole length of the string is equal to the input parameter
'length'. The number of dots varies for different lengths.
The middle character C2 can occur instead of any dot, or not at all.*/
for (int i = 1; i < length-1; i++) { // for each potential position of C2
// for each alphabet character to be C1
for (int first = 0; first < alphabet.length; first++) {
// for each alphabet character to be C3
for (int last = 0; last < alphabet.length; last++) {
// make blank pattern, i.e. no C2
Substring s_blank = new Substring(-1, alphabet[first],
'0', alphabet[last]);
// get its frequency in the input string
s_blank.occurrences = search_sequences(s_blank.toString());
// if blank ep is found frequently enough in the input string, store it
if (s_blank.frequency()>=nP) ep_subs.add(s_blank);
// when C2 is present, for each character it could be
for (int mid = 0; mid < alphabet.length; mid++) {
// make pattern C1,C2,C3
Substring s = new Substring(i, alphabet[first],
alphabet[mid],
alphabet[last]);
// search input string for pattern s
s.occurrences = search_sequences(s.toString());
// if s is frequent enough, store it
if (s.frequency()>=nP) ep_subs.add(s);
}
}
}
}
}
Here's what happens: When I time the calls to search_sequences, they start out at around 40-100ms each and carry on that way for the first patterns. Then after a couple hundred patterns (around 'C.....G.C') those calls suddenly start to take about ten times as long, 1000-2000ms. After that, the times steadily increase until at about 12000ms ('C......TA') it gives this error:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.nio.HeapCharBuffer.toString(HeapCharBuffer.java:542)
at java.nio.CharBuffer.toString(CharBuffer.java:1157)
at java.util.regex.Matcher.toMatchResult(Matcher.java:232)
at java.util.Scanner.match(Scanner.java:1270)
at java.util.Scanner.hasNextLine(Scanner.java:1478)
at PatternFinder4.search_sequences(PatternFinder4.java:217)
at PatternFinder4.init_ep_subs(PatternFinder4.java:256)
at PatternFinder4.main(PatternFinder4.java:62)
This is the search_sequences method:
/* Searches the input string 'sequences' for occurrences of the parameter string 'sub' */
public static ArrayList<int[]> search_sequences(String sub) {
/* arraylist returned holding int arrays with coordinates of the places where 'sub'
was found, i.e. {l,i} l = lines number, i = index within line */
ArrayList<int[]> occurrences = new ArrayList<int[]>();
s = new Scanner(sequences);
int line_index = 0;
String line = "";
while (s.hasNextLine()) {
line = s.nextLine();
pattern = Pattern.compile(sub);
matcher = pattern.matcher(line);
pattern = null; // all the =nulls were intended to help memory management, had no effect
int index = 0;
// for each occurrence of 'sub' in the line being scanned
while (matcher.find(index)) {
int start = matcher.start(); // get the index of the next occurrence
int[] occurrence = {line_index, start}; // make up the coordinate array
occurrences.add(occurrence); // store that occurrence
index = start+1; // start looking from after the last occurence found
}
matcher=null;
line=null;
line_index++;
}
s=null;
return occurrences;
}
I've tried the program on a couple of different computers of differing speeds, and while the actual times time complete search_sequence are smaller on faster computers, the relative times are the same; at around the same number of iterations, search_sequence starts taking ten times as long to complete.
I've tried googling about memory efficiency and speed of different input streams such as BufferedReader etc, but the general consensus seems to be that they are all roughly equivalent to Scanner. Do any of you have any advice about what this bug is or how I could try to figure it out myself?
If anyone wants to see any more of the code, just ask.
EDIT:
1 - The input file 'sequences' is 1000 protein sequences (each on one line) of varying lengths around a couple hundred characters. I should also mention this program will /only ever need to work/ up to patterns of length nine.
2 - Here are the Substring class methods used in the above code
static class Substring {
int residue; // position of the middle character C2
char front, mid, end; // alphabet characters for C1, C2 and C3
ArrayList<int[]> occurrences; // list of positions the substring occurs in 'sequences'
String string; // string representation of the substring
public Substring(int inresidue, char infront, char inmid, char inend) {
occurrences = new ArrayList<int[]>();
residue = inresidue;
front = infront;
mid = inmid;
end = inend;
setString(); // makes the string representation using characters and their positions
}
/* gets the frequency of the substring given the places it occurs in 'sequences'.
This only counts the substring /once per line ist occurs in/. */
public int frequency() {
return PatternFinder.frequency(occurrences);
}
public String toString() {
return string;
}
/* makes the string representation using the substring's characters and their positions */
private void setString() {
if (residue>-1) {
String left_mid = "";
for (int j = 0; j < residue-1; j++) left_mid += ".";
String right_mid = "";
for (int j = residue+1; j < length-1; j++) right_mid += ".";
string = front + left_mid + mid + right_mid + end;
} else {
String mid = "";
for (int i = 0; i < length-2; i++) mid += ".";
string = front + mid + end;
}
}
}
... and the PatternFinder.frequency method (called in Substring.frequency()) :
public static int frequency(ArrayList<int[]> occurrences) {
HashSet<String> lines_present = new HashSet<String>();
for (int[] occurrence : occurrences) {
lines_present.add(new String(occurrence[0]+""));
}
return lines_present.size();
}
What is alphabet? What kind of regexs are you giving it? Have you checked the number of occurrences you're storing? It's possible that simply storing the occurrences is enough to make it run out of memory, since you're doing an exponential number of searches.
It sounds like your algorithm has a hidden exponential resource usage. You need to rethink what you are trying to do.
Also, setting a local variable to null won't help since the JVM already does data flow and liveness analysis.
Edit: Here's a page that explains how even short regexes can take an exponential amount of time to run.
I can't spot an obvious memory leak, but your program does have a number of inefficiencies. Here are some recommendations:
Indent your code properly. It will make reading it, both for you and for others, much easier. In its current form it's very hard to read.
If you're referring to a member variable, prefix it with this., otherwise readers of code snippets won't know for sure what you're referring to.
Avoid static members and methods unless they're absolutely necessary. When referring to them, use the Classname.membername form, for the same reasons.
How is the code of frequency() different from just return occurrences.size()?
In search_sequences(), the regex string sub is a constant. You need to compile it only once, but you're recompiling it for every line.
Split the input string (sequences) into lines once and store them in an array or ArrayList. Don't re-split inside search_sequences(), pass the split collection in.
There are probably more things to fix, but this is the list that jumps out.
Fix all these and if you still have problems, you may need to use a profiler to find out what's happening.

Print words which occurs more than once from a string

I am trying to find and print the words in a string that occurs more than one. And it works almost. I am however fighting with a small problem. The words a printed out twice since they occur twice in the sentence. I want them printed only once:
This is my code:
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String sentence = "is this a sentence or is this not ";
String[] myStringArray = sentence.split(" "); //Split the sentence by space.
int[] count = new int[myStringArray.length];
for (int i = 0; i < myStringArray.length; i++){
for (int j = 0; j < myStringArray.length; j++){
if (myStringArray[i].matches(myStringArray[j]))
count[i]++;
//else break;
}
}
for (int i = 0; i < myStringArray.length; i++) {
if (count[i] > 1)
System.out.println("1b. - Tokens that occurs more than once: " + myStringArray[i] + "\n");
}
}
}
You can try for (int i = 0; i < myStringArray.length; i+=2) instead.
break on the first match, after incrementing. then it won't also increment the second match.
Your code has some problems with it.
If you notice, your code will look through the list of n elements n^2 times.
If the occurrence of the word is twice. You will increment each word's count value twice.
What you need to keep track of is the set of words you have already seen, and check if a new word you encounter has already been seen or not.
If you had 3 occurrence of one word in your sentence, you each word would have a count of 3. The 3 is redundant data that doesn't need to be stored for each token, but rather just the word.
All this can be done easily if you know how a Map works.
Here is an implementation that would work.
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
String sentence = "is this a sentence or is this not ";
String[] myStringArray = sentence.split("\\s"); //Split the sentence by space.
Map <String, Integer> wordOccurrences = new HashMap <String, Integer> (myStringArray.length);
for (String word : myStringArray)
if (wordOccurrences.contains(word))
wordOccurrences.put(word, wordOccurrences.get(word) + 1);
else wordOccurrences.put(word, 1);
for (String word : wordOccurrences.keySet())
if (wordOccurrences.get(word) > 1)
System.out.println("1b. - Tokens that occurs more than once: " + word + "\n");
}
}
We want to find the repeating words from an input string. So, I suggest the following approach which is fairly simple:
Make a Hash Map instance. The key (String) will be the word and the value(Integer) will be the frequency of its occurrence.
Split the string using split("\s") method to make an array of only words.
Introduce an Integer type 'frequency' variable with initial value '0'.
Iterate of the string array and after checking frequency, add each element ( or word) to the map (if frequency for that key is 0) or if
the key (word) exists, only increment the frequency by 1.
So you are now left with each word and its frequency.
For example, if input string is "We are getting dirty as this earth is getting polluted. We must stop it."
So, the map will be
{ ("We",2), ("are",1), ("getting",2), ("dirty",1), ("as",1), ("this",1), ("earth",1), ("is",1), ("polluted.",1), ("must",1), ("stop",1), ("it.",1) }
Now you know what is next step and how to use it. I agree with Kaushik.

Categories