Storing the input in 3 dimentional arrays - java

I want to store the input for different test cases that want to test with my java program .
below the sample input :
1
4 5
2 5 6 8
3 8 5 1 7
Here:
1st line- No of test cases.
2nd line-length of arrays M and N.
3rd line- elements of M array.
4th line: elements of N array .
My problem , how to store all these elements at run time and given them as input my java class .

As #Vamsi krishna suggested, the separate lines for the input are not really relevant. So you can enter the values as arguments to the java command line and read them in your main method:
public static void main(String[] args) {
int i = 0;
int numberOfTests = Integer.parseInt(args[i++]);
int mSize = Integer.parseInt(args[i++]);
int nSize = Integer.parseInt(args[i++]);
int[] mValues = new int[mSize];
for(n = 0; n < mSize; n++) {
mValues[n] = Integer.parseInt(args[i++]);
}
int[] nValues = new int[nSize];
for(n = 0; n < mSize; n++) {
nValues[n] = Integer.parseInt(args[i++]);
}
}
Then call your application with:
java MyApp.class 1 4 5 2 5 6 8 3 8 5 1 7
Note: you did not indicate how the number of test cases should be used. If this means multiple groups of m,n arrays can be specified as input an extra iteration is needed and the m,n arrays must be stored somewhere, for example in another array.
If this simple approach is not good enough (it might be too error prone because of the lack of formatting on the input) you could put the input in a file and read it using java.util.Scanner:
public static void main(String[] args) {
File file = new File(args[0]);
Scanner sc = new Scanner(file);
try {
while (sc.hasNextInt()) {
int i = sc.nextInt();
// see logic above but use sc.nextInt() to get the next int value
}
}
finally {
sc.close();
}
}
Call this with:
java MyApp.class C:\input.txt
And put the input in the file C:\input.txt.

/*
* Sharing the code here with . Yes,there will be multiple test cases in
* the input Suggest any better way if you find
*/
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int testcases = Integer.parseInt(br.readLine());
String readinput = "";
int count = 0;
int[][][] array = new int[testcases][3][];
for (int i = 0; i <= array.length; i++) {
readinput = "";
count = 0;
for (int j = 0; j < array[i].length; j++) {
readinput = br.readLine();
count = readinput.split(" ").length;
String[] data = new String[count];
data = readinput.split(" ");
System.out.println(Arrays.toString(data));
for (int k = 0; k < count; k++) {
array[i][j][k] = Integer.parseInt(data[k]);
}
}
}

Related

Reading a string splitting it and assigning values to 2D array in JAVA

I am trying to split a string with " "(space) and assigning each value on row to each respective array.
The input file contains:
4
2 2
1 3
4 7
3 4
The first line of the file has a single integer value N which is number of jobs.
The next N lines will represent a job, each with 2 values.
How do I start reading from second line from a Input file?
I want to split from Second line and assign it to 2D array. So if (2,2) is there on second line, then 2 should be assigned to array[0][0] and the other 2 to array[0][1]. For next line 1 should be assigned to array[1][0] and 3 should be assigned to array[1][1].
int num = scan.nextInt(); // taking number of jobs from first line
int[][] array = new int[num][num];
while (scan.hasNext()) //It reads till file has next line
{
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
}
Had done till here, couldn't figure out further.
int[][] array = new int[num][num];
Wrong dimensions of the array, for N = 4 you create array of 4 * 4, not 4 * 2.
Since the number of columns is fixed in your case, you should create array as new int[num][2] and update reading of the data accordingly.
String str = scan.nextLine();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
array[i][j] = scan.nextInt();
}
}
Reading a line just to skip it may be redundant if you use Scanner to read the integer numbers using nextInt. So actually you do NOT need to read the data line by line, then split each line into String parts, and convert each part into a number because Scanner class takes care of it.
Also, the innermost loop tries to read N numbers per array row, while it's better to refer actual length of the array in the row.
Thus, it should be ok just to read the data according to the task using Scanner only:
int num = scan.nextInt(); // taking number of jobs from the first line
// preparing array of N rows and 2 columns
int[][] array = new int[num][2];
for (int i = 0; i < num; i++) {
for (int j = 0; j < array[i].length; j++) { // reading 2 ints per row
array[i][j] = scan.nextInt();
}
}
You can make it a lot easier by just ignoring the first line and letting Java do the hard work:
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.Arrays;
public class FileToArray {
public static void main(String[] args) {
try {
try (Stream<String> stream = Files.lines(Path.of("arr.txt"))) {
String[][] nums = stream.skip(1).map(s -> s.split(" ")).toArray(String[][]::new);
System.out.println(Arrays.deepToString(nums));
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}

I'm trying to count the percentage of every letter in a document by using a scanner, but I can't figure out how to correctly compute and display it

First I uploaded the file I'm using, the constitution. Then, I created two arrays, one for the length of the alphabet, the second to compute the frequency. I created a while loop to read every line in the document and count the frequency of every letter, I just can't figure out how to compute each as a percentage of each letter because after I'm going to put it into a bar chart.
int [ ]lettersLabels = new int [26];
int [ ]lettersFrequency = new int [26];
String line;
//initialize arrays
letterLabels = 0;
lettersFrequency = 0;
Scanner sc = new Scanner(constitution);
while(sc.hasNextLine())
{
line = sc.nextLine();
line = sc.toLowerCase();
char[] characters = line.toCharArray();
for (int i = 0; i< characters.length ; i++)
{
if((characters[i] >='a') && (characters[i]<='z'))
{
lettersLabels[characters[i] -'a' ]++;
}
}
}
for (int i = 0; i < 26; i++)
{
lettersFrequency = 'a' + [characters[i] -'a' ]++;
lettersFrequency = lettersFrequency / 100;
System.out.println(lettersFrequency);
}
Percentage is ratio * 100 (1/2 = 0.5 = (0.5 * 100)% = 50%), and the ratio here is lettersLabels[i] / totalLetters. So, in order to find the percentage, you just use lettersFrequency[i] = (double) lettersLabels[i] / (double) totalLetters * 100;. So, you might need a variable totalLetters at the beginning to count the number of letters.
You have a mistake in your code, which is initializing arrays with 0. You have already initialized the arrays with int[] arr = new int[26];, so you don't need those two lines, which will give an error since initializing arrays with an int is the wrong type. Also, when setting some part of lettersFrequency to something, you need to specify the index, like lettersFrequency[i], and instead of using characters when its out of scope to get the characters, so instead you have to use the letterLabels array.
Hope this works!
Here I've fix some of the errors with description see the code comments for explanation :
int [ ]lettersLabels = new int [26];
int [ ]lettersFrequency = new int [26];
String line;
int totalLetter =0; // needed to calculate %
// No need to initialize, it's already initialized with 0 values.
// remove those lines.
//initialize arrays
// letterLabels = 0;
// lettersFrequency = 0;
Scanner sc = new Scanner(constitution);
while(sc.hasNextLine())
{
line = sc.nextLine();
// need to lower case the current line
line = line.toLowerCase();
char[] characters = line.toCharArray();
for (int i = 0; i< characters.length ; i++)
{
if((characters[i] >='a') && (characters[i]<='z'))
{
// lets count the letter frequency.
totalLetter++;
lettersFrequency[characters[i] -'a' ]++;
}
}
}
// get rid of divide by zero exception
if(totalLetter ==0) totalLetter =1;
for (int i = 0; i < 26; i++)
{
char ch = 'a'+i;
// let's count the parentage of each letter.
double parcentage = (lettersFrequency[i]*100.00)/totalLetter;
System.out.println("parcentage of "+ ch+ " is: " +lettersFrequency +"%");
}

Array rotation TLE (Time Limit Exceeded)

I am really confused why my java code is not working it is giving TLE on Code Monks on Hacker Earth.
Here is the link to the 1
Link to Question
the first question MONK AND ROTATION
import java.util.Scanner;
class TestClass {
static int[] ar=new int[100001];
public static void main(String args[] ){
Scanner in=new Scanner(System.in);
byte t=in.nextByte();
while(t-->0){
int n=in.nextInt();
int k=in.nextInt()%n;
for(int i=0;i<n-k;i++)
ar[i]=in.nextInt();
for(int i=0;i<k;i++)
System.out.print(in.nextInt()+" ");
for(int i=0;i<n-k;i++)
System.out.print(ar[i]+" ");
System.out.println();
}
}
}
I don't know why is it giving TLE I think there is some infinite loop going.
the question at the site is-
Monk and Rotation
Monk loves to perform different operations on arrays, and so being the principal of HackerEarth School, he assigned a task to his new student Mishki. Mishki will be provided with an integer array A of size N and an integer K , where she needs to rotate the array in the right direction by K steps and then print the resultant array. As she is new to the school, please help her to complete the task.
Input:
The first line will consists of one integer T denoting the number of test cases.
For each test case:
The first line consists of two integers N and K, N being the number of elements in the array and K denotes the number of steps of rotation.
The next line consists of N space separated integers , denoting the elements of the array A.
Output:
Print the required array.
Constraints:
1<=T<=20
1<=N<=10^5
0<=K<=10^6
0<=A[i]<=10^6
Sample Input
1
5 2
1 2 3 4 5
Sample Output
4 5 1 2 3
Explanation
Here T is 1, which means one test case.
denoting the number of elements in the array and , denoting the number of steps of rotations.
The initial array is:
In first rotation, 5 will come in the first position and all other elements will move to one position ahead from their current position. Now, the resultant array will be
In second rotation, 4 will come in the first position and all other elements will move to one position ahead from their current position. Now, the resultant array will be
Time Limit: 1.0 sec(s) for each input file
Memory Limit: 256 MB
Source Limit: 1024 KB
I'm not sure about the correctness of your solution, but try to use StreamTokenizer or BufferedReader instead of Scanner. Scanner is too slow and may result in TLE when you need to read a lot of data.
Reduce the number of reads and writes from/to System.in and System.out.
Look at the following solution
Scanner scanner = new Scanner(System.in);
int noOfTestCases = scanner.nextInt();
for (int i = 0; i < noOfTestCases; i++) {
int arraySize = scanner.nextInt();
int noOfRotations = scanner.nextInt();
noOfRotations = noOfRotations % arraySize;
scanner.nextLine();
String inputString = scanner.nextLine();
String[] inputStringArray = inputString.split(" ");
StringBuffer sb = new StringBuffer();
for (int j = 0; j < arraySize; j++) {
sb.append(inputStringArray[(arraySize + j - noOfRotations) % arraySize] + " ");
}
System.out.print(sb);
System.out.println("");
}
import java.util.*;
public class temp {
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-->0){
int n = sc.nextInt();
int k = sc.nextInt();
int p = 0;
int ar[] = new int[n];
for(int i=0;i<n;i++){
ar[i] = sc.nextInt();
}
k %= n;
for(int i=0;i<n;i++){
p = ar[(i+(n-k))%n];
System.out.print(p+" ");
}
System.out.println();
}
}
}
Though I have not used a big sized array in the starting, this code is working fine for all test cases.
Try this one.
Think from a different perspective. Instead of splitting the string and converting it into an array and applying the iterative logic, we can apply a different logic.
The trick is you just need to find the position of the input string where we have to split only once.
By that I mean,
input=>
6 2       //4 is the length of numbers and 2 is the index of rotation
1 2 3 4 5 6     //array (take input as a string using buffered reader)
Here, we just need to split the array string at the 2nd last space i.e. 4th space. So the output can be achieved by just splitting the string once-
5 6 1 2 3 4
first split- 5 6 + space + second split- 1 2 3 4
This logic worked for me and all the test cases passed.
Also don't forget to cover the corner case scenario when array input string is just one number.
Code Snippet-
int count=0;
for(int k=0; k<arr.length(); k++) {
if(arr.charAt(k)==' ')
count++;
if(count==size-rot) {
System.out.println(arr.substring(k+1,arr.length())
+ " " + arr.substring(0,k));
break;
}
}
Problem is in the System.out.print() call that is inside the for-loop. Thats a fairly heavy call and if called too many times and creates an overhead. This solution works:
//import for Scanner and other utility classes
import java.util.*;
class TestClass {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String input = s.nextLine();
int noOfTests = Integer.parseInt(input);
for (int t = 0; t < noOfTests; t++) {
input = s.nextLine();
String[] str = input.split(" ");
int sizeOfArray = Integer.parseInt(str[0]);
int noOfRotations = Integer.parseInt(str[1]);
String strIntegerArray = s.nextLine();
String[] array = strIntegerArray.split(" ");
printRightRotatedArray(array, noOfRotations, strIntegerArray.length());
}
}
static void printRightRotatedArray(String[] array, int noOfRotations, int lengthOfStr) {
int len = array.length;
int noOfAcutalRotations = noOfRotations % len;
int startingIndex = len - noOfAcutalRotations;
StringBuilder sb = new StringBuilder(lengthOfStr+1);
for (int i = 0; i < len; i++) {
sb.append(array[(startingIndex + i) % len]);
sb.append(" ");
}
System.out.println(sb);
}
}
putting all into string buffer and print at the end worked for me.
class TestClass {
public static void main(String args[] ) throws Exception {
//BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();// output
for(int i=0;i<t;i++){
String [] nk=br.readLine().split(" ");
int n= Integer.parseInt(nk[0]);
int k=Integer.parseInt(nk[1]);
String [] a=br.readLine().split(" ");
int split=n-(k%n);
for (int j = split; j < a.length; j++) {
sb.append(a[j]);
sb.append(' ');
}
for (int j = 0 ; j < split; j++) {
sb.append(a[j]);
sb.append(' ');
}
sb.append("\n");
}
System.out.println(sb);
}
}

Java parsing command line arguments ( args[]) into an int[][] Type

Can somebody please tell me how to parse the following into an int[][] Type. This is the structure of numbers which are typed into the java args "1,2;0,3 3,4;3,4 " (the first 4 numbers should represent a matrix as well as the last 4 numbers; so i need both parsed as a int[][] ) but how can i take this and parse it into an int[][] type ?
First thing would be this i guess :
String[] firstmatrix = args[0].split(";");
String[] rowNumbers = new String[firstmatrix.length];
for(int i=0; i< firstmatrix.length; i++) {
rowNumbers = firstmatrix[i].split(",");
}
but i cant get it to work out -.-
Edit : At first thank you for all your help. But i should have mentioned that exception handling is not necesarry. Also, i am only allowed to use java.lang and java.io
edit 2.0: Thank you all for your help!
public static void main(String[] args) throws IOException {
List<Integer[][]> arrays = new ArrayList<Integer[][]>();
//Considering the k=0 is the show, sum or divide argument
for(int k=1; k< args.length; k++) {
String[] values = args[k].split(";|,");
int x = args[k].split(";").length;
int y = args[k].split(";")[0].split(",").length;
Integer[][] array = new Integer[x][y];
int counter=0;
for (int i=0; i<x; i++) {
for (int j=0; j<y; j++) {
array[i][j] = Integer.parseInt(values[counter]);
counter++;
}
}
//Arrays contains all the 2d array created
arrays.add(array);
}
//Example to Show the result i.e. arg[0] is show
if(args[0].equalsIgnoreCase("show"))
for (Integer[][] integers : arrays) {
for (int i=0; i<integers.length; i++) {
for (int j=0; j<integers[0].length; j++) {
System.out.print(integers[i][j]+" ");
}
System.out.println();
}
System.out.println("******");
}
}
input
show 1,2;3,4 5,6;7,8
output
1 2
3 4
******
5 6
7 8
input for inpt with varible one 3*3 one 2*3 matrix
show 1,23,45;33,5,1;12,33,6 1,4,6;33,77,99
output
1 23 45
33 5 1
12 33 6
******
1 4 6
33 77 99
******
In the program arguments using a space splits it into two different arguments. What would probably be best for you is to change it to the format to:
1,2;0,3;3,4;3,4
Then
String[] firstMatrix = args[0].split(";");
System.out.print(Arrays.toString(firstMatrix));
Produces
[1,2, 0,3, 3,4, 3,4]
And doing
int[][] ints = new int[firstMatrix.length][2];
int[] intsInside;
for (int i = 0; i < firstMatrix.length; i++) {
intsInside = new int[2];
intsInside[0] = Integer.parseInt(firstMatrix[i].split(",")[0]);
intsInside[1] = Integer.parseInt(firstMatrix[i].split(",")[1]);
ints[i] = intsInside;
}
System.out.print("\n" + Arrays.deepToString(ints));
Produces
[[1, 2], [0, 3], [3, 4], [3, 4]]
NOTE: Values 0, 1, and 2 in certain places in the code should be replaced with dynamic values based on array lengths etc.
As you have provided arguments like "1,2;0,3 3,4;3,4", it seems you will have args[0] and args[1] as two-parameter for input but you have only shown args[0] in your example. Below is a modified version of your code which might give you hint for your solution
public static void main(String[] args) {
for (String tmpString : args) {
String[] firstmatrix = tmpString.split(";");
// Assuming that only two elements will be there splitter by `,`.
// If not the case, you have to add additional logic to dynamically get column length
String[][] rowNumbers = new String[firstmatrix.length][2];
for (int i = 0; i < firstmatrix.length; i++) {
rowNumbers[i] = firstmatrix[i].split(",");
}
}
}
You can try something like splitting the input by semicolon first in order to get the rows of the matrix and then split each row by comma in order to get the single values of a row.
The following example does exactly that:
public static void main(String[] args) {
System.out.println("Please enter the matrix values");
System.out.println("(values of a row delimited by comma, rows delimited by semicolon, example: 1,2;3,4 for a 2x2 matrix):\n");
// fire up a scanner and read the next line
try (Scanner sc = new Scanner(System.in)) {
String line = sc.nextLine();
// split the input by semicolon first in order to have the rows separated from each other
String[] rows = line.split(";");
// split the first row in order to get the amount of values for this row (and assume, the remaining rows have this size, too
int columnCount = rows[0].split(",").length;
// create the data structre for the result
int[][] result = new int[rows.length][columnCount];
// then go through all the rows
for (int r = 0; r < rows.length; r++) {
// split them by comma
String[] columns = rows[r].split(",");
// then iterate the column values,
for (int c = 0; c < columns.length; c++) {
// parse them to int, remove all whitespaces and put them into the result
result[r][c] = Integer.parseInt(columns[c].trim());
}
}
// then print the result using a separate static method
print(result);
}
}
The method that prints the matrix takes an int[][] as input and looks like this:
public static void print(int[][] arr) {
for (int r = 0; r < arr.length; r++) {
int[] row = arr[r];
for (int v = 0; v < row.length; v++) {
if (v < row.length - 1)
System.out.print(row[v] + " | ");
else
System.out.print(row[v]);
}
System.out.println();
if (r < arr.length - 1)
System.out.println("—————————————");
}
}
Executing this code and inputting the values 1,1,1,1;2,2,2,2;3,3,3,3;4,4,4,4 results in the output
1 | 1 | 1 | 1
—————————————
2 | 2 | 2 | 2
—————————————
3 | 3 | 3 | 3
—————————————
4 | 4 | 4 | 4
I tried the java8 stream way, with int[][] as result
String s = "1,2;0,3;3,4;3,4";
int[][] arr = Arrays.stream(s.split(";")).
map(ss -> Stream.of(ss.split(","))
.mapToInt(Integer::parseInt)
.toArray())
.toArray(int[][]::new);
With List<List<Integer>>, should be the same effect.
String s = "1,2;0,3;3,4;3,4";
List<List<Integer>> arr = Arrays.stream(s.split(";")).
map(ss -> Stream.of(ss.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList()))
.collect(Collectors.toList());
System.out.println(arr);
Hope it helps

Moving Average Using User-Input Array

I need to write a program that calculates a moving average by a user inputted array. The first element of the array is the window size, and the input is terminated by a 0. The output values are printed with two digits after the decimal point.
Example input: 3 2 4 7 7 8 11 12 0
Corresponding Output: 4.33 6.00 7.33 8.67 10.33
(4.33 is average of 2,4,7 and 6 is average of 4,7,7 etc.)
Here's my code so far:
package movingaverage;
import java.util.Scanner;
public class MovingAverage {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
avg[0] = sum / 5;
int j = 1;
for (int i = 5; i < arr.length; i++) {
sum = sum + arr[i] - arr[i - 5];
avg[j++] = sum / 5;
}
}
}
I think I have the loop right, but I'm not sure how to get the array to end at 0.
This is a possible solution.
public class Test
{
private static final Scanner SCANNER;
static {
SCANNER = new Scanner(System.in);
}
public static final void main(final String... args) {
final String[] numbers = SCANNER.nextLine().trim().split(" ");
final int consideredElements = Integer.parseInt(numbers[0]);
float sum = 0;
int value = 0;
for (int i = 1; i < numbers.length; i++) {
sum = 0;
for (int k = 0; k < consideredElements; k++) {
value = Integer.parseInt(numbers[i + k]);
if (value == 0) {
return;
}
sum += value;
}
System.out.println(new BigDecimal(sum / consideredElements).setScale(2, RoundingMode.HALF_EVEN));
}
}
}
First, you are using 5 in a couple of places in your program, I see no justification for that. Could it be that your expectation of user input lead you to put 5 where the number you really should use, depends on user input? Maybe you should use the window size instead? I’m guessing a bit here.
Next, as #lppEdd pointed out, you are not reading the numbers from your input — only the window size.
Next, you are declaring your array of size n, which I believe was your window size, not your array size. I believe the real solution to this problem is using better and more explanatory variable names.
Your code does not compile since you have not declared the array avg that you try to store your moving average into.
Fifth, when you want your average as a double, you need to convert to double before dividing (this is a classic pitfall that has already generated many questions on Stack Overflow).
I hope this gets you a couple of steps further.

Categories

Resources