Finding a word on a two dimensional char array - java

What kind of approch could be an easy way to find the given words on a puzzle like this? I'm using Java. Thanks for help.

Interesting question. I would solve this by first building a list of "possible word holders" (sequences of characters which can possibly hold one of the given words) by traversing the puzzle horizontally, vertically and diagonally (in both directions). I would then see if the given words (or their reverse) are present (using contains() method in Java) in each of the obtained "possible word holders". Here is the code I wrote in Java. I haven't tested it properly, but I guess it works!
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class WordPuzzle {
public Set<String> findWords(char[][] puzzle, Set<String> words) {
Set<String> foundWords = new HashSet<String>();
int minimumWordLength = findMinimumWordLength(words);
Set<String> possibleWords = findPossibleWords(puzzle, minimumWordLength);
for(String word : words) {
for(String possibleWord : possibleWords) {
if(possibleWord.contains(word) || possibleWord.contains(new StringBuffer(word).reverse())) {
foundWords.add(word);
break;
}
}
}
return foundWords;
}
private int findMinimumWordLength(Set<String> words) {
int minimumLength = Integer.MAX_VALUE;
for(String word : words) {
if(word.length() < minimumLength)
minimumLength = word.length();
}
return minimumLength;
}
private Set<String> findPossibleWords(char[][] puzzle, int minimumWordLength) {
Set<String> possibleWords = new LinkedHashSet<String>();
int dimension = puzzle.length; //Assuming puzzle is square
if(dimension >= minimumWordLength) {
/* Every row in the puzzle is added as a possible word holder */
for(int i = 0; i < dimension; i++) {
if(puzzle[i].length >= minimumWordLength) {
possibleWords.add(new String(puzzle[i]));
}
}
/* Every column in the puzzle is added as a possible word holder */
for(int i = 0; i < dimension; i++) {
StringBuffer temp = new StringBuffer();
for(int j = 0; j < dimension; j++) {
temp = temp.append(puzzle[j][i]);
}
possibleWords.add(new String(temp));
}
/* Adding principle diagonal word holders */
StringBuffer temp1 = new StringBuffer();
StringBuffer temp2 = new StringBuffer();
for(int i = 0; i < dimension; i++) {
temp1 = temp1.append(puzzle[i][i]);
temp2 = temp2.append(puzzle[i][dimension - i - 1]);
}
possibleWords.add(new String(temp1));
possibleWords.add(new String(temp2));
/* Adding non-principle diagonal word holders */
for(int i = 1; i < dimension - minimumWordLength; i++) {
temp1 = new StringBuffer();
temp2 = new StringBuffer();
StringBuffer temp3 = new StringBuffer();
StringBuffer temp4 = new StringBuffer();
for(int j = i, k = 0; j < dimension && k < dimension; j++, k++) {
temp1 = temp1.append(puzzle[j][k]);
temp2 = temp2.append(puzzle[k][j]);
temp3 = temp3.append(puzzle[dimension - j - 1][k]);
temp4 = temp4.append(puzzle[dimension - k - 1][j]);
}
possibleWords.add(new String(temp1));
possibleWords.add(new String(temp2));
possibleWords.add(new String(temp3));
possibleWords.add(new String(temp4));
}
}
return possibleWords;
}
public static void main(String args[]) {
WordPuzzle program = new WordPuzzle();
char[][] puzzle = {
{'F','Y','Y','H','N','R','D'},
{'R','L','J','C','I','N','U'},
{'A','A','W','A','A','H','R'},
{'N','T','K','L','P','N','E'},
{'C','I','L','F','S','A','P'},
{'E','O','G','O','T','P','N'},
{'H','P','O','L','A','N','D'}
};
Set<String> words = new HashSet<String>();
words.add("FRANCE");
words.add("POLAND");
words.add("INDIA");
words.add("JAPAN");
words.add("USA");
words.add("HOLLAND");
Set<String> wordsFound = program.findWords(puzzle, words);
for(String word : wordsFound) {
System.out.println(word);
}
}
}

In general, I say use the most naive approach unless your puzzles are going to be large. I wouldn't optimize anything that takes less than 0.1s, but thats just me.
foreach box
for all directions
grab the string of characters in that direction
lookup a dictionary
I think the smarts can be in how you design your dictionary. In this case, I would do a multi-level hash table where characters pick which hash table to look at the next level.

I would put the word list into a Trie, then do a search from all squares in all directions.

The easiest approach (conceptualy) is to simply enumerate all possible words in your array and check all of then in a dictionnary. A dictionnary behing a map, an array of string... or a real dictionnary downloaded from the internet.
As an exemple here is the code to find all possible word horizontally... Adding other direction is just more work :
import java.util.HashSet;
import java.util.Set;
public class WordFinder {
public static void main(String[] args) {
String[][] words = { { "F", "Y", "Y", "H", "N", "R", "D" },
{ "R", "L", "J", "C", "I", "N", "U" },
...};
Set<String> dictionnary = new HashSet<String>();
dictionnary.add(...);
Set<String> wordsFound = findWords(words, dictionnary);
...
}
/**
* Find all words in the specified array present in the dictionnary.
*
*/
private static Set<String> findWords(String[][] words, Set<String> dictionnary) {
Set<String> wordsFound = new HashSet<String>();
// Find all possible words horizontally :
int nbrRows = words.length;
int nbrCol = words[0].length; // We suppose we have at least one row and all row have same lengh
// Iterate through all rows
for (int currentRow = 0; currentRow < nbrRows; currentRow++) {
// Iterate through all possible starting position in the current row.
for (int beginWordIndex = 0; beginWordIndex < nbrCol; beginWordIndex++) {
// Iterate then through all possible ending positions in the current row, so to deal with word of any lengh.
for (int endWordIndex = beginWordIndex; endWordIndex < nbrCol; endWordIndex++) {
// Construct a word from the begin/end indexes :
String currentWord = getWordInRow(words, currentRow, beginWordIndex, endWordIndex);
// Check if the word candidate really exist, if yes, store it in the wordsFound variable.
if (dictionnary.contains(currentWord)) {
wordsFound.add(currentWord);
}
// The reverse
String reverseWord = reverseString(currentWord);
// Check if the reverse word really exist, if yes, store it in the wordsFound variable.
if (dictionnary.contains(reverseWord)) {
wordsFound.add(currentWord);
}
}
}
}
// Don't forget vertically and in diagonals too... Same principe.
return wordsFound;
}
/**
* Return a word "candidate" in the specified row, starting at beginIndex and finishing at endIndex.
*/
private static String getWordInRow(String[][] words, int row, int beginIndex, int endIndex) {
String currentWord = "";
int currentPosition = beginIndex;
while (currentPosition <= endIndex) {
currentWord += words[row][currentPosition];
}
return currentWord;
}
/**
* Return the reverse of a String
*/
private static String reverseString(String string) {
String result = "";
for (int i = string.length()-1; i >=0;i++) {
result+= string.charAt(i);
}
return result;
}
}
This is not the best, most effective solution. But it is conceptually simple.
EDIT :
reverse order: see edited code. Just write a function that can reverse a word. Because we already have all posible word in normal order, reversing them is enough to have words in reverse order.
Diagonals : I'am sure you can do it if you have understood the code I have already put. I will not do your homework or do your testing in place of you. Try to figure how you would do it with a paper and a pen. How would you do it if you had to do it by hand. Then from that, write your solution ;)

Related

Encoding a String Array

EDIT : [Schoolwork Assignment]
So, I want to encode, with only 0 and 1, words.
0 = word not present
1 = word present
My dictionary correspond to :
String[] dictionary = {"Hello", "I", "am", "Lukas", "and", "Jonas", "play", "football"};
For example : If I encode these words...
String[] listOfWords = {"Hello", "play" "football"};
I must have the following array :
int[] wordsEncode = {1,0,0,0,0,0,1,1};
You can see that "Hello" is present, "I" "am" "Lukas" "and" "Jonas" are not present. Finally, "play" and "football" are present.
We must preserve the order of dictionary and that is my problem in my code.
I don't really know how to fix that problem (using a second for loop ?) ?
I think wordEncode[i] is my error, but how to fix that ?
Here is my code :
class Dictionary {
/**
* Array words Dictionary
*/
String[] dictionary;
/**
* Maximum of words MAX_WORDS
*/
final int MAX_WORDS = 50;
/**
* Number of words in the dictionary
*/
int numberWordsDictionary;
/**
* Constructor
*/
Dictionary() {
dictionary = new String[MAX_WORDS];
numberWordsDictionary = 0;
}
int[] encoder(String[] listOfWords) {
int[] wordsEncode = new int[numberWordsDictionary];
StringBuilder builder = new StringBuilder();
for(String word : dictionary) {
builder.append(word);
}
String dictionaryString = builder.toString();
for(int i = 0; i < listOfWords.length; i++) {
if(dictionaryString.contains(listOfWords[i])) {
wordsEncode[i] = 1;
} else {
wordsEncode[i] = 0;
}
}
return wordsEncode;
}
}
Sorry about indentation (not same as my Java IDE) :(
Thanks !
Using two-level nested loops, you should check each element of dictionary[] whether it is there in listOfWords[] and if yes, update the value at the corresponding index in wordsEncode[] to 1.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] dictionary = { "Hello", "I", "am", "Lukas", "and", "Jonas", "play", "football" };
String[] listOfWords = { "Hello", "play", "football" };
int[] wordsEncode = new int[dictionary.length];
for (int i = 0; i < dictionary.length; i++) {
boolean found = false;
for (String s : listOfWords) {
if (s.equals(dictionary[i])) {
found = true;
break;
}
}
if (found) {
wordsEncode[i] = 1;
}
}
// Display the result
System.out.println(Arrays.toString(wordsEncode));
}
}
Output:
[1, 0, 0, 0, 0, 0, 1, 1]
Loop your input words. For each input word, see if your list of target words contains that particular word. If so, add a 1 to your results list. If not, add zero.
I use the more convenient Collections, but you could do the same approach with arrays.
List< String > input = List.of( "Hello", "I", "am", "Lukas", "and", "Jonas", "play", "football" ) ;
List< String > targets = List.of( "Hello", "play" "football" ) ;
List< Integers > hits = new ArrayList<>() ;
for( String s : input )
{
int i = targets.contains( s ) ? 1 : 0 ;
hits.add( i ) ;
}
What you did here is iterate through dictionary array and added the words to a StringBuilder to check if a certain word you got in the listOfWords array is in the StringBuilder. But there a better solution to this you can just make a nested loop that compares every element of listOfWords array and dictionary array and if it found a match it sets the encode array value at the index of the second loop to 1:
int[] encoder(String[] listOfWords) {
int[] wordsEncode = new int[numberWordsDictionary];
for (int i = 0; i < listOfWords.length; i++) {
for (int j = 0; j < numberWordsDictionary; j++) {
if (listOfWords[i].equals(dictionary[j])) {
wordsEncode[j] = 1;
break;
}
}
}
return wordsEncode;
}
/* This approach is wrong, the combined string could catch words that are
part of the ending of one word and part of the beginning of another but
not actually a word in the dictionary. For instance, if you had
"arch" and "attach" in your dictionary, testing for "chat" would return true
*/
/*
StringBuilder builder = new StringBuilder();
for(String word : dictionary) {
builder.append(word);
}
String dictionaryString = builder.toString();
*/
for(int i = 0; i < listOfWords.length; i++) {
boolean found = false;
for (int j = 0; j < dictionary.length; j++) {
if (dictionary[j].equalslistOfWords[i]) {
found = true;
}
}
if (found) {
wordsEncode[i] = 1;
} else {
wordsEncode[i] = 0;
}
// you can also do wordsEncode[i] = found ? 1 : 0;
}
return wordsEncode;
}

Generate permutations on list of strings using one character only

I am trying to generate permutations using list of strings taking one character one time.
Below is the code of input and output that I want.
Can we simply do it iteratively?. Also I am not finding exact method.
String[] lst = new String[]{"abc", "def", "ghi"}; //Given
String[] permutations = new String[]{ //To Generate
"adg", "adh", "adi",
"aeg", "aeh", "aei",
"afg", "afh", "afi",
"bdg", "bdh", "bdi",
"beg", "beh", "bei",
"bfg", "bfh", "bfi",
"cdg", "cdh", "cdi",
"ceg", "ceh", "cei",
"cfg", "cfh", "cfi",
};
Update: I am not looking just for the above example with list size=3. It can be of any size and each string may happen to be of different length.
For ex: list = [ "ab", "abc", "defghi", "x", "einsigl"]
In this answer I will walk through how I solved this problem to find an algorithm that works for an array of any length for words which can be any length and are not required to all be the same length.
I will first make a recursive solution, and then transorm it into an iterative one.
The easiest way to answer problems like this is to think of them recursively:
Generating all permutations of [] should return [""]
Generating all permutations of a non-empty list means, for each letter c in the first word in the list, return all permutations of the rest of the list with c prepended on the front.
This can be written in Java as follows:
public static List<String> generatePermutationsRecursiveSlow(String[] words) {
if (words.length == 0)
// base case
return Collections.singletonList("");
else {
// recursive case
// result list
ArrayList<String> permutations = new ArrayList<>();
// split array into item 0 and items [1..end]
String firstWord = words[0];
String[] otherWords = new String[words.length - 1];
System.arraycopy(words, 1, otherWords, 0, words.length - 1);
// recurse to find permutations for items [1..end]
List<String> otherWordsPermutations = generatePermutationsRecursiveSlow(otherWords);
// for each character in the first word
for (char c : firstWord.toCharArray()) {
// for each permutation from the recursive call's results
for (String otherWordsPermutation : otherWordsPermutations) {
// prepend this character onto the permutation and add it to the results
permutations.add(c + otherWordsPermutation);
}
}
return permutations;
}
}
Calling generatePermutationsRecursiveSlow(new String[0]) returns [""].
Calling generatePermutationsRecursiveSlow(new String[]{"cd"}) will cause the local c variable to be equal to 'c', and it will recurse with an empty array as the argument, making otherWordsPermutations equal to [""], so it will add 'c' + "" (which is "c") to the results, then it will do the same for 'd', adding "d" to the results.
Calling generatePermutationsRecursiveSlow(new String[]{"ab", "cd"}) will mean that when c is 'a', it will add to the results list 'a'+"c", then 'a'+"d", and whencis'b', it will add'b'+"c"and'b'+"d"`
A similar but better optimised version which works in the same way can be written like this:
public static List<String> generatePermutationsRecursive(String[] words) {
ArrayList<String> permutations = new ArrayList<>();
int wordLen = words.length;
generatePermutationsRecursive(words, permutations, new char[wordLen], 0);
return permutations;
}
public static void generatePermutationsRecursive(String[] words, ArrayList<String> permutations, char[] word, int i) {
if (i == word.length) {
// base case
permutations.add(new String(word));
} else {
for (int j = 0; j < words[i].length(); j++) {
// equivalent of prepending
word[i] = words[i].charAt(j);
// recurse
generatePermutationsRecursive(words, permutations, word, i + 1);
}
}
}
This is better optimised since it uses the word parameter to avoid the O(n) prepending to the string by instead modifying a character array. It also introduces the parameter i which is the effective start index of the array, making it possible to avoid copying parts of the input array.
This can be transformed into an iterative approach by tracking the variables that change between different recursive calls using a stack (in place of the call stack):
private static List<String> generatePermutationsIterative(String[] words) {
// in the recursive version, each recursive function call would have its own local copy of `i` and `j`
// simulate that here with 2 stacks
ArrayDeque<Integer> i_stack = new ArrayDeque<>(words.length);
ArrayDeque<Integer> j_stack = new ArrayDeque<>(words.length);
i_stack.add(0);
j_stack.add(0);
char[] word = new char[words.length];
ArrayList<String> permutations = new ArrayList<>();
while (!i_stack.isEmpty()) {
int i = i_stack.removeLast();
int j = j_stack.removeLast();
if (i == words.length) {
// base case
permutations.add(new String(word));
continue;
}
if (!(j < words[i].length())) {
// reached end of loop `for (int j = 0; j < words[i].length(); j++)`
continue;
}
// if not reached end of loop `for (int j = 0; j < words[i].length(); j++)` yet,
// then increment `j` and allow next iteration to happen
i_stack.add(i);
j_stack.add(j + 1);
word[i] = words[i].charAt(j);
// recurse
i_stack.add(i + 1);
j_stack.add(0);
}
return permutations;
}
Code here
As a sidenote, look how cool Haskell is with this 2-line solution to the problem here (admittedly its not iterative, but it should have tail-call optimisation, making it as fast as an iterative solution).
Here's one way to do it that should work for arbitrary number of words of arbitrary length (not including 0).
String[] lst = new String[] {
"abc",
"def",
"ghi"
};
int numWords = lst.length;
int wordlen = lst[0].length();
int numPerms = (int) Math.pow(wordlen, numWords);
char[][] perms = new char[numPerms][numWords];
char[][] chararr = Arrays.stream(lst)
.map(String::toCharArray)
.toArray(i -> new char[i][wordlen]);
for (int i = 0; i < numWords; i++) {
double permsLocal = Math.pow(wordlen, i + 1);
int numRepeats = (int) Math.ceil((numPerms / permsLocal));
int repeats = (int)(permsLocal / wordlen);
for (int x = 0; x < repeats; x++) {
char[] word = chararr[i];
for (int j = 0; j < wordlen; j++) {
char c = word[j];
for (int k = 0; k < numRepeats; k++) {
perms[(x * wordlen * numRepeats) + k + j * numRepeats][i] = c;
}
}
}
}
String[] permutations = Arrays.stream(perms)
.map(String::new)
.toArray(String[]::new);
Output:
[adg, adh, adi, aeg, aeh, aei, afg, afh, afi, bdg, bdh, bdi, beg, beh,
bei, bfg, bfh, bfi, cdg, cdh, cdi, ceg, ceh, cei, cfg, cfh, cfi]
Link to repl.it: https://repl.it/repls/BoilingExcitingAttributes
You can do it as follows:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
String[] lst = new String[] { "abc", "def", "ghi" };
List<String> list = new ArrayList<>();
for (char a : lst[0].toCharArray()) {
for (char b : lst[1].toCharArray()) {
for (char c : lst[2].toCharArray()) {
list.add(new String(new char[] { a, b, c }));
}
}
}
// Convert to array
String[] permutations = list.toArray(new String[0]);
// Display
System.out.println(Arrays.toString(permutations));
}
}
Output:
[adg, adh, adi, aeg, aeh, aei, afg, afh, afi, bdg, bdh, bdi, beg, beh, bei, bfg, bfh, bfi, cdg, cdh, cdi, ceg, ceh, cei, cfg, cfh, cfi]

Finding every possible combination of elements in an array in Java

Suppose I have this array: [a,b,c,d] How would I go about finding every possible combination i.e ab,abc,abcd.....etc. This needs to include duplicates, so abcd is not the same as dcba
The purpose is to find all combinations and check if if can make the same combination from a different array. My initial attempt is:
for (int i = 0; i < values.length; i++) {
String cur = values[i];
for (int k = 0; k < values.length; k++) {
if (i != k) {
cur = cur.concat(values[k]);
System.out.println(cur);
}
}
}
Which give the output :
ab
abc
abcd
ba
bac
bacd
ca
cab
cabd
da
dab
dabc
which is obviously not correct
This is for a programming challenge I'm doing to try and improve so any suggestions of a faster solution would be helpful
Is this what you're looking for?
public static void main(String[] data) {
ArrayList<Character> chars = new ArrayList<>(4);
chars.add('a');
chars.add('b');
chars.add('c');
chars.add('d');
System.out.println(getPermutations("", chars));
}
private static ArrayList<String> getPermutations(String currentResult, ArrayList<Character> possibleChars) {
ArrayList<String> result = new ArrayList<>(possibleChars.size());
for (char append: possibleChars) {
String permutation = currentResult + append; //create a new string with an additional character
result.add(permutation); //add the permutation to the result
if (possibleChars.size() > 0) {
//make a new list with the appendable characters
ArrayList<Character> possibleCharsUpdated = (ArrayList)possibleChars.clone();
//from that list, exclude the character we just appended
possibleCharsUpdated.remove(new Character(append));
//merge the result of a recursive call of this method and the result we already had
result.addAll(getPermutations(permutation, possibleCharsUpdated));
}
}
return result;
}

Recursively creating strings from 2 dimensional character array

I need to create all possible strings from a 2d-array so that the first character comes from charArray[0], the second character comes from charArray[1]...and the final character comes from the charArray[keyLength-1].
Example:
input:
char[][] charArray =
{{'m','M','L','S','X'}
{'e','E','o','N','Z'}
{'o','G','F','r','Y'}
{'D','H','I','J','w'}};
output:
{meoD, meoH, meoI,..., XZYJ, XZYw} //in an Array or ArrayList
I had a working solution that builts a tree with each character in charArray[0] as a root and it did a depth first string construction, but the JVM ran out of memory for charArray lengths less than 12. I would normally take an iterative approach, but the charArray length (i.e. key string length) is decided at runtime and I would like to find a more complete solution than writing a switch statement on the key string length and manually writing out loops for a finite number of key string lengths.
I've been stuck on this small section of my program for longer than I'd like to admit, so any help would be greatly appreciated!
Here is how it can be solved:
import java.util.ArrayList;
import java.util.List;
public class Arrays2D {
public static void main(String[] args) {
//input keys
String[][] charArray =
{{"m","M","L","S","X"},
{"e","E","o","N","Z"},
{"o","G","F","r","Y"},
{"D","H","I","J","w"}};
//print output
System.out.println(findCombinations(charArray));
}
private static List<String> findCombinations(String[][] charArray) {
List<String> prev = null;
for (int i = 0; i < charArray.length; i++) {
List<String> curr = new ArrayList<String>();
for (int j = 0; j < charArray[i].length; j++) {
if (i + 1 < charArray.length) {
for (int l = 0; l < charArray[i+1].length; l++) {
String s = charArray[i][j] + charArray[i + 1][l];
curr.add(s);
}
}
}
if (prev != null && !curr.isEmpty()) {
prev = join(prev, curr);
}
if (prev == null)
prev = curr;
}
return prev;
}
public static List<String> join(List<String> p, List<String> q) {
List<String> join = new ArrayList<String>();
for (String st1 : p) {
for (String st2 : q) {
if (st1.substring(st1.length() - 1).equals(st2.substring(0, 1))) {
String s = st1 + st2;
s = s.replaceFirst(st1.substring(st1.length() - 1), "");
join.add(s);
}
}
}
return join;
}
}
I have checked and it correctly generating the combinations. You can run and see the output.

location and repetition of characters within a string

Hi biologist here with a little bit of coding background. my goal is to be able to input a string of characters and the code to be able to tell me how many times they occur and at what location in the string.
so ill be entering a string and i want the location and abundance of sq and tq within the string. with the location being the first character e.g njnsqjjfl sq would be located at postition 4.
This is what ive come up with so far (probably very wrong)
string S = "...";
int counter =0;
for(int i=0; i<s.length; i++){
if(s.charAt (i) == 'sq')}
counter++;})
string S = "...";
int counter =0;
for(int i=0; i<s.length; i++){
if(s.charAt (i) == 'tq')}
counter++;})
any input will help, thankyou
So , you can have multiple occurrences of "sq" and "tq" in your code, so you can have 2 arraylists to save these two separately(or one to save them together).
ArrayList<Integer>sqLocation = new ArrayList<>();
ArrayList<Integer>tqLocation = new ArrayList<>();
for(int i =0;i<s.length()-1;i++){
if(s.charAt(i)=='s' && s.charAt(i+1)=='q'){
sqLocation.add(i);
}
else if(s.charAt(i)=='t' && s.charAt(i+1)=='q'){
tqLocation.add(i);
}
}
System.out.println("No. of times sq occurs = "+sqLocation.size());
System.out.println("Locations ="+sqLocation);
System.out.println("No. of times tq occurs = "+tqLocation.size());
System.out.println("Locations ="+tqLocation);
This can be achieved using regex. Your use case is to count occurrences and position of those occurrences. The method match returns an integer list which is position and count is size of list
Exmaple code
public class RegexTest {
public static List<Integer> match(String text, String regex) {
List<Integer> matchedPos = new ArrayList<>();
Matcher m = Pattern.compile("(?=(" + regex + "))").matcher(text);
while(m.find()) {
matchedPos.add(m.start());
}
return matchedPos;
}
public static void main(String[] args) {
System.out.println(match("sadfsagsqltrtwrttqsqsqsqsqsqs", "sq"));
System.out.println(match("sadfsagsqltrtwrttqksdfngjfngjntqtqtqtqtqtq", "tq"));
}
}
what you want is a HashMap <String, List <Integer>>
this will hold, the String that you are looking for e.g. sq or tq, and a List of the positions that they are at.
You want to loop around using String.indexOf see https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(java.lang.String,%20int)
psuedocode being
String contents = "sadfsagsqltrtwrttqksdfngjfngjntqtqtqtqtqtq";
map.add (lookFor, new ArrayList ());
int index = 0;
while ((index = contents.indexOf (lookFor, index)) != -1) {
list = map.get (lookFor);
list.add (index);
}
You should use not charAt but substring to get a part of String.
int count(String s, String target) {
int counter = 0;
int tlen = target.length();
for (int i = tlen; i < s.length(); i++) {
if (s.substring(i - tlen, i).equals(target)) {
counter++;
}
}
return counter;
}
// in some method
count("...", "sq");
count("...", "tq");

Categories