I am trying to create an array that reads string tokens from standard input, and places them in an array, and then prints the words out, until it reaches a specific word. For example, let's say I wanted my array to read a series of words until it reached the word "okay" from std in, print out each word, and then terminate before printing out "okay". The length of this array will be unknown, so I am confused on how to do this.
String s = sc.next();
String[] copy = new String[???];
for( int i = 0; i < copy.length; i++ ){
copy[i] = sc.next();
}
Something like:
String s = sc.next();
ArrayList<String> copy = new ArrayList<String>();
while(!s.equals("okay")){
copy.add(s);
s = sc.next();
}
for (String n : copy){
System.out.println(n);
}
If you don't want to use any list at all, then this becomes impossible. This is simply because array size needs to be defined at the time the array object is created.
So with this constraint you can have a large integer and declare an array of that size.
Final int MY_LARGE_CONST = 3000;
...
String[] tokens = new String[MY_LARGE_CONST]...
This is wasteful since it takes more memory and will fail if you have more tokens than the constant.
Alternaely if you are ok with lists and not ok with iterating over that for actual processing, then u can put the tokens in an ArrayList and once they are all collected, call the toArray method on the ArrayList object.
It's my code Without using ArrayList.
import java.util.Scanner;
import java.util.StringTokenizer;
public class Sample {
public static void main(String[] args) {
Scanner sc = new Scanner(System. in );
String line = sc.nextLine();
StringTokenizer st = new StringTokenizer(line);
int len = st.countTokens();
String[] array = new String[len];
for (int idx = 0; idx < len; idx++) {
array[idx] = st.nextToken();
}
for (String str: array) {
System.out.println(str);
}
}
}
Related
How do I create a method that takes a string as an argument, and returns the array whose elements are the words in the string.
This is what I have came up with so far:
// split takes some string as the argument, and returns the array
// whose elements are the words in the string
public static String[] split (String s)
{
// determine the number of words
java.util.Scanner t = new java.util.Scanner (s);
int countWords = 0;
String w;
while (t.hasNext ())
{
w = t.next ();
countWords++;
}
// create appropriate array and store the string’s words in it
// code here
}
As you can see, I can just input each word via Scanner. Now I just have to put all the words of the String into an array as the elements. However, I'm not sure how to proceed.
You can use StringTokenizer in java to devide your string into words:
StringTokenizer st = new StringTokenizer(str, " ");
And your output st whould be an array of words.
Take a look at this Java StringTokenizer tutorial for further information.
Your code whould look like:
StringTokenizer st = new StringTokenizer(s, " ");
int n=st.countTokens();
for(int i=0;i<n;i++) {
words[i]=st.nextToken();// words is your array of words
}
As Maroun Maroun commented, you should use the split(regex) method from Strings, but if you want to do this by yourself:
First, declare the array:
String[] words = new String[50]; // Since you are using an array you have to declare
// a fixed length.
// To avoid this, you can use an ArrayList
// (dynamic array) instead.
Then, you can fill the array inside the while loop:
while (t.hasNext()) {
w = t.next();
words[countWords] = w;
countWords++;
}
And finally return it:
return words;
Note:
The sentences
words[countWords] = w;
countWords++;
can be simplified in
words[countWords++] = w;
As #Maroun Maroun said: use the split function or like #chsdk said use StringTokenizer.
If you want to use scanner:
public static String[] split(String s)
{
Scanner sc = new Scanner(s);
ArrayList<String> l = new ArrayList<String>();
while(sc.hasNext())
{
l.add(sc.next());
}
String[] returnValue = new String[l.size()];
for(int i = 0; i < returnValue.length; ++i)
{
returnValue[i] = l.get(i);
}
return returnValue;
}
The user is allowed to play with an array of strings. They can add strings to the array, remove strings from the array, search for strings in the array, and eventually they will be able to sort the array. The sorting is what is messing me up. I've tried a few different approaches. The first approach was to convert the array into an ArrayList and use Collections to sort the ArrayList, which would be converted back into the static class array. It doesn't work. The second approach I tried was to iterate through the array and try to sort only the strings added by the user instead of everything in the array (since there are some null values in the array). Perhaps I should iterate through the array and then store the non-null values into a new array that I can then sort? But what if I want to add more strings after sorting the new array? That's why I stopped with the second solution. The third attempt was to use Arrays.sort() on my array but for some reason it does not work.
Here is the exception:
Exception in thread "main" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at testingSearch.sortArray(testingSearch.java:93)
at testingSearch.main(testingSearch.java:42)
Here is my code:
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class testingSearch {
static String[] strArray;
static {
strArray = new String[5];
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(true){
System.out.println("1. Add string to the string array.");
System.out.println("2. Remove string from the string array.");
System.out.println("3. Display strings in string array.");
System.out.println("4. Search the string array for a string.");
System.out.println("5. Sort the strings in the string array.");
int userChoice = 0;
userChoice = input.nextInt();
switch(userChoice) {
case 1:
addString();
break;
case 2:
removeString();
break;
case 3:
displayStrings();
break;
case 4:
searchArray();
break;
case 5:
sortArray();
break;
}
}
}
public static void addString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to add?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.add(userInput);
strArray = stringList.toArray(strArray);
}
public static void removeString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to remove?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.remove(userInput);
strArray = stringList.toArray(strArray);
}
public static void displayStrings(){
for (String s: strArray){
if (!(s == null)){
System.out.println(s);
}
}
}
public static void searchArray(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to search the array for?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
if (stringList.contains(userInput)){
System.out.println("The string array contains that string!");
}
else {
System.out.println("The string array does not contain that string...");
}
}
public static void sortArray(){
/*ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);*/
/*for (String s: strArray) {
if (!(s == null)){
Arrays.sort(strArray);
}
}*/
List<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);
//Arrays.sort(strArray);
}
}
The reason you're getting NullPointerExceptions can be explained by the javadoc for Arrays#sort() (emphasis mine):
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the Comparable interface.
Because Arrays.sort() expects Comparable elements and not null values, you end up with a NullPointerException when the method tries to call compareTo().
The fix-this-now way of solving this would be to simply make sure all null elements in your array are replaced with something non-null, such as "". So loop through your array at creation and after removing a String and set null elements to "". However, this solution probably wouldn't perform too well for your code, as it requires another loop after every String is removed, which could grow onerous. At least it won't require you to create a bunch of objects, due to the magic of the String pool, so it's a bit better than what you might do with a different object.
A better solution would be to simply use ArrayList<String> instead of a raw array; after all, you're already using one to manage addString() and removeString(), so you would have less converting from array to ArrayList and back to do. In addition, you wouldn't need to worry about NPEs when sorting (at least for your use case; adding null to a Collection would still result in NPEs when sorting).
You can also just use a raw array, but managing that would get kind of annoying, so I wouldn't recommend that. If you do it right you won't have to worry about NPEs though.
No problem! Here you go:
1. Create a new array
2. Insert items to that array, in the right order
public class sorter {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
String[] newArray = new String[array.length];
int index = 0;
for(int m = 0 ; m < newArray.length; m++){
String leastString = null;
int i = 0;
for(i = 0; i < array.length; i++){
if(leastString==null&&array[i]!=null){
leastString = array[i];
break;
}
}
for(int j = i+1; j < newArray.length; j++){
if(array[j]!=null){
if(array[j].compareTo(array[i])<0){
leastString = array[j];
i = j;
}
}
}
if(i==newArray.length)break;
newArray[m] = leastString;
array[i] = null;
}
for(String s : newArray){
System.out.println(s);
}
}
}
This prints:
:)
BYE
HI
SUP
null
EDIT: Another very simple way to solve this in a very effiecient manner, is to use ArrayList:
public class AClass {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
ArrayList<String> newArray = new ArrayList<String>();
for(String s : array){
if(s!=null){
newArray.add(s);
}
}
Collections.sort(newArray);
String[] retval = new String[newArray.size()];
retval = newArray.toArray(retval);
for(String s : retval){
System.out.println(s);
}
}
}
I guess the simple way of doing things really would be:
static String[] strArray;
static {
strArray = new String[5];
for(int i = 0, i < strArray.length; i++)
{
strArray[i] = "";
}
}
And then just call
Arrays.sort(strArray);
When you want to sort it. If that doesn't work, although I think it should; your initial approach would have been the following:
List<String> stringList = new ArrayList<String>();
for(int i = 0; i < strArray.length; i++)
{
stringList.add(strArray[i]);
}
Collections.sort(stringList);
strArray = stringList.toArray(new String[stringList.size()]);
Although it clearly doesn't seem very memory-friendly.
I'm cating a file using the cat text-file | Java my-program on my terminal
the result when I print the lines after i store it into a array results in null
can someone explain why?
Scanner scan2 = new Scanner(System.in);
Scanner scan = new Scanner(System.in);//create new scanner object
int index = 0;//create index to increment through array
while(scan.hasNextLine()){//while looop to execute if file has length
String line = scan.nextLine();//store line into string input
count++;
}
if(count < BUFSIZE){
stringArray = new String[count];
}
else{
stringArray = new String[BUFSIZE];
}
while(scan2.hasNextLine()){
String line2 = scan2.nextLine();
if(index > stringArray.length-1)
{
stringArray = expandArray(stringArray,BUFSIZE);//call method to increase array length
}
stringArray[index] = line2;//store line into array at given index
index++;//increment index
}
/*while(sorted){
sorted = false;
for(int i = 0; i < stringArray.length-1; i++){
if(stringArray[i].compareTo(stringArray[i+1]) > 0){
temp = stringArray[i];
stringArray[i] = stringArray[i+1];
stringArray[i+1] = temp;
sorted = true;
}
}
}*/
for(int i = 0; i < stringArray.length; i++){
System.out.println(stringArray[i]);
}
}
}
private static String [] expandArray(String [] array, int extend){
String newArray [] = new String[array.length+extend];//create new array with given array and int as length to extend
//for loop to copy data from old array into new created array
for( int i = 0; i < array.length; i++){
newArray[i] = array[i];
}
return newArray;//return newly created array
}
}
the program bubble sorts the array of strings. If I read in the file through Scanner file its fine, but why I cat it doesn't. The expand array method is to dynamically expand the array every-time it reaches max capacity. Thank you
The following is wrong:
Scanner scan2 = new Scanner(System.in);
Scanner scan = new Scanner(System.in);//create new scanner object
Basically, each scanner grabs the System.in stream, but streams can only be read once. You should change your code to use only one scanner, and then only use it once.
When you wrote the program to use a file, the Scanner would actually open two streams to the file so that it can be read twice, but this won't work when all you have is one stream.
EDIT:
Here is a version where you use only one Scanner (and thus one stream) :
Scanner scan = new Scanner(System.in);//create new scanner object
int count = 0;
stringArray = new String[BUFSIZE];
while (scan.hasNextLine()){//while looop to execute if file has length
String line = scan.nextLine();//store line into string input
if (count >= stringArray.length) {
//call method to double array length
stringArray = expandArray(stringArray, stringArray.length);
}
stringArray[count] = line;
count++;
}
// Shrink array to required size
String[] temp = stringArray;
stringArray = new String[count];
System.arraycopy(temp, 0, stringArray, 0, count);
Please note I didn't test it, but this is conceptually how you could do it.
The other alternative is to use an ArrayList<String> which will automatically expand and shrink.
Scanner scan = new Scanner(System.in);
List<String> list = new LinkedList<>();
while(scan.hasNext()) list.add(scan.next());
scan.close();
Collections.sort(list);
for(String line : list) System.out.println(line);
lol
UPDATE #JBert:
System.out.println(StringUtils.join(Ordering.<String>natural().sortedCopy(IOUtils.readLines(System.in)), "\r\n"));
looool
In this code
while(scan2.hasNextLine()){
String line2 = scan2.nextLine();
if(index > stringArray.length-1)
you are doing something if index is greater than the length of the array, but no doing anything otherwise.
Is this correct method to sort ArrayList?
The problem is that the list is not sorted.
out = new StringTokenizer(input.toString());
n = (out.countTokens());
for (int i = 0; i < n; i++) {
String[] words = { out.nextToken().toString() };
final List<String> wordList = Arrays.asList(words);
Collections.sort(wordList);
System.out.println(wordList.toString());
}
Each of your words[] arrays is composed of a single string, obtained from the next token of your StringTokenizer. And you are iterating in exact order of the tokenization. So yes, your output will not be sorted. I presume you wanted to do something like this:
out = new StringTokenizer(input.toString());
int count = out.countTokens():
List<String> wordList = new ArrayList<String>(count);
for(int i = 0; i < count; i++) {
wordList.add(out.nextToken());
}
Collections.sort(wordList);
But, don't use the tokenizer class, its legacy. The following code will serve you better:
List<String> wordList = Arrays.asList(input.split("\\s"));
Collections.sort(wordList);
out.nextToken().toString() give you one string. Your array length should be 1, I presume.
Even if you put this into a loop, you sort at each loop, you have to sort outside the loop.
StringTokenizer out = new StringTokenizer( input.toString());
List<String> wordList = new ArrayList< String >();
while( out.hasMoreTokens()) {
wordList.add( out.nextToken());
}
Collections.sort( wordList );
System.out.println(wordList.toString());
Well I have been stumped as to the best way to do this, I have written the code to read in lines of code from txt files as List. I can then print specific parts or convert this to an array of objects. But, ultimately I would like to have just a 2d int array you can see often in C/C++. I am very green when it comes to java, having only started earlier this week. I have like it up until this point of making dynamic 2d arrays at run time. Can any of you suggest a good way to get to a 2d int array from where i am currently stuck. I was just about to convert it to a char array using 'toChar', then to take the (value#index-48) and store it in its corresponding spot, but that seems pretty ghetto to me.
====updated==========================
eh, thanks for all the replies, but I just figured out how to do it using doubles, so for anyone else, here you go. I would still rather have int, since I have already built my other matrixops classes using this type, but Double shouldn't be an issue i guess.
package uaa.cse215;
import java.io.*;
import java.util.*;
public class ReadMatrix {
private Double[][] A;
private Double[][] B;
private int count;
public int filedir(String matrix) throws Exception{
Double[][] Temp;
String[] arr;
BufferedReader rd = new BufferedReader(new FileReader(matrix));
String s;
List<String> textFile = new ArrayList<String>();
while ((s=rd.readLine())!=null) {
textFile.add(s);
}
String splitarray[] = textFile.get(0).split(" ");//run once to grab # cols
int rows = textFile.size();//number of rows
int cols = splitarray.length;//number of cols
Temp = new Double[rows][cols]; // now can initiate array
for (int i=0; i<rows; i++) {
s = textFile.get(i);
arr = s.split(" ");
for (int j=0; j<cols; j++) {
Temp[i][j] = Double.parseDouble(arr[j]);
}
}
count++;
if (count == 1){
A = Temp;
}
else
B = Temp;
rd.close();
return(1);
}
}
Please note that Java has the char data type which is a 16bit unsigned integer holding a UTF-16 code point. int is in Java always a signed 32 bit integer. So if you want a C like Arrays of chars representing the content of a String, you should use a char[][]
To convert the content of your List<String> into a 2d array you can use the following code:
char[][] twoDarray = new char[textFile.size()];
for(int i = 0; i < textFile.size(); i+)
{
twoDarray[i] = textFile.get(i).toCharArray();
}
The array twoDarray then contains all Strings each as a char array.
This line won't compile
splitarray[j] = textFile.get(i).split(" ");
as splitarray[j] is of type String and split returns an array of Strings
Do the following instead:
for(int row=0;row<textFile.size();row++){
String[] splitarray = textFile.get(row).split(" ");
for(int col=0;col<splitarray.length;col++){
tmp[row][col] = Integer.parse(splitarray[col]);
}
}
if the input matrix dimentions are dynamic or jagged you can use
List<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
to read numbers and than copy it to raw 2d array if you want.
java.util.Scanner has many handy methods for reading "typed" data from input
Here's an example reading file to 2D array
public static int[][] read2DArray(String fileName) throws FileNotFoundException {
Scanner sc = null;
List<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
int columnCount = 0;
int[][] arr = null;
try {
sc = new Scanner(new File(fileName));
while (sc.hasNextLine()) {
// Read line
String line = sc.nextLine();
// Split it
String[] nums = line.split(" ");
if (nums.length > columnCount) {
columnCount = nums.length;
}
// Convert to integers and add to list
list.add(new ArrayList<Integer>());
for (String n : nums) {
list.get(list.size() - 1).add(new Integer(n));
}
}
// Convert list to array
int rowCount = list.size();
arr = new int[rowCount][columnCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < list.get(i).size(); j++) {
arr[i][j] = list.get(i).get(j);
}
}
} finally {
if (sc != null) {
sc.close();
}
}
return arr;
}
Assuming your data file contains ascii-represented numbers that you want parsed into integers:
11 -9 13
12 55 102
1 1 1024
Then you can use the Integer(String s) constructor to parse your string objects.
Also, I suggest splitting each row only once. It won't matter much for small arrays, but the larger your inputs get, the more you'll needlessly recompute the splits.
An (untested) re-writing:
int tmp[][] = new int [rows][cols];
for(int i=0;i<rows;i++){
splitarray = textFile.get(i).split(" ");
for(int j=0;j<cols;j++){
tmp[i][j] = Integer(splitarray[j]);
}
}