Algorithm to split string with comma only in the outer braces - java

I want to split string only inside the first braces. How can I do it in java
Input String 1: text2(text3, text4), text5(text6, text7)
String1: text2(text3, text4)
String2: text5(text6, text7)
Input String 2: text2, text3(text4, text5(text6, text7, text8))
String1: text2
String2: text3(text4, text5(text6, text7, text8))
Input String can have arbitrary number of levels. Please assume that the input string has matching braces.
Thanks in advance

package ic.ac.uk.relationshipvisualiser.app;
import java.util.ArrayList;
import java.util.List;
public class tmpTest3 {
public static List<String> process(String p_inp) {
List<String> res = new ArrayList<String>();
p_inp = p_inp.trim();
int numberOfOpenBracketsEncountered = 0;
String t = "";
String cur = "";
for (int c=0;c<p_inp.length();c++) {
cur = p_inp.substring(c,c+1);
if (cur.equals("(")) {
numberOfOpenBracketsEncountered++;
}
if (cur.equals(")")) {
numberOfOpenBracketsEncountered--;
}
if (cur.equals(",")) {
if (numberOfOpenBracketsEncountered==0) {
if (t.length()>0) res.add(t.trim());
t = "";
} else {
cur = cur;
t = t + cur;
}
} else {
cur = cur;
t = t + cur;
}
}
if (t.length()>0) res.add(t.trim());
return res;
}
public static void main(String[] args) {
System.out.println("Start tmpTest3");
List<String> inputs = new ArrayList<String>();
inputs.add("text2(text3, text4), text5(text6, text7)");
inputs.add("text2, text3(text4, text5(text6, text7))");
for (int c=0;c<inputs.size();c++) {
System.out.println("Running test for " + inputs.get(c));
List<String> res = process(inputs.get(c));
System.out.println("Got " + res.size() + " strings as a result:");
for (int d=0;d<res.size();d++) {
System.out.println(" - :" + res.get(d) + ":");
}
System.out.println("----------------------");
}
System.out.println("End tmpTest3");
}
}

Will This works for you ..?
import java.util.Arrays;
class Program {
public static void main (String[] args) throws java.lang.Exception {
String subject1 = "text2(text3, text4), text5(text6, text7)";
String subject2 = "text2, text3(text4, text5(text6, text7))";
String p = "\\s*\\d*\\(\\)";
String[] res = subject1.split(p);
System.out.println(Arrays.toString(res));
res=subject2.split(p);
System.out.println(Arrays.toString(res));
} // end main
} // end
Out put :-
[text2(text3, text4), text5(text6, text7)]
[text2, text3(text4, text5(text6, text7))]

Related

How to replace a word based on its length?

All words having the given length wordLength in the string sentence must be replaced with the word myWord. All parameters come from user input and may vary. I have tried this way but it only returns the initial string with the initial words.
Here is my source code:
package main;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
String sentence = "";
int wordLength = 0;
String myWord = "";
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader bis = new BufferedReader(is);
System.out.println("Text input: ");
sentence = bis.readLine();
System.out.println("Word lenth to replace");
wordLength = Integer.parseInt(bis.readLine());
System.out.println("Word to replace to");
myWord = bis.readLine();
Text myText = new Text(myWord, sentence, wordLength);
myText.changeSentence();
System.out.println("New string" + myText.getSentence());
}
}
class Text {
private String mySentence;
private int charNumber;
private String wordToChange;
private String newSentence = "1.";
public Text(String wordToChange, String mySentece, int charNumber) {
this.mySentence = mySentece;
this.wordToChange = wordToChange;
this.charNumber = charNumber;
}
public String getSentence() {
return newSentence;
}
public void changeSentence() {
int firstPos = 0;
int i;
for (i = 0; i < mySentence.length(); i++) {
if (mySentence.charAt(i) == ' ') {
if (i - firstPos == charNumber) {
newSentence = newSentence.concat(wordToChange + " ");
firstPos = i + 1;
} else {
newSentence = newSentence.concat(mySentence.substring(firstPos, i + 1));
firstPos = i + 1;
}
} else if (i == mySentence.length() - 1) {
if (i - firstPos == charNumber) {
newSentence = newSentence.concat(wordToChange + " ");
firstPos = i + 1;
} else {
newSentence = newSentence.concat(mySentence.substring(firstPos, i + 1));
firstPos = i + 1;
}
}
}
}
}
I changed your code a little bit:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
String sentence = "";
int wordLenght = 0;
String myWord = "";
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader bis = new BufferedReader(is);
try {
System.out.println("Text input: ");
sentence = bis.readLine();
System.out.println("Word lenth to replace");
wordLenght = Integer.parseInt(bis.readLine());
System.out.println("Word to replace to");
myWord = bis.readLine();
} catch (IOException e) {
e.printStackTrace();
}
Text myText = new Text(myWord, sentence, wordLenght);
System.out.println(myText.getChangeSentence());
}
}
class Text {
private String mySentence;
private int charNumber;
private String wordToChange;
private String newSentence = "1.";
public Text(String wordToChange, String mySentece, int charNumber) {
this.mySentence = mySentece;
this.wordToChange = wordToChange;
this.charNumber = charNumber;
}
public String getChangeSentence() {
String[] words = mySentence.split(" ");
for(int i = 0 ; i < words.length ; i++) {
if(words[i].length() == charNumber) {
words[i] = wordToChange;
}
}
for (String word : words) {
newSentence += word + " ";
}
return newSentence;
}
}
Input : This is a test
word length : 2
word to replace : ii
output: This ii a test
As I can see the only separator of words that is currently considered to appear in the input text is a single white space " ". If that's true, then the changeSentence method can be quite short. There is no need to do parse the sentence character by characted. Having in mind that the white space is a separator, you can simply split the sentence by the characted " " and collect them as words. After that you can just iterate through words and replace ones that lenght matches given input characters number. After that, you can just join words together with the previously used separator and that's it.
Examples if you want to try with loops
public void changeSentence() {
final String[] words = mySentence.split(" ");
for (int i = 0; i < words.length; i++) {
if (words[i].length() == charNumber) {
words[i] = wordToChange;
}
}
newSentence = String.join(" ", words);
}
or with regular expressions
public void changeSentence() {
String regex = "\\b\\w{" + charNumber+ "}\\b";
newSentence = mySentence.replaceAll(regex, wordToChange);
}
or with the stream API
public void changeSentence() {
newSentence = Arrays.stream(mySentence.split(" "))
.map(s -> s.length() == charNumber ? wordToChange : s)
.collect(Collectors.joining(" "));
}

Passing a parameter to another function

I wrote a code for hangman, and i want to pass the randomly guessed word(randomly guessed from a text file), to be passed to a function hangman() where i can get the length of the word. a random word will be guessed from the getRandomWord(String path) function and I have passed value obtained to function() But cannot seem to pass the and get the result.
public class Main {
public static void main(String[] args) throws IOException {
Main ma = new Main();
String stm= null;
loadWords();
//hangman(w);
function();
}
public static String[] loadWords() {
System.out.println("Loading words from file :");
try {
File myObj = new File("C:\\Users\\Admin\\Documents\\NetBeansProjects\\Main\\words.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNext()) {
String data = myReader.nextLine().toLowerCase();
String[] spl = data.split(" ");
System.out.println(spl.length + " words loaded");
return spl;
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
return null;
// TODO: Fill in your code here
}
public static String getRandomWord(String path) throws IOException {
List<String> words = new ArrayList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
String line;
while ((line = reader.readLine()) != null) {
String[] wordline = line.split("\\s+");
for (String word : wordline) {
words.add(word);
}
}
}
Random rand = new Random();
return words.get(rand.nextInt(words.size()));
}
public static List< String> getRemainingLetters(ArrayList< String> lettersGuessed) {
String alpha = "abcdefghijklmnopqrstuvwxyz";
String[] alpha1 = alpha.split("");
ArrayList< String> alpha2 = new ArrayList<>(Arrays.asList(alpha1));
for (int i = 0; i < lettersGuessed.size(); i++) {
for (int j = 0; j < alpha2.size(); j++) {
if (alpha2.get(j).equals(lettersGuessed.get(i))) {
alpha2.remove(j);
break;
}
}
}
return alpha2;
}
public static void function() throws IOException {
int numGuesses = 5;
String w = getRandomWord("C:\\Users\\Admin\\Documents\\NetBeansProjects\\Main\\words.txt");
String[] word = w.split("");
ArrayList< String> wList = new ArrayList<>(Arrays.asList(word));
ArrayList< String> wAnswer = new ArrayList< String>(wList.size());
for (int i = 0; i < wList.size(); i++) {
wAnswer.add("_ ");
}
int left = wList.size();
Scanner scanner = new Scanner(System.in);
boolean notDone = true;
ArrayList< String> lettersGuessed = new ArrayList< String>();
while (notDone) {
System.out.println();
String sOut = "";
List< String> lettersLeft = getRemainingLetters(lettersGuessed);
for (String s : lettersLeft) {
sOut += s + " ";
}
System.out.println("Letters Left: " + sOut);
sOut = "";
for (int i = 0; i < wList.size(); i++) {
sOut += wAnswer.get(i);
}
System.out.println(sOut + " Guesses left:" + numGuesses);
System.out.print("Enter a letter(* exit): ");
String sIn = scanner.next();
numGuesses--;
if (sIn.equals("*")) {
break;
}
lettersGuessed.add(sIn);
for (int i = 0; i < wList.size(); i++) {
if (sIn.equals(wList.get(i))) {
wAnswer.set(i, sIn);
left--;
}
}
if (left == 0) {
System.out.println("Congradulations you guessed it!");
break;
}
if (numGuesses == 0) {
StringBuilder sb = new StringBuilder();
for (String string : wList) {
sb.append(string);
}
String stm = sb.toString();
System.out.println("Sorry you ran out of guesses, the word was: " + stm);
break;
}
}
}
public static void hangman(String word) {
System.out.println("Welcome to Hangman Ultimate Edition");
System.out.println("I am thinking of a word that is " + word.length() + " letters long");
System.out.println("-------------");
}
}
Problems in your code:
Not passing the random word to the methods, hangman and function.
Instead of re-using the random word obtained from the method, getRandomWord in main, you have called getRandomWord again in the method, hangman which will give you a different random word causing incosistency.
Given below is the corrected program with a sample run:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
String word = getRandomWord("C:\\Users\\Admin\\Documents\\NetBeansProjects\\Main\\words.txt");
hangman(word);
function(word);
}
public static String getRandomWord(String path) throws IOException {
List<String> words = new ArrayList<String>();
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
String line;
while ((line = reader.readLine()) != null) {
String[] wordline = line.split("\\s+");
for (String word : wordline) {
words.add(word);
}
}
}
Random rand = new Random();
return words.get(rand.nextInt(words.size()));
}
public static List<String> getRemainingLetters(ArrayList<String> lettersGuessed) {
String alpha = "abcdefghijklmnopqrstuvwxyz";
String[] alpha1 = alpha.split("");
ArrayList<String> alpha2 = new ArrayList<>(Arrays.asList(alpha1));
for (int i = 0; i < lettersGuessed.size(); i++) {
for (int j = 0; j < alpha2.size(); j++) {
if (alpha2.get(j).equals(lettersGuessed.get(i))) {
alpha2.remove(j);
break;
}
}
}
return alpha2;
}
public static void function(String w) throws IOException {
// The available number of guesses = length of the random word
int numGuesses = w.length();
// Split the random word into letters
String[] word = w.split("");
ArrayList<String> wList = new ArrayList<>(Arrays.asList(word));
ArrayList<String> wAnswer = new ArrayList<String>(wList.size());
for (int i = 0; i < wList.size(); i++) {
wAnswer.add("_ ");
}
int left = wList.size();
Scanner scanner = new Scanner(System.in);
boolean notDone = true;
ArrayList<String> lettersGuessed = new ArrayList<String>();
while (notDone) {
System.out.println();
String sOut = "";
List<String> lettersLeft = getRemainingLetters(lettersGuessed);
for (String s : lettersLeft) {
sOut += s + " ";
}
System.out.println("Letters Left: " + sOut);
sOut = "";
for (int i = 0; i < wList.size(); i++) {
sOut += wAnswer.get(i);
}
System.out.println(sOut + " Guesses left:" + numGuesses);
System.out.print("Enter a letter(* exit): ");
String sIn = scanner.next();
numGuesses--;
if (sIn.equals("*")) {
break;
}
lettersGuessed.add(sIn);
for (int i = 0; i < wList.size(); i++) {
if (sIn.equals(wList.get(i))) {
wAnswer.set(i, sIn);
left--;
}
}
if (left == 0) {
System.out.println("Congradulations you guessed it!");
break;
}
if (numGuesses == 0) {
StringBuilder sb = new StringBuilder();
for (String string : wList) {
sb.append(string);
}
String stm = sb.toString();
System.out.println("Sorry you ran out of guesses, the word was: " + stm);
break;
}
}
}
public static void hangman(String word) {
System.out.println("Welcome to Hangman Ultimate Edition");
System.out.println("I am thinking of a word that is " + word.length() + " letters long");
System.out.println("-------------");
}
}
A sample run:
Welcome to Hangman Ultimate Edition
I am thinking of a word that is 3 letters long
-------------
Letters Left: a b c d e f g h i j k l m n o p q r s t u v w x y z
_ _ _ Guesses left:3
Enter a letter(* exit): c
Letters Left: a b d e f g h i j k l m n o p q r s t u v w x y z
_ _ _ Guesses left:2
Enter a letter(* exit): a
Letters Left: b d e f g h i j k l m n o p q r s t u v w x y z
_ _ _ Guesses left:1
Enter a letter(* exit): t
Sorry you ran out of guesses, the word was: fox
To make your existing code run, you should just clean up the main method:
remove unused code:
Main ma = new Main(); // no need to create an instance, you use only static methods
String stm= null; // not used anywhere
loadWords(); // not used, entire method may be removed:
// it reads words only in the first line
fix method function to have a String w parameter, move getting the random word out of this method.
Thus, resulting changes should be:
public static void main(String[] args) throws IOException {
String word = getRandomWord("C:\\Users\\Admin\\Documents\\NetBeansProjects\\Main\\words.txt");
hangman(word);
function(word);
}
public static void function(String w) throws IOException {
int numGuesses = 5;
String[] word = w.split("");
// ... the rest of this method remains as is
}

How to Split String in "" after comma (,)

If I have String string = "[10.10, 20.20, 30.30]";
How to split into this format ["10.10", "20.20", "30.30"]
Before splitting, you need to take away the brackets, using substring
String string = "[10.10, 20.20, 30.30]";
String[] res = string.substring(1, string.length() - 1).split(",\\s");
System.out.println(Arrays.toString(res)); // [10.10, 20.20, 30.30]
Do it as follows:
public class Main {
public static void main(String[] args) {
String string = "[10.10, 20.20, 30.30]";
String[] arr = string.replace("[", "").replace("]", "").split(",");
for (int i = 0; i < arr.length; i++) {
arr[i] = "\"" + arr[i].trim() + "\"";
}
String newStr = "[" + String.join(", ", arr) + "]";
System.out.println(newStr);
}
}
Output:
["10.10", "20.20", "30.30"]
If you have a String[] to convert, you can do it as follows:
import java.util.Arrays;
import java.util.stream.Collectors;
public class Main {
public static void main(String args[]) {
String[] strArr = { "10.10", "20.20", "30.30" };
System.out.println("Before: " + Arrays.toString(strArr));
strArr = Arrays.stream(strArr).map(s -> "\"" + s + "\"").collect(Collectors.toList()).toArray(new String[0]);
System.out.println("After: " + Arrays.toString(strArr));
}
}
Output:
Before: [10.10, 20.20, 30.30]
After: ["10.10", "20.20", "30.30"]
[Update]
Posting the following update based on the requirement mentioned by OP in the comment:
public class Main {
public static void main(String[] args) {
String str = "10.10,20.20,30.30";
str = "[" + str.replaceAll("[0-9.-]+", "\"$0\"") + "]";
System.out.println(str);
}
}
Output:
["10.10","20.20","30.30"]

Implementing Elimination of Immediate Left-Recursion in Java

I am working on implementing a generic code to solve left recursion problem in a grammar using java so my code is working as follows I am reading an input like this as each line goes to the next line:
E
E+T|T
T
T*F|F
F
(E)|id|number
and the required output is supposed to be like this one :
E->[TE']
T->[FT']
F->[(E), id, number]
E'->[+TE', !]
T'->[*FT', !]
I wrote that code which is storing input in Arraylists to iterate over them and produce the output:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class IleftRecursion {
//storing each line in its corresponding Arraylist
static ArrayList<String> leftRules = new ArrayList<>();
static ArrayList<String> rightRules = new ArrayList<>();
public static void read_file(String file) throws IOException {
FileReader in = new FileReader(file);
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
leftRules.add(line);
rightRules.add(br.readLine());
}
br.close();
}
public static void ss() {
for (int i = 0; i < leftRules.size(); i++) {
for (int j = 1; j <= i - 1; j++) {
//splitting inputs on bars "|" to iterate through them
for (String x : rightRules.get(i).split("\\|")) {
if (x.contains(leftRules.get(j))) {
String f = "";
String ff = "";
for (int k=0; k<rightRules.get(k).split("\\|").length;k++) {
f = x;
f = f.replaceAll(leftRules.get(i), rightRules.get(k).split("\\|")[k]);
ff += f;
}
rightRules.remove(i);
rightRules.add(i, ff);
}
}
}
//Recursive or Not boolean
boolean isRec = false;
for (String z : rightRules.get(i).split("\\|")) {
if (z.startsWith(leftRules.get(i))) {
isRec = true;
break;
}
}
if (isRec) {
String a = "";
String b = "";
for (String s : rightRules.get(i).split("\\|")) {
if (s.startsWith(leftRules.get(i))) {
b += s.replaceAll(leftRules.get(i), "") + leftRules.get(i) + "',";
} else {
a += s + leftRules.get(i) + "'";
}
}
b += "!";
if(a.length()>=1)
a.substring(1, a.length() - 1);
rightRules.add(i, a);
rightRules.add(i + 1, b);
leftRules.add(leftRules.get(i) + "'");
}
}
}
public static void main(String[] args) throws IOException {
read_file("Sample.in");
ss();
for (int i=0;i<leftRules.size();i++)
{
System.out.print(leftRules.get(i)+"->");
System.out.println("["+rightRules.get(i)+"]");
}
}
}
I debugged the code many times trying to figure out why Am I getting output like this
E->[TE']
T->[+TE',!]
F->[T]
E'->[T*F]
Which is missing One rule and also not all the new productions generated in the right way but I couldn't fix could anyone help me through that ?

How would I compare jumbled words to dictionary words in two files using HashMaps in Java?

So I constructed some simple code to compare two text files. One with a jumbled list of words that are supposed to match up to words in the dictionary file. Basically finding which jumbled words match to their dictionary word. Some words have a few jumbled words that match to them, some don't have any matches. I'm looking to change this code to be much simpler, using HashMaps to make the program simpler and faster, but I'm not very good with HashMaps at all and could use the help.
Here is the code I currently have for the non-hashmap version if it helps:
import java.util.*;
import java.io.*;
public class Project6
{
public static void main(String[] args) throws Exception
{
if (args.length < 2 ) die( "Must give name of two input files on cmd line." );
BufferedReader dFile = new BufferedReader( new FileReader( args[0] ) );
BufferedReader jFile = new BufferedReader( new FileReader( args[1] ) );
ArrayList<String> jWordList= new ArrayList<String>();
ArrayList<String> dWordList= new ArrayList<String>();
long startTime = System.currentTimeMillis();
while (dFile.ready())
{
String word = dFile.readLine();
dWordList.add( word );
}
dFile.close();
while (jFile.ready())
{
String word = jFile.readLine();
jWordList.add( word );
}
jFile.close();
Collections.sort( dWordList );
Collections.sort( jWordList );
String[] dArray = dWordList.toArray(new String[dWordList.size()]);
String[] jArray = jWordList.toArray(new String[jWordList.size()]);
dArray = canonArray( dArray );
jArray = canonArray( jArray );
for(int i = 0 ; i < jWordList.size() ; i++)
{
String jWord = jArray[i];
System.out.print(jWordList.get(i) + " ");
for(int c = 0 ; c < dWordList.size() ; c++)
{
String dWord = dArray[c];
if(jWord.equals(dWord))
{
System.out.print(dWordList.get(c) + " ");
}
}
System.out.println();
}
long endTime = System.currentTimeMillis();
long ms = endTime-startTime;
System.out.println("Elapsed time in seconds: " + ms/1000.0 + "\n"); // 1 ms is a 1,000th of a second
}
private static void die( String errmsg )
{
System.out.println( "\nFATAL ERROR: " + errmsg + "\n" );
System.exit(0);
}
private static String toCanonical( String word )
{
char[] charArray = word.toCharArray();
Arrays.sort(charArray);
String charNewString = new String(charArray);
return charNewString;
}
private static String[] canonArray( String[] Arr )
{
String[] newArr = new String[Arr.length];
for(int i = 0 ; i < Arr.length ; i++)
{
String temp = toCanonical(Arr[i]);
newArr[i] = temp;
}
return newArr;
}
}
It produces the following output, which I would like to keep exactly the same (minus the print of elapsed time):
What you want is to define a HashMap such that the key's hash and equals method will come out the same regardless of the order and case of the string's characters. The following takes a String and converts it to lowercase and sorts the characters.
import java.util.*;
import java.io.*;
public class Project6 {
public static void main(String[] args) throws Exception {
if (args.length < 2) die("Must give name of two input files on cmd line.");
BufferedReader dFile = new BufferedReader(new FileReader(args[0]));
BufferedReader jFile = new BufferedReader(new FileReader(args[1]));
HashMap<String, List<String>> dWordMap = new HashMap<String, List<String>>();
long startTime = System.currentTimeMillis();
while (dFile.ready()) {
String word = dFile.readLine();
if (word == null) break;
addWord(word, dWordMap);
}
dFile.close();
while (jFile.ready()) {
String jWord = jFile.readLine();
if (jWord == null) break;
List<String> dWords = dWordMap.get(createKey(jWord));
if (dWords != null) {
System.out.println(jWord + " " + dWords);
}
}
jFile.close();
long endTime = System.currentTimeMillis();
long ms = endTime - startTime;
System.out.println("Elapsed time in seconds: " + ms / 1000.0 + "\n");
}
private static void die(String errmsg) {
System.out.println("\nFATAL ERROR: " + errmsg + "\n");
System.exit(0);
}
private static String createKey(String word) {
char[] chword = word.toLowerCase().toCharArray();
Arrays.sort(chword);
return new String(chword);
}
private static void addWord(String word, Map<String, List<String>> map) {
String key = createKey(word);
List<String> list = map.get(key);
if(list==null) {
list = new ArrayList<String>();
map.put(key, list);
}
list.add(word);
}
}

Categories

Resources