So i've been trying to take a txt file which has input like this for eg -
abcddhdj
efghdd
ijkl
to get this -
j
d
hd
dd
dhl
cgk
bfj
aei
i have tried to do this using 2d char array which gave nullexception and arrayoutofbound error and didnt work mostly,then tried string array , arraylist of arraylist of char , and lastly i have been trying using arraylsit of string
here is the closest i got to my solution after lot of searching by using string[] -
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt")); // PUT YOUR FILE LOCATION HERE
int k=0,i,j=0,x;
String line[] = new String[10] ; //SET THE APPROXIMATE NUMBER OF ROWS
while((line[k] = br.readLine()) !=null)
{System.out.println(line[k]); //print to check input - verified
k++;
}
for(x=0;x<k;x++)
{if(j<line[x].length())
{j=line[x].length()-1;} //this part not working in above loop
}
System.out.println(j); // verified but not working inside previous loop for some reason
System.out.println(k);
for(x=j-1;x>=0;x++) //without this loop,its perfect, but with it gives indexoutofbound error , doesnt run at x=j
{ for(i=0;i<k;i++)
{ System.out.print(line[i].charAt(x));
}
System.out.println();
}
}
here is one output
run:
abcd
efgh
ijkl
4 //should have come as 3 since i did length-1
3
chl //notice the d missing , every char of first row shifted,just why
bgk //in outofbound error , it only prints d at the end, need explanation
afj
ei
BUILD SUCCESSFUL (total time: 0 seconds)
if i add a space after abcd it gives indexoutofbound and no output after k
at end i used another method which adds spaces to make all length equal
yet still the output was wrong, plus there is something wrong with this way of thinking , there should be better method
so i tried arraylist , this is giving me more problems again
trying to work this out by any method understandable.
This ought to do the trick:
The key here is that I pad all the line arrays with empty chars so that each character array is the same length as the longest line.
public static void main(String[] args)
{
try (BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt")))
{
String line;
List<List<Character>> lines = new ArrayList<>();
int longestLine = 0;
while((line = br.readLine()) !=null)
{
line = line.trim();
if (line.length() > 0)
{
List<Character> currList = new ArrayList<>();
for (char c : line.toCharArray())
{
currList.add(c);
}
if (currList.size() > longestLine)
{
longestLine = currList.size();
}
lines.add(currList);
}
}
// pad all lists to be the same as the longest
for (List<Character> currList : lines)
{
while (currList.size() < longestLine)
{
currList.add(Character.MIN_VALUE);
}
}
// go through each list backwards
for (int i = longestLine - 1; i >= 0; i-- )
{
for (List<Character> currList : lines)
{
System.out.print(currList.get(i));
}
System.out.println();
}
}
catch (Throwable t)
{
t.printStackTrace();
}
}
Example Input:
abcd
efgh
ijkl
g
Example Output:
dhl
cgk
bfj
aeig
Assuming input is read into the arraylist
ArrayList<String> inputList = new ArrayList<String>();
inputList.add("abcddhdj");
inputList.add("efghdd");
inputList.add("ijkl");
int maxSize = 0;
for (String input : inputList) {
if (input.length() > maxSize) {
maxSize = input.length();
}
}
String outputList[] = new String[maxSize];
for (int i = 0; i < maxSize; i++) {
String output = "";
for (String input : inputList) {
if(i<input.length())
output=output+input.charAt(i);
}
outputList[maxSize-(i+1)]=output;
}
Store all to direct 2d array and transpose in printing loop
final char[][] matrix = Files.lines(Paths.get(fileName)).map(String::toCharArray).toArray(char[][]::new);
final int width = Arrays.stream(matrix).mapToInt(a -> a.length).max().getAsInt();
for (int i = 0; i < width; ++i ) {
final int idx = width-i-1;
String s = Arrays.stream(matrix).map(a -> a.length > idx ? String.valueOf(a[idx]) : " ").collect(Collectors.joining());
System.out.println(s);
}
Related
I am reading multiple lines from the command line looking like this:
10 12
71293781758123 72784
1 12345677654321
Then I calculate stuff with the data of each line and output exactly the same amount of lines.
Unfortunately, I never get more than one line output in the end, namely the result of the last one.
The input function looks like that:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
String line = input.nextLine();
String[] lines = line.split(" ");
System.out.println(fct(lines[0], lines[1]));
}
input.close();
}
fct outputs a String.
Is there something weird happening I am not aware of?
Edit: I have added fct,since this could also be the problem:
public static String fct(String stringA, String stringB) {
int [] a = new int[stringA.length()];
int [] b = new int[stringB.length()];
for(int i=0; i< stringA.length(); i++) {
a[i] = stringA.charAt(i) - '0';
}
for(int i=0; i< stringB.length(); i++) {
b[i] = stringB.charAt(i) - '0';
}
if(a.length < b.length) {
int[] c = a.clone();
a = b.clone();
b = c.clone();
}
Stack<Integer> s = new Stack<Integer>();
int carry = 0;
int b_ind = b.length -1;
for(int i=a.length-1; i>=0; i--) {
if(b_ind >= 0) {
int diff = a[i] - b[b_ind] - carry;
if(diff < 0) {
carry = 1;
diff = 10 + diff;
} else {
carry = 0;
}
s.push(diff);
} else {
if(carry==0) {
s.push(a[i]);
} else {
s.push(a[i]-carry);
carry = 0;
}
}
b_ind -= 1;
}
String all = "";
while(!s.empty()) {
all = all + s.pop();
}
return all.replaceFirst("^0+(?!$)", "").trim();
}
The output would then be:
2
71293781685339
12345677654320
Being directly on the console on the line after the input finished.
Add one line break after last input line 1 12345677654321. Otherwise program won't read last line till you press enter(return) key.
If you want output on console like this:
10 12
71293781758123 72784
1 12345677654321
98
71293781685339
12345677654320
But you are getting this:
10 12
71293781758123 72784
1 1234567765432198
71293781685339
Notice, 98 is getting appended to last input line. And the second output is on the next line. You actually have two outputs.
And the third input has not been read by the program because third input line doesn't end in new line. If you press Enter key here the program will process the third input.
You need to make sure that there is a new line character after last input line before pasting entire input in to console.
Just a sidenote:
I would use java.math.BigInteger in this context (math with big integers).
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
try (var scanner = new Scanner(System.in)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] lines = line.split(" ");
System.out.println(fct(lines[0], lines[1]));
}
}
}
public static String fct(String numberA, String numberB) {
var a = new BigInteger(numberA);
var b = new BigInteger(numberB);
return a.subtract(b).abs().toString();
}
}
The output is supposed to be each word of the array printed backwards with their own lines
public class Main
{
public static void main(String[] args)
{
String [] list = {"every", "nearing", "checking", "food", "stand", "value"};
String reverse = "";
int length = list.length;
for(int j=0; j<list.length; j++)
{
String word = list[j];
for ( int i = length - 1 ; i >= 0 ; i-- )
{
reverse = reverse + word.charAt(i);
}
System.out.println(reverse);
}
}
}
but I keep getting this message
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String
index out of range: 5
at java.lang.String.charAt(String.java:658)
enter code here`at Main.main(Main.java:13)
I cleaned up your code a tiny bit. Don't rely on temporary variables that do not improve the readability of your code. Do try and use for-each loops (they improve readability). Applying those two points, gives us
String[] list = { "every", "nearing", "checking", "food", "stand", "value" };
for (String word : list) {
for (int i = word.length() - 1; i >= 0; i--) {
System.out.print(word.charAt(i));
}
System.out.println();
}
which is based on your original code. Personally, I would prefer to use StringBuilder and its' reverse() method. Like,
for (String word : list) {
System.out.println(new StringBuilder(word).reverse());
}
or in Java 8+, with a map like
Arrays.stream(list).map(s -> new StringBuilder(s).reverse())
.forEachOrdered(System.out::println);
for ( int i = length - 1 ; i >= 0 ; i-- )
The length value you are using above is the length of the list array, not the word.
Remember to empty reverse word after each loop:
System.out.println(reverse);
reverse = "";
if you don't flush you'll get:
yrev
yrevgnirae
yrevgniraegnikceh
yrevgniraegnikcehdoo
yrevgniraegnikcehdoodnat
yrevgniraegnikcehdoodnateula
instead of:
yrev
gnirae
gnikceh
doo
dnat
eula
Verify that the provided arguments are valid in Main.java:13. Check that the provided offset points to a valid index and that the count argument does not point to indices greater than the size of the string itself.
An alternate:
public String[] reverseString(String[] words)
{
String[] reverse=new String[words.length];
for(int i=0;i<words.length;i++)
{
//added for setting element as emptyString instead of null
reverse[i] = "";
for(int j=words[i].length()-1;j>=0;j--)
{
reverse[i]+=words[i].substring(j,j+1);
}
}
System.out.println(Arrays.toString(reverse));
return reverse;
}
In line 11, change
int i = length-1;
to
int i = word.length()-1;
and the exception will go away.
I need to find second to last word in each line (they are divided by space) and find 3 most popular of them and find how many are there? Can you help me in any way?
Input example:
abcd i
asd ffdds abcd ddd ?
abcd ffdds asd ddd i
ddd abcd i
a f g w e a asdfasdasdas fdd i
Answer that I need:
abcd 2
ddd 2
fdd 1
or
2 abcd
2 ddd
1 fdd
This is my code
public class asdf {
public static void main(String args[]) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("input.txt"));
String str;
List < String > list = new ArrayList < String > ();
while ((str = in .readLine()) != null) {
if (str.startsWith(" ") && str.endsWith("i") || str.endsWith("?")) {
list.add(str);
}
}
String[] stringArr = list.toArray(new String[0]); //for backup
String[] stringArrAC = list.toArray(new String[0]);
for (int i = 0; i < stringArrAC.length; i++) {
stringArrAC[i] = stringArrAC[i].substring(63);
}
//String[] stringArrLAST = (new String[0]);
Map<String, Integer> occurrences = new HashMap();
for (String line : stringArrAC) {
String[] words = line.split(" ");
String nextToLastWord = words[words.length - 2];
occurrences.put(nextToLastWord,
occurrences.get(nextToLastWord) == null
? 1
: occurrences.get(nextToLastWord) + 1);
}
occurrences.entrySet().stream()
// Sort the values in descending order
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
// Gets top 3 entries
.limit(3)
// Print them
.forEach(System.out::println);
try {
PrintWriter pr = new PrintWriter("output.txt");
for (int i = 0; i < stringArrAC.length; i++) {
pr.println(stringArrAC[i]);
}
pr.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("No such file exists.");
}
}
Java 8 makes this simpler.
Count the occurrences of the next to last word with a HashMap, then use streams to sort the HashMap in descending order and grab the top three values.
public static void main(String[] args) throws Exception {
List<String> lines = new ArrayList() {
{
add("abcd i");
add("asd ffdds abcd ddd ?");
add("abcd ffdds asd ddd i");
add("ddd abcd i");
add("a f g w e a asdfasdasdas fdd i");
add("123 awef bad");
add("123 awef bad");
add("123 awef bad");
add("oneword");
}
};
Map<String, Integer> occurrences = new HashMap();
for (String line : lines) {
// Skip blank lines
if (line.isEmpty()) {
continue;
}
String[] words = line.split(" ");
// Account for a line that might have only one word
String nextToLastWord = words.length >= 2 ? words[words.length - 2] : words[0];
occurrences.put(nextToLastWord,
occurrences.get(nextToLastWord) == null
? 1
: occurrences.get(nextToLastWord) + 1);
}
occurrences.entrySet().stream()
// Sort the values in descending order
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
// Gets top 3 entries
.limit(3)
// Print them
.forEach(System.out::println);
}
Results:
awef=3
ddd=2
abcd=2
Parse each line with a string tokenizer to get an array of words. For each line, the word you want will be the second to last element in the array. Create a Map to store the word in, along with an associated counter that you'll increment by one each time you encounter the same word. In other words, once the word is in the map, if you find that word again, increment its counter in the map. When you're done, get the key value pairs from the map, find the 3 highest counter values, and their associated words.
Hey guys and gals hope everyones Saturday night is going as swimmingly (preferably more) than mine own.
I'm a java noob so bear with me.
We are told to export the an excel sheet from Open Office into a .txt (Tab Delimited)
It ends up looking like this
1 2 3
4 5 6
7 8 9
10 11 12
Where all values are separated by a tab.. (something I haven't encountered yet and are Integer values)
I can see one option, as i type this as I could capture each line, then string split the line by?? whitespace or /t ... and then assign the values to the respective positions in the [30][10] array...
(which ends up being a .csv and load it into java.
So Job 1 is to populate a 2D array with the files from the tab delimited file.
import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
public class Nitrogen
{
private int elevations[][] = null;
private String filename = "location.txt";
public Nitrogen()
{
int [][]elevations = new int[30][10];
}
public void run()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] +" ");
}
System.out.println("");
}
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
public static void main(String[] args)
{
Nitrogen n = new Nitrogen();
n.run();
}
}
So, this prints out 30 lines of line 1, then a line of 0's on top of 29 lines of line 2, then 2 lines of 0's on top of 28 lines of line 3, You get the point....all moving left to right.
Not quite sure....tis getting late and i might give up for the evening.
Alright!! Here is the solution... persistence pays of thanks for the help everyone
public void populate()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
}
for (int h=0; h < rows; h++){ //This was just to show I had it
for (int g=0; g < columns; g++) { //in there correctly
System.out.print(elevations[h][g] +" ");
}
System.out.println(""); }
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
If you are trying to print out the array, I would suggest the following amendment to your code:
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] + " ");
}
System.out.println("");
}
The above will produce an output such as:
Row1, Row1, Row1
Row2, Row2, Row2
Because it prints out the columns, with a space in between each element, then a new line between the rows.
I know this is a simple assignment for a class, but if you can use Collections for IO, please do so. It makes the code much more generally usable.
If you want to read values from a tab delimited file (in OpenOffice, this is called a {Tab} delimited CSV file in the Save dialog window), the easiest you can do, is split each line according to a tab, like this:
public static ArrayList<ArrayList<Integer>> readFile(String filename) throws IOException {
File file = new File(filename);
BufferedReader br = new BufferedReader(new FileReader(file));
ArrayList<ArrayList<Integer>> list = new ArrayList<>(); // list of lines
String buffer;
while ((buffer = br.readLine()) != null) {
String[] splitted = buffer.split("\t"); // split the lines by tabs
ArrayList<Integer> line = new ArrayList<>();
for (String str : splitted) {
line.add(Integer.parseInt(str)); // cast and add all the integers to a list
}
list.add(line); // add the line to the list of lines
}
return list;
}
We are able to create a list of lines, with each line containing the Integer values from the text file. Now, we need to create a 2D list out of it, so concatenate all the values from every line to the line before.
public static ArrayList<Integer> concatenateAll(ArrayList<ArrayList<Integer>> lines) {
ArrayList<Integer> result = new ArrayList<>(); // create an empty 2D list for all the values
for(ArrayList<Integer> line : lines) {
result.addAll(line); // add all the values from every line to the 2D list
}
return result;
}
We can create a 2D list of all the values in the file. To use these two methods, we need to invoke them like this:
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> lineList = null;
try {
lineList = readFile("table.csv");
} catch (IOException ioe) {
ioe.printStackTrace();
}
ArrayList<Integer> allLines = concatenateAll(lineList);
System.out.println(allLines);
}
If we absolutely need an array, we can add this at the end:
Integer[] linesArray = new Integer[allLines.size()];
allLines.toArray(linesArray);
System.out.println(Arrays.toString(linesArray));
For non-class assignments, here's a one liner:
private string[][] Deserialize(string data)
{
return ( from string line
in data.Split('\r\n')
select line.Split(' ')
).ToArray();
}
I want to read in a grid of numbers (n*n) from a file and copy them into a multidimensional array, one int at a time. I have the code to read in the file and print it out, but dont know how to take each int. I think i need to splitstring method and a blank delimiter "" in order to take every charcter, but after that im not sure. I would also like to change blank characters to 0, but that can wait!
This is what i have got so far, although it doesnt work.
while (count <81 && (s = br.readLine()) != null)
{
count++;
String[] splitStr = s.split("");
String first = splitStr[number];
System.out.println(s);
number++;
}
fr.close();
}
A sample file is like this(the spaces are needed):
26 84
897 426
4 7
492
4 5
158
6 5
325 169
95 31
Basically i know how to read in the file and print it out, but dont know how to take the data from the reader and put it in a multidimensional array.
I have just tried this, but it says 'cannot covernt from String[] to String'
while (count <81 && (s = br.readLine()) != null)
{
for (int i = 0; i<9; i++){
for (int j = 0; j<9; j++)
grid[i][j] = s.split("");
}
Based on your file this is how I would do it:
Lint<int[]> ret = new ArrayList<int[]>();
Scanner fIn = new Scanner(new File("pathToFile"));
while (fIn.hasNextLine()) {
// read a line, and turn it into the characters
String[] oneLine = fIn.nextLine().split("");
int[] intLine = new int[oneLine.length()];
// we turn the characters into ints
for(int i =0; i < intLine.length; i++){
if (oneLine[i].trim().equals(""))
intLine[i] = 0;
else
intLine[i] = Integer.parseInt(oneLine[i].trim());
}
// and then add the int[] to our output
ret.add(intLine):
}
At the end of this code, you will have a list of int[] which can be easily turned into an int[][].
private static int[][] readMatrix(BufferedReader br) throws IOException {
List<int[]> rows = new ArrayList<int[]>();
for (String s = br.readLine(); s != null; s = br.readLine()) {
String items[] = s.split(" ");
int[] row = new int[items.length];
for (int i = 0; i < items.length; ++i) {
row[i] = Integer.parseInt(items[i]);
}
rows.add(row);
}
return rows.toArray(new int[rows.size()][]);
}
EDIT: You just updated your post to include a sample input file, so the following won't work as-is for your case. However, the principle is the same -- tokenize the line you read based on whatever delimiter you want (spaces in your case) then add each token to the columns of a row.
You didn't include a sample input file, so I'll make a few basic assumptions.
Assuming that the first line of your input file is "n", and the remainder is the n x n integers you want to read, you need to do something like the following:
public static int[][] parseInput(final String fileName) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
int n = Integer.parseInt(reader.readLine());
int[][] result = new int[n][n];
String line;
int i = 0;
while ((line = reader.readLine()) != null) {
String[] tokens = line.split("\\s");
for (int j = 0; j < n; j++) {
result[i][j] = Integer.parseInt(tokens[j]);
}
i++;
}
return result;
}
In this case, an example input file would be:
3
1 2 3
4 5 6
7 8 9
which would result in a 3 x 3 array with:
row 1 = { 1, 2, 3 }
row 2 = { 4, 5, 6 }
row 3 = { 7, 8, 9 }
If your input file doesn't have "n" as the first line, then you can just wait to initialize your final array until you've counted the tokens on the first line.