Finding the indexes of multiple words in a string - java

I swear I did this a while back and it worked. But I can't remember how I did it. I want to find the indexes of multiple words in a string. The code below only works for one word. I need a more eloquent solution for dealing with several.
import java.util.*;
public class test {
public static List<List<Boolean>> work;
public static void main (String[] args) {
String test = "I'm trying to both extract and replaces. This that and the other";
String word = "I'm";
for (int i = -1; (i = test.indexOf(word, i + 1)) != -1; ) {
System.out.println(i);
}
}
}
Let's say I wanted to find the index of “both” and “other.”

I did some more research, this appears to be what you are asking for:
String test = "I'm trying to both extract and replaces. This that and the other";
String[] words = test.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll("[^\\w]", "");
}
System.out.println(Arrays.asList(words).indexOf("both"));
Result:
3
Keep in mind that Java counts including 0, so "both" is actually at index 4 for us humans.
----Old Solution----
The question is vague about what they want, but this will return the index number corresponding to each word via HashMap:
HashMap<Integer, String> hmap = new HashMap<Integer, String>();
String test = "I'm trying to both extract and replaces. This that and the other";
String[] words = test.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll("[^\\w]", "");
}
for(int i = 0; i < words.length; i++){
hmap.put(i, words[i]);
}
System.out.println(hmap);
Result:
{0=Im, 1=trying, 2=to, 3=both, 4=extract, 5=and, 6=replaces, 7=This, 8=that, 9=and, 10=the, 11=other}

public static void main (String[] args)
{
String test="I'm trying to both extract and replaces. This that and the other";
String[] words={"other","This","that"};
for(int j=0;j<words.length;j++)
{
for(int i=-1;(i=test.indexOf(words[j],i+1))!=-1;)
{
System.out.println(words[j]+" "+ i);
}
}
}
ouput
other 59
This 41
that 46

buddy ... I was trying to point you in the right direction ... not give you complete working code :) Here is a complete working code:
public static void main (String[] args)
{
String test = "I'm trying to both extract and replaces. This that and the other";
String[] words = {"I'm", "other", "both"};
for (int j=0; j < words.length; j++)
{
System.out.println("Word: " + words[j] + " is at index: " + test.indexOf(words[j]));
}
}
This way, you will not get ArrayIndexOutOFBounds exception. You are going through each word once.
But for each word, you have go through entire test string once. In your earlier code, you were using i = test.indexOf(word) in the loop. If the words were not in the order of appearing in test string, this will create problem.
For eg: test = "I'm a rockstar"
words = {"rockstar", "a"}
In this case, the loop variable i moves forward to index where 'rockstar' is found but then will not find 'a' after that as test string doesn't contain an 'a' after 'rockstar'.
But in the current code I posted, order of words can be anything.
Hope its clear.

I believe you're referencing the answer from this SO question. To use it for more than one word, all you need is a simple data structure to store the words you want to find, loop over that, and return a map holding the word and its corresponding locations, as follows:
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class WordFinder {
public static void main(String[] args) {
String phrase = "0123hello9012hello8901hello7890";
String[] words = { "hello", "90" };
Map<String, Stack<Integer>> dest = findWordsInString(words, phrase);
System.out.println(dest.toString());
}
public static Map<String, Stack<Integer>> findWordsInString(String[] words, String phrase) {
Map<String, Stack<Integer>> dest = new HashMap<>();
for (String word : words) {
Stack<Integer> locations = new Stack<>();
for (int loc = -1; (loc = phrase.indexOf(word, loc + 1)) != -1;) {
locations.add(loc);
}
dest.put(word, locations);
}
return dest;
}
}
Program Output:
{90=[9, 19, 29], hello=[4, 13, 22]}

Related

Is there an easy way to eliminate the final comma in my output? Number Seperator

For another assignment i needed to program a "number seperator", that splits any given int value into all of its digits and returns it to the main class as a String.
I have the program up and running but there's a small problem with my output.
public class NumberSeperator {
static String splitNumber(int zahl) {
String s = Integer.toString(zahl);
return s;
}
public static void main(String args[]) {
System.out.println("Input a Number: ");
int zahl = readInt();
String ziffern = splitNumber(zahl);
for (int i = 0; i < ziffern.length(); i++) {
System.out.print(ziffern.charAt(i) + ",");
}
}
}
The output of 1234 should be: 1,2,3,4
and the actual output is: 1,2,3,4,
At the risk of sounding extremely stupid, is there an easy fix to this?
How about printing first element without comma and rest in form ,nextElement like
one, two, three
^^^---------------- - before loop
^^^^^----------- - loop iteration
^^^^^^^---- - loop iteration
It can be achieved like:
if(ziffern.length()>0){
System.out.print(ziffern.charAt(0));
}
for(int i=1; i<ziffern.length(); i++){
System.out.print(", "+ziffern.charAt(i));
}
OR you can convert ziffern to String[] array first and use built-in solution which is: String.join(delimiter, data)
System.our.print(String.join(",", ziffern.split("")));
When it's the last iteration, just don't add it.
In the last iteration, it will make the comma empty so that you won't see it after the last value.
String comma=",";
for (int i = 0; i < ziffern.length(); i++) {
if (i == ziffern.length()-1) {
comma="";
}
System.out.print(ziffern.charAt(i) + comma);
}
with Java 8 and streams you can do it in a single command:
String join = Arrays.asList(ziffern.split(""))
.stream()
.collect(Collectors.joining(","));
System.out.println(join);
or with just plain java 8:
String join = String.join(",", ziffern.split(""));
System.out.println(join);
A simple one liner will do your job:
static String splitNumber(int zahl) {
return String.join(",", String.valueOf(zahl).split(""));
}
Quite often this occurs when you know you have at least two items to print. So here is how you could do it then.
String ziffern = splitNumber(zahl);
String output = ziffern[0];
for (int i = 1; i < ziffern.length(); i++) {
output = "," + ziffern[i];
}
System.out.println(output);
You can just output the string without the last character.
Your modified code should be:
public class NumberSeperator {
static String splitNumber(int zahl) {
String s = Integer.toString(zahl);
return s;
}
public static void main(String args[]) {
int zahl = 1234;
String s="";
String ziffern = splitNumber(zahl);
for (int i = 0; i < ziffern.length(); i++) {
s+=ziffern.charAt(i) + ",";
}
System.out.println(s.substring(0,s.length()-1));
}

Used an arraylist in Java to find four consecutive letters in a dictionary, error while building the code

This is the initial challenge I'm trying to address
1) takes two arguments—a “source" English word in a string, and an English dictionary supplied in an array
2) returns a list of English words as an array
The words returned are those from the dictionary that have four consecutive letters (or more) in common with the “source” word. For example, the word MATTER has the four letters in a row “ATTE" in common ATTEND.
The code however gives me errors with the substring
Below is the code for your reference.
public class FourLetterInCommon {
static String wrd = "split";
static String[] d = new String[]{"SPLITS", "SPLITTED", "SPLITTER", "SPLITTERS", "SPLITTING", "SPLITTINGS", "SPLITTISM", "SPLITTISMS", "SPLITTIST", "SPLITTISTS"};
public static void main(String[] args){
System.out.println(fourletters (wrd, d));
}
public static List<String> fourletters (String word, String[] dict){
int dictsize = dict.length;
int wordlength = word.length();
List<String> Commonletters = new ArrayList<String>();
for(int i = 0; i<=dictsize; i++) {
for (int j=0; j<=wordlength;) {
if(dict[i].contains(word.substring(i, 5)))
{
Commonletters.add(dict[i]);
}
break;
}
}
return Commonletters;
}
}
This is the error message I get:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.substring(Unknown Source) at FourLetterInCommon.fourletters(FourLetterInCommon.java:22) at FourLetterInCommon.main(FourLetterInCommon.java:10)
What does the errors mean? Apologies, but a bit clueless at this stage.
Quite a few issues here.
1)
for(int i = 0; i<=dictsize; i++) {
should be
for(int i = 0; i<dictsize; i++) {
2)
for (int j=0; j<=wordlength;) {
should be
for (int j=0; j<=wordlength-4; j++) {
3)
if(dict[i].contains(word.substring(i, 5)))
should be
if(dict[i].contains(word.substring(j, j+4)))
4)
I don't believe you really want to break; there. I'm guessing you want to break when you find a match, so it should be inside the if statement.
Corrected code:
public class FourLetterInCommon
{
static String wrd = "SPLIT";
static String[] d = new String[] { "SPLITS", "SPLITTED", "SPLITTER", "SPLITTERS", "SPLITTING", "SPLITTINGS",
"SPLITTISM", "SPLITTISMS", "SPLITTIST", "SPLITTISTS" };
public static void main(String[] args)
{
System.out.println(fourletters(wrd, d));
}
public static List<String> fourletters(String word, String[] dict)
{
int dictsize = dict.length;
int wordlength = word.length();
List<String> Commonletters = new ArrayList<String>();
for (int i = 0; i < dictsize; i++)
{
for (int j = 0; j <= wordlength - 4; j++)
{
if (dict[i].contains(word.substring(j, j + 4)))
{
Commonletters.add(dict[i]);
break;
}
}
}
return Commonletters;
}
}
Output:
[SPLITS, SPLITTED, SPLITTER, SPLITTERS, SPLITTING, SPLITTINGS, SPLITTISM, SPLITTISMS, SPLITTIST, SPLITTISTS]
The following line would throw an Exception:
if(dict[i].contains(word.substring(i, 5)))
Here, i ranges from 0 to dict.length which is 10 in this case. word contains 5 characters only. So, accessing any character from index 5 onwards would throw an Exception.
If you want to check for certain number of characters then you should use this:
for (int j=0; j < wordlength;) {
if(dict[i].contains(word.substring(j, wordlength - j)))

i want to count occurrence of each word in a given sentence in java

beginner at java was asked in an interview
here i have to count the occurrence of each word in a given sentence.
for eg( "chair is equal to chair but not equal to table."
Output : chair :2,
is :1,
equal :2,
to :2,
but :1,
not :1,
table :1 )
I have written some part of the code and tried using for loop but i failed....
public static void main(String[] args)
{
int counter = 0;
String a = " To associate myself with an organization that provides a challenging job and an opportunity to provide innovative and diligent work.";
String[] b =a.split(" "); //stored in array and splitted
for(int i=0;i<b.length;i++)
{
counter=0;
for(int j<b.length;j>0;j--)
{
if(b[i] = b[j])
//
}
}
}
}
Use a hashmap to count frequency of objects
import java.util.HashMap;
import java.util.Map.Entry;
public class Funly {
public static void main(String[] args) {
int counter = 0;
String a = " To associate myself with an organization that provides a challenging job and an opportunity to provide innovative and diligent work.";
String[] b = a.split(" "); // stored in array and splitted
HashMap<String, Integer> freqMap = new HashMap<String, Integer>();
for (int i = 0; i < b.length; i++) {
String key = b[i];
int freq = freqMap.getOrDefault(key, 0);
freqMap.put(key, ++freq);
}
for (Entry<String, Integer> result : freqMap.entrySet()) {
System.out.println(result.getKey() + " " + result.getValue());
}
}
}
Quite easy since Java8:
public static Map<String, Long> countOccurrences(String sentence) {
return Arrays.stream(sentence.split(" "))
.collect(Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
}
I would also remove non literal symbols, and convert to lowecase before running:
String tmp = sentence.replaceAll("[^A-Za-z\\s]", "");
So your final main method for interview will be:
ppublic static void main(String[] args) {
String sentence = "To associate myself with an organization that provides a challenging job and an opportunity to provide innovative and diligent work.";
String tmp = sentence.replaceAll("[^A-Za-z\\s]", "").toLowerCase();
System.out.println(
countOccurrences(tmp)
);
}
Output is:
{diligent=1, a=1, work=1, myself=1, opportunity=1, challenging=1, an=2, associate=1, innovative=1, that=1, with=1, provide=1, and=2, provides=1, organization=1, to=2, job=1}
A simple (but not very efficient) way would be to add all the elements to a set, which doesn't allow duplicates. See How to efficiently remove duplicates from an array without using Set. Then iterate through the set and count the number of occurrences in your array, printing out the answer after each set element you check.
There are several solutions to this and I'm not going to provide you with any of them. However, I'm going to give you a rough outline of one possible solution:
You could use a Map, for example a HashMap, where you use the words as keys and the number of their occurrence as values. Then, all you need to do is to split the input string on spaces and iterate over the resulting array. For each word, you check if it already exists in the map. If so you increase the value by one, otherwise you add the word to the map and set the value to 1. After that, you can iterate over the map to create the desired output.
You need to use Map data structure which stores data in key-value pairs.
You can use the HashMap (implementation of Map) to store each word as key and their occurance as the value inside the Map as shown in the below code with inline comments:
String[] b =a.split(" "); //split the array
Map<String, Integer> map = new HashMap<>();//create a Map object
Integer counter=null;//initalize counter
for(int i=0;i<b.length;i++) { //loop the whole array
counter=map.get(b[i]);//get element from map
if(map.get(b[i]) == null) { //check if it already exists
map.put(b[i], 1);//not exist, add with counter as 1
} else {
counter++;//if already eists, increment the counter & put to Map
map.put(b[i], counter);
}
}
Using simple For loops
public static void main(String[] args) {
String input = "Table is this Table";
String[] arr1 = input.split(" ");
int count = 0;
for (int i = 0; i < arr1.length; i++) {
count = 0;
for (int j = 0; j < arr1.length; j++) {
String temp = arr1[j];
String temp1 = arr1[i];
if (j < i && temp.contentEquals(temp1)) {
break;
}
if (temp.contentEquals(temp1)) {
count = count + 1;
}
if (j == arr1.length - 1) {
System.out.println(">>" + arr1[i] + "<< is present >>" + count + "<< number of times");
}
}
}
}

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");

Disappearing Arraylist Values

I am writing a Java program that will take a sentence (or phrase) and translate it into a group of objects that the computer can easily read. I wanted to make a simple word separating program, and then extend it later on.
My code is like this:
package Literary;
import java.util.ArrayList;
public class WordParser {
public static String[] getWords(String tempone){
ArrayList<String> temptwo = new ArrayList();
ArrayList<Character> tempthree = new ArrayList();
for (int tempfour = 0; tempfour == tempone.length() - 1; tempfour++){
if (tempone.charAt(tempfour) != ' '){
tempthree.add(tempone.charAt(tempfour));
} else {
temptwo.add(getStringRepresentation(tempthree));
tempthree.clear();
}
}
String[] tempfive = new String[temptwo.size()];
for (int tempfour = 0; tempfour == tempfive.length - 1; tempfour++){
tempfive[tempfour] = temptwo.get(tempfour);
}
return tempfive;
}
/** Courtesy of Vineet Reynolds on StackExchange.
*
* "You can iterate through the list and create the string."
*
* #param list
* #return
*/
public static String getStringRepresentation(ArrayList<Character> list){
StringBuilder builder = new StringBuilder(list.size());
for(int i = 0; i == list.size() + 1; i++)
{
builder.append(list.get(i).charValue());
}
return builder.toString();
}
}
It's supposed to receive a string as an input, and return a list of strings that have been separated by spaces.
But when I run my main class:
import Literary.WordParser;
public class Start {
public static void main(String[] args) {
String x = "There was once a sword in the stone";
String[] tempstring = WordParser.getWords(x);
for (int i = 1; i == tempstring.length; i++){
System.out.println("Word " + i + " : " + tempstring[i]);
}
}
}
The console tells me nothing except run: and BUILD SUCCESSFUL (total time: 1 second).
I'm using Netbeans 8 and Java 1.7 if that helps.
Looks like the problem's here:
for (int i = 1; i == tempstring.length; i++) {
This for loop will run at most once: if tempstring is exactly one String long, it should print out the word.
However, since your test sentence has 8 words, nothing will ever print out (provided WordParser works correctly).
You probably want to change this line to: (note the < between i and tempstring.length.)
for (int i = 1; i < tempstring.length; i++) {
so that it will loop through all the items in tempstring.
You had multiple issues in your code:
1) for loops were not properly made, they would never execute. Use either !=, > or < instead of ==.
2) you don't need a method getWords() nor getStringRepresentation(). Method like that are already implemented in Java.
So the final code should be this:
public class WordParser {
public static String[] getWords(String tempone) {
return tempone.split(" ");
}
public static void main(String[] args) {
String x = "There was once a sword in the stone";
String[] tempstring = WordParser.getWords(x);
for (int i = 0; i < tempstring.length; i++) {
System.out.println("Word " + (i+1) + " : " + tempstring[i]);
}
}
}
Output:
Word 1 : There
Word 2 : was
Word 3 : once
Word 4 : a
Word 5 : sword
Word 6 : in
Word 7 : the
Word 8 : stone
I've also fixed your code that runs the same as above, if you are interested:
import java.util.ArrayList;
public class WordParser {
public static String[] getWords(String tempone) {
ArrayList<String> sarr = new ArrayList<String>();
ArrayList<Character> tempthree = new ArrayList<Character>();
String[] ansarr;
if(tempone.charAt(tempone.length()-1) != ' ')
tempone += " "; //Add white space to the end to catch the last word
for (int i = 0; i < tempone.length(); i++) {
if (tempone.charAt(i) != ' ') {
tempthree.add(tempone.charAt(i));
} else {
sarr.add(tempthree.toString());
tempthree.clear();
}
}
ansarr = new String[sarr.size()];
for (int i = 0; i < ansarr.length; i++) {
ansarr[i] = sarr.get(i);
}
return ansarr;
}
public static void main(String[] args) {
String x = "There was once a sword in the stone";
String[] tempstring = WordParser.getWords(x);
for (int i = 0; i < tempstring.length; i++) {
System.out.println("Word " + (i+1) + " : " + tempstring[i]);
}
}
}
Enjoy! :)
I think you should use String.split(" ") which seems to do the same thing
Change your main method as follows,
and it will work
public static void main(String[] args) {
String x = "There was once a sword in the stone";
String[] tempstring = WordParser.getWords(x);
for (int i = 1; i <= tempstring.length; i++){
System.out.println("Word " + i + " : " + tempstring[i - 1]);
}
}
For the WordParser you could use,
public class WordParser
{
public static String[] getWords(String tempone)
{
return tempone.split(" ");
}
}
First of, I would recommend using the split method to break up a sentence
it is defined as:
public String[] split(String regex, int limit)
and you can simply call
String s1=new String("Random words in a sentence");
String[] words=s1.split(" ");
in order to break the string up into words and you will now have a String
array of five elements where each element consists of a word
In Respect to your question, you are not using the conditional statement correctly
You want to iterate over the elements of the String array WHILE the position
is less than stringname.length, not only if it the position equals the stringname.length
Therefore, you must make the following changes in these parts of your code
For Example:
for (int i = 1; i == tempstring.length; i++)
should have its line changed to
for (int i = 1; i < tempstring.length; i++)
and this problem also occurs in various places in your WordParser.java file
It is useful to remember also that you may often want to start at index 0 instead
of index 1, as java has its' first indice as 0.

Categories