Getting words from a file Inputs - java

I am trying to take in words from a file input that only contains strings and store each word separately into a single array (ArrayList is not allowed).
My code below takes in the file input, but takes it in as one chunk. For example, if the file input was "ONE TWO THREE" I want each word to have its own index in the array (array[0] = "ONE", array[1]="TWO" and array[2]="THREE") but my code below just takes the sentence and puts it all in array[0] = "ONE TWO THREE". How can I fix this?
int i = 0;
String wd = "";
while (in.hasNextLine() ) {
wd = in.nextLine() ;
array[i] = wd;
i++;
System.out.println("wd");
}

Thats happens because you a reading LINES from the file. You can do something like this:
String array[]=in.nextLine().split(" ");

f the file input was " ONE TWO THREE" i want each word to have its own
space in the array so array[0] = ONE, array1=TWO and array[2]=THREE
Use String#split(delim) with white space as delimiter.
String fileInput = "ONE TWO THREE";
String[] array = filrInput.split("\\s");

Instead of the line
array[i] = wd; // since wd is the whole line, this puts lines in the array
you want to split the line you read in and put the split items in your array.
String[] items = wd.split("\\s+"); // splits on any whitespace
for (String item : items) { // iterate through the items and shove them in the array
array[i] = item;
i++;
}

I would set the delimiter to space " " then use .next().
in.useDelimiter(" ");
while(in.hasNext()){
wd = in.next();
//wd will be one word
}

Related

Way to scan contents of a singular array index?

There is an array in my code that includes the names to random items delimited by a /n (i think). the splitLines[] array is an organizational method that collects strings and integers separated by a delimiter in a file. The file is formatted as
<<Prize’s Name 0>>\t<<Prize’s Price 0>>\n
<<Prize’s Name 1>>\t<<Prize’s Price 1>>\n
My goal is to assign each line in the contents of splitLines[0] and splitLines[1] to its own index in separate arrays. The splitLines[0] array is formatted as
<<Prize's Name 0>>/n
<<Prize's Name 1>>/n
and the splitLines[1] array is formatted as
<<Prize's Price 0>>/n
<<Prize's Price 1>>/n
The process here is messy and convoluted, but as I am still learning the inner workings of arrays (and java as a language), I have yet to find a way that successfully reads through the array index and picks out each and every word and assigns it to another array. So far I have tried setting up a Scanner that takes splitLines[] as a parameter, but I am unsure whether fileScanner.next{Int,Line,Double, etc.}() is capable of reading into the array index at all. I am unsure how to proceed from here. Here is the block that I have so far
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.Math;
public class DrewCarey {
public static void main(String[] args) throws FileNotFoundException {
{
int min = 0;
int max = 52;
int randomIndex = (int)Math.floor(Math.random()*(max-min+1)+min);
String[] aPrize = new String[53];
int[] aPrice = new int[53];
final String DELIM = "\t";
Scanner fileScanner = new Scanner(new File("PrizeFile.txt"));
String fileLine = fileScanner.nextLine();
String[] splitLines = fileLine.split(DELIM);
String temp = "drew";
while(fileScanner.hasNextLine())
{
for(int i=0;i<aPrize.length;i++)
{
fileLine = fileScanner.nextLine();
splitLines = fileLine.split(DELIM);
if(fileLine.split(DELIM) != splitLines)
{
// String name = splitLines[0];
// int price = Integer.parseInt(splitLines[1]);
//splitLines[0] = aPrize[i];
// price = aPrice[i];
System.out.println(splitLines[0]);
// splitLines[0] = temp;
// splitLines[1] = temp;
}
}
}
fileScanner.close();
} ```
Your file/data is formatted in a very strange way which will cause all manner of issues, also are you splitting with "\n" or "/n" it is conflicting in your question. You should NOT use "\n" for the split because it is confused with an actual JAVA newline chracter. So assuming the file data is a single line that looks like this with "/n" and "/t":
<<Prize’s Name 0>>/t<<Prize’s Price 0>>/n <<Prize’s Name 1>>/t<<Prize’s Price 1>>/n <<Prize’s Name 2>>/t<<Prize’s Price 2>>/n <<Prize’s Name 3>>/t<<Prize’s Price 3>>/n <<Prize’s Name 4>>/t<<Prize’s Price 4>>
Then you can correctly split the first line of the file as shown below. The biggest problem in your code is that you only split with the "t" DELIM, never with the "n" delim. The below code solves this problem by splitting with "/n" first, then we split the resulting line with the "/t" and simply assign each part of the split to the aPrize and aPrice array.
//Add "\n" delim
final String DELIM_N = "/n ";
final String DELIM_T = "/t";
//We will use two string arrays in this demo for simplicity
String[] aPrize = new String[53];
String[] aPrice = new String[53];
Scanner fileScanner = new Scanner(new File("PrizeFile.txt"));
//Get first line
String fileLine = fileScanner.nextLine();
//Split line with "/n"
String[] splitLines = fileLine.split(DELIM_N);
//loop through array of split lines and save them in the Prize and Price array
for (int i = 0; i < splitLines.length; i++)
{
//Split each itom with "/t"
String[] splitItems = splitLines[i].split(DELIM_T);
//Check that each line does not have unexpected items
if (splitItems.length > 2)
{
System.out.println("Unexpected items found");
}
else
{
//Insert your code here to clean the input and remove the << and >> around items and parse them as an int etc.
//Assign the items to the array
//index 0 is prize
aPrize[i] = splitItems[0];
//and index 1 is price
aPrice[i] = splitItems[1];
}
}
//Complete. Print out the result with a loop
System.out.println("File read complete, Data split into two arrays:");
for (int i = 0; i < 10; i++)
{
System.out.println("Prize at index "+ i +" is: " + aPrize[i]);
System.out.println("Price at index "+ i +" is: " + aPrice[i]);
}
The output is as follows:
File read complete, Data split into two arrays:
Prize at index 0 is: <<Prize’s Name 0>>
Price at index 0 is: <<Prize’s Price 0>>
Prize at index 1 is: <<Prize’s Name 1>>
Price at index 1 is: <<Prize’s Price 1>>
...
I didn't understand your concern completely.
Try using ArrayList implementation of List instead of array.
Example:
List<String> aPrice = new ArrayList<>();
aPrice.add("some string");
You cant add more elements to array. ArrayList internally uses array,
but has methods to extend the number of elements stored.
You can retrieve elements by index as well.
You can use Arrays.asList() method to convert array to list if required.
You can check out the docs for more : ArrayList Documentation

Hanging Letter Program

I was practicing problems in JAVA for the last few days and I got a problem like this:
I/p: I Am A Good Boy
O/p:
I A A G B
m o o
o y
d
This is my code.
System.out.print("Enter sentence: ");
String s = sc.nextLine();
s+=" ";
String s1="";
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(c!=32)
{s1+=c;}
else
{
for(int j=0;j<s1.length();j++)
{System.out.println(s1.charAt(j));}
s1="";
}
}
The problem is I am not able to make this design.My output is coming as each character in each line.
First, you need to divide your string with space as a delimiter and store them in an array of strings, you can do this by writing your own code to divide a string into multiple strings, Or you can use an inbuilt function called split()
After you've 'split' your string into array of strings, just iterate through the array of strings as many times as your longest string appears, because that is the last line you want to print ( as understood from the output shared) i.e., d from the string Good, so iterate through the array of strings till you print the last most character in the largest/ longest string, and exit from there.
You need to handle any edge cases while iterating through the array of strings, like the strings that does not have any extra characters left to print, but needs to print spaces for the next string having characters to be in the order of the output.
Following is the piece of code that you may refer, but remember to try the above explained logic before reading further,
import java.io.*;
import java.util.*;
public class MyClass {
public static void main(String args[]) throws IOException{
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
String[] s = sc.nextLine().split(" ");
// Split is a String function that uses regular function to split a string,
// apparently you can strings like a space given above, the regular expression
// for space is \\s or \\s+ for multiple spaces
int max = 0;
for(int i=0;i<s.length;i++) max = Math.max(max,s[i].length()); // Finds the string having maximum length
int count = 0;
while(count<max){ // iterate till the longest string exhausts
for(int i=0;i<s.length;i++){
if(count<s[i].length()) System.out.print(s[i].charAt(count)+" "); // exists print the character
else System.out.print(" "); // Two spaces otherwise
}
System.out.println();count++;
}
}
}
Edit: I am sharing the output below for the string This is a test Input
T i a t I
h s e n
i s p
s t u
t

Check if String contains multiple values stored in Array of strings

I'm trying to write a program that checks if a string contains multiple words that must be occurred in a specific order the words are stored in Array of Strings
Here what I have reached so far
boolean Check = false;
Scanner S = new Scanner(System.in);
System.out.println("What is your question?");
String input=S.nextLine();
String[] Words = {"pay","car"};
for (int i = 0; i <= Words.length -1 ; i++) {
if (input.matches(".*\\b"+Words[i]+"\\b.*") && input.matches(".*\\b"+Words[1]+"\\b.*")) {
Check = true;
}
}
if (Check){
System.out.println("30k Dollar");
} else{
System.out.println("Wrong info! ");
}
Basically, what my code does is when the user input for example
"how much should i pay for the car?" he will get an answer of "30k Dollar"
because the strings "pay" and "car" are both in my array of strings.
Case 2: if the user input " bla bla car bla bla pay"
he will get the same answer.
How can I prevent the program from giving the same answer for the 2 different questions?
also in my code I used Words[i] and Words[1] but when I got larger list of words this wont work, I tried using nested loop but it didn't work.
You don't need to iterate over input words, just generate the full regex:
String[] words = {"pay","car"};
String regex = ".*\\b" + String.join("\\b.*\\b", words) + "\\b.*";
String test1= "how much should i pay for the car?";
System.out.println(test1.matches(regex)); // True
String test2 = "bla bla car bla bla pay";
System.out.println(test2.matches(regex)); // False
I will assume you always look for words separated by spaces, so you can get the words separated using split
String inputWords[] = input.split(" ");
First thing we need to reduce the time complexity of checking if the word is in our array so we can fill the array in a set but since we care about the order we better use a map with key the word and value the index of that word in the array
Map<String,Integer> map = new HashMap<>();
String[] words = {"pay","car"};
for(int i =0; i< words.length; i++)
map.put(words[i], i);
So now all you need is to iterate over your inputWords and check that all the words are there and you are not violating the order, this time complexity is O(n)
int lastFoundIndex = -1;
int numFound =0;
for(int i=0; i < inputWords.length; i++) {
if(map.get(inputWords[i]) != null ) {
if(map.get(inputWords[i]) < lastFoundIndex)
break;
lastFoundIndex = map.get(inputWords[i]);
numFound ++;
}
}
if(numFound >= words.length) // this condition means we are allowing more than occurence without violating the order
system.out.println("30k Dollar");
else
System.out.println("Wrong info! ");
You could combine them into a single regex check. You're already matching any character before or after (with .*) so just basically concatenate your regex strings into a single check.
if (input.matches(".*\\b" + Words[0] + "\\b.*\\b" + Words[1] + "\\b.*"))
EDIT: response to "also in my code I used Words[i] and Words[1] but when I got larger list of words this wont work, I tried using nested loop but it didn't work."
You could just iterate over the input words to create the regex string.
String regexPattern = ".*\\b" + String.Join("\\b.*\\b", Words) + "\\b.*";
EDIT2: here's my answer and edit combined w/ more context in the code:
String[] Words = {"pay","car"};
String regexPattern = ".*\\b" + String.Join("\\b.*\\b", Words) + "\\b.*";
if (input.matches(regexPattern)) {
System.out.println("30k Dollar");
} else {
System.out.println("Wrong info!");
}
EDIT3: Replaced Words.Join() with String.Join() cause I can Java w/o a compiler, real gud.

if statement not adding value to my counter in word count program

I have a java program that reads a txt file and counts the words in that file. I setup my program so the String read from the txt file is saved as an ArrayList, and my variable word contains that ArrayList. The issue with my code is that my if statement does not seem to add a value to my count variable each time it detects space in the word string, it seems to only run the if statement once. How can I make it so the if statement finds a space, adds a +1 to my counter value, removes the space, and looks for the next space in the word variable's string? Here is the code:
import java.io.*;
import java.util.*;
public class FrequencyCounting
{
public static void main(String[] args) throws FileNotFoundException
{
// Read-in text from a file and store each word and its
// frequency (count) in a collection.
Scanner inputFile = new Scanner(new File("phrases.txt"));
String word= " ";
Integer count = 0;
List<String> ma = new ArrayList<String>();
while(
inputFile.hasNextLine()) {
word = word + inputFile.nextLine() + " ";
}
ma.add(word);
System.out.println(ma);
if(word.contains(" ")) {
ma.remove(" ");
count++;
System.out.println("does contain");
}
else {
System.out.println("does not contain");
}
System.out.println(count);
//System.out.println(ma);
inputFile.close();
// Output each word, followed by a tab character, followed by the
// number of times the word appeared in the file. The words should
// be in alphabetical order.
; // TODO: Your code goes here.
}
}
When I execute the program, I get a value of 1 for the variable count and I get a returned string representation of the txt file from my phrases.txt
phrases.txt is :
my watch fell in the water
time to go to sleep
my time to go visit
watch out for low flying objects
great view from the room
the world is a stage
the force is with you
you are not a jedi yet
an offer you cannot refuse
are you talking to me
Your if statement is not inside any loop, so it will only execute once.
A better approach, which would save a shit ton of runtime, is to read each line like you already do, use the String.split() method to split it on spaces, then add each element of the returned String[] to your list by using the ArrayList.addAll() method (if that one exist, otherwise (optionally, ensure the capacity and) add the elements one by one).
Then count by using the ArrayList.size() method to get the number of elements.
Based on the comments in your code :
// Read-in text from a file and store each word and its
// frequency (count) in a collection.
// Output each word, followed by a tab character, followed by the
// number of times the word appeared in the file. The words should
// be in alphabetical order.
My understanding is that you need to store count for every word, rather having a total count of words. For storing count for every word which should be stored itself in alphabetical order, it is better to go with a TreeMap.
public static void main(String[] args) {
Map<String, Integer> wordMap = new TreeMap<String, Integer>();
try {
Scanner inputFile = new Scanner(new File("phrases.txt"));
while(inputFile.hasNextLine()){
String line = inputFile.nextLine();
String[] words = line.split(" ");
for(int i=0; i<words.length; i++){
String word = words[i].trim();
if(word.length()==0){
continue;
}
int count = 0;
if(wordMap.containsKey(word)){
count = wordMap.get(word);
}
count++;
wordMap.put(word, count);
}
}
inputFile.close();
for(Entry<String,Integer> entry : wordMap.entrySet()){
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
What is your goal here ? Do you just want to read the file and count numbers of words?
You need to use a while loop instead of an if statement that'll just run once. Here's a better way to do what you want to do:
Scanner inputFile = new Scanner(new File("phrases.txt"));
StringBuilder sb = new StringBuilder();
String line;
int totalCount = 0;
while(inputFile.hasNextLine()) {
line = inputFile.nextLine();
sb.append(line).append("\n"); // This is more efficient than concatenating strings
int spacesOnLine = countSpacesOnLine(line);
totalCount += spacesOnLine;
// print line and spacesOnLine if you wish to here
}
// print text file
System.out.println(sb.toString());
// print total spaces in file
System.out.println("Total spaces" + totalCount);
inputFile.close();
Then add a method that counts the spaces on a line:
private int countSpacesOnLine(String line) {
int totalSpaces = 0;
for(int i = 0; i < line.length(); i++) {
if (line.charAt(i) == ' ')
totalSpaces += 1;
}
return totalSpaces;
}
You can achieve your objective with the following one liner too:
int words = Files.readAllLines(Paths.get("phrases.txt"), Charset.forName("UTF-8")).stream().mapToInt(string -> string.split(" ").length).sum();
probably I am late, but here is c# simple version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace StackOverflowAnswers
{
class Program
{
static void Main(string[] args)
{
string contents = File.ReadAllText(#"C:\temp\test.txt");
var arrayString = contents.Split(' ');
Console.WriteLine("Number of Words {0}", arrayString.Length);
Console.ReadLine();
}
}
}

Java - Importing text file into array when lines are not consistent

I have an assignment that pretty much has me stumped early on, the remainder of which is fairly easy (sorting the data once its imported and then saving it again under a different name).
We need to import data from a .txt file into 3 separate Arrays ( name, mascot, alias ) however the lines are not consistent. By consistent I mean one line may have:
Glebe,G Shield,Glebe District
While another line may have:
St George,Knight & Dragon,Saints,Dragons,St George Illawarra
Everything before the first , belongs to the name array.
Everything after the first , but before the second , belongs to the mascot array.
Everything after the second , till the end of the line belongs to the alias array.
I've been able to work out how to import the .txt file where it contains the entire line, which I was then able to convert into importing everything before a "," and new line (using Delimiters). However the lines that contain more then 3 sets of data ruin the import as the alias array only ends up holding 1 not everything else.
Thus does anyone know of and can show me a code that pretty much does:
name = Everything before the first ,
Mascot = Everything after the first , but before the second ,
Alias = Everything after the second , till the end of the line
That I could use as a base to work into mine?
After a day of research I've constantly come up with dead ends. They all generally involve splitting up at each comma but that breaks the import (lines with more then 1 alias, the second alias is put into the name array, ect)
This is the code I came up with that imports the entire line into an array:
public static void LoadData() throws IOException
{
String clubtxt = ("NRLclubs.txt");
String datatxt = ("NRLdata.txt");
int i, count;
File clubfile = new File(clubtxt);
File datafile = new File(datatxt);
if (clubfile.exists())
{
count = 0;
Scanner inputFile = new Scanner(clubfile);
i = 0;
while(inputFile.hasNextLine())
{
count++;
inputFile.nextLine();
}
String [] teamclub = new String[count];
inputFile.close();
inputFile = new Scanner(clubfile);
while(inputFile.hasNext())
{
teamclub[i] = inputFile.nextLine();
System.out.println(teamclub[i]);
i++;
}
inputFile.close();
}
else
{
System.out.println("\n" + "The file " + clubfile + " does not exist." + "\n");
}
if (datafile.exists())
{
count = 0;
Scanner inputFile = new Scanner(datafile);
i = 0;
while(inputFile.hasNextLine())
{
count++;
inputFile.nextLine();
}
String [] teamdata = new String[count];
inputFile.close();
inputFile = new Scanner(datafile);
while(inputFile.hasNext())
{
teamdata[i] = inputFile.nextLine();
System.out.println(teamdata[i]);
i++;
}
inputFile.close();
}
else
{
System.out.println("\n" + "The file " + datafile + " does not exist." + "\n");
}
}
Look at String.split method with the parameter limit.
When you have your input line in a variable called line, you can can call
String[] tokens = line.split(',', 3);
This will split the line on the commas, while making sure that it will not return more than 3 tokens. It returns an array of String in which the first element will be what is before the first comma, the second will be what is between the first and second commas, and the third element will be what is after the second comma.
Since you only want to parse on the first 2 commas, you can use String split with a limit.
If you prefer, you can use the String indexOf method to find the first 2 commas, then use the String substring method to get the characters between the commas.
You want to be able to handle a line with one comma, or no commas at all.
Here's one way to parse the String line
public List<String> splitLine(String line) {
List<String> list = new ArrayList<String>();
int firstPos = line.indexOf(",");
int secondPos = line.indexOf(",", firstPos + 1);
if (firstPos >= 0) {
if (secondPos >= 0) {
list.add(line.substring(0, firstPos));
list.add(line.substring(firstPos + 1, secondPos));
list.add(line.substring(secondPos + 1));
} else {
list.add(line.substring(0, firstPos));
list.add(line.substring(firstPos + 1));
list.add("");
}
} else {
list.add(line);
list.add("");
list.add("");
}
return list;
}
You can use the String.split method.
String line = // the line you read here
// Split on commas but only make three elements
String[] elements = line.split(',', 3);
// The first belongs to names
names[linecount] = elements[0];
// The second belongs to mascot
mascot[linecount] = elements[1];
// And the last belongs to aliases
aliases[linecount] = elements[2];
Try looking into the Pattern/Matcher stuff -- you need to come up with an appropriate regex.
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Something like this might do it:
static final Pattern pattern = Pattern.compile("([^,]*),([^,]*),(*$)");
MatchResult result = pattern.matcher(line).toMatchResult();
if (result.groupCount() == 3) {
// Found the groups
name = result.group(0);
// etc..
} else {
// failed to match line
}
Basically what you want to do is split each line into an array as you read it in, and then parse the data line by line. Something like this (pseudocode):
Scanner inputFile = new Scanner(datafile);
while(inputFile.hasNextLine()) {
String line = inputFile.nextLine();
String[] lineSplit = line.split(",");
//TODO: make sure lineSplit is at least 3 long.
String name = lineSplit[0];
String mascot = lineSplit[1];
//EDIT: Don't just get the last element, get everything after the first two.
// You can do this buy just getting the substring of the length of those two strings
// + 2 to account for commas.
//String alias = lineSplit[lineSplit.length() - 1];
String alias = line.substring(name.length() + mascot.length() + 2);
//If you need to do trimming on the strings to remove extra whitespace, do that here:
name = name.trim();
mascot = mascot.trim();
alias = alias.trim();
//TODO: add these into the arrays you need.
}
Hope this helps.

Categories