I have a problem in my project math.
My project is to write a program that reads a set of elements and its relations. Your input data will be from a text file. (SetRelation).
{1,2,3} {(1,1),(2,2),(3,3),(1,2),(1,3),(2,3)}
I have no problem reading the text file into the program but I'm stuck when I want to try to put the relation into the two dimensional array.
For example: {(1,1),(2,2),(3,3),(1,2),(1,3),(2,3)}
The two dimensional array would have to be like this:
col[0][1][2]
[0] 1 1 1
[1] 1 1
[2] 1
I don't know how to set one into two dimensional array because there are various relations in the text file.
This is my coding.
import javax.swing.*;
import java.util.ArrayList;
import java.io.*;
import java.util.StringTokenizer;
import java.lang.*;
import java.util.*;
public class tests
{
public static int s1[][];
public static int s2[][];
public static int s3[][];
public static int s4[][];
public static int s5[][];
public static int s6[][];
public static int s7[][];
public static int s8[][];
public static int s9[][];
public static int s10[][];
public static void main(String[] args) throws IOException, FileNotFoundException
{
BufferedReader infile = null;
ArrayList arr1 = new ArrayList();
ArrayList arr2 = new ArrayList();
ArrayList arr3 = new ArrayList();
ArrayList arr4 = new ArrayList();
try
{
infile = new BufferedReader (new FileReader ("numbers.txt"));
String indata = null;
while ((indata = infile.readLine())!= null)
{
StringTokenizer st = new StringTokenizer(indata," ");
String set = st.nextToken();
arr1.add(set);
String relation = st.nextToken();
arr2.add(relation);
}
for(int i =0; i < arr2.size(); i++)
{
String r = arr2.get(i).toString();
String result = r.replaceAll("[{}(),; ]", "");
arr3.add(result);
}
for(int i = 0; i < arr3.size(); i++)
{
System.out.println(arr3.get(i).toString());
}
for(int i =0; i < arr1.size(); i++)
{
String s = arr1.get(i).toString();
String result = s.replaceAll("[{}(),; ]", "");
arr4.add(result);
}
int set1 = Integer.parseInt(arr4.get(0).toString());
String ss1 = arr4.get(0).toString();
int a = ss1.length();
s1 = new int[a][a];
int sA[][];
/*for(int row=1;row< a;row++)
{
for(int col=0;col < a;col++)
{
sA = new int[row][col];
int firstNo = Integer.parseInt(arr3.get(row).toString());
int secondNo = Integer.parseInt(arr3.get(col).toString());
sA = new int [firstNo][ secondNo] ;
System.out.print(sA);
}
System.out.println();
}*/
char arrA;
char indOdd=' ',indEven=' ';
char[] cArr = arr3.get(0).toString().toCharArray();
//System.out.println(arr3.get(0).toString().length());
int l = arr3.get(0).toString().length();
int arr10[][] = new int[(l/2)][2];
for(int i=0;i< 2;i++)
{
for(int row = 0; row < (l/2);row++)
{
for(int gh = 0;gh < l;gh++)
{
if(i%2==0)
{
indEven = cArr[gh];
System.out.println(indEven);
arr10[row][i] = indEven;
//System.out.println(arr10[row][i]);
//row++;
}
else
{
indOdd = cArr[gh+1];
System.out.println(indOdd);
arr10[row][i] = indOdd;
//row++;
}
}
}
//arr10 = new int[indOdd][indEven];
//System.out.println(arr10);
}
}
catch (FileNotFoundException fnfe)
{
System.out.println("File not found");
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
infile.close();
}
}
But I'm stuck how to set one into the two dimensional array if the relation is {(a,b),(a,c),(b,a),(b,c),(c,c)}; and {(33,33),(45,45),(67,67),(77,77),(78,78)};
So, you have two problems: parsing the input and setting the array.
To parse the input, think about the format you're given. An opening curly brace, a bunch of ordered pairs, then a closing brace. Think about this pseudocode:
Read in a left curly brace
While the next character is not a right curly brace{
Read in a left parenthesis
Get the first number and put it in a variable!
Read in a comma
Get the second number and put it in a variable!
Read in a right parenthesis
Store your relation in the array!
}
Now your issue is just how to put it in the array. Your relations are practically already indexes into the grid! Note the 0-indexing, so just subtract 1 from both, and set the resulting coordinate equal to 1.
array[first number-1][second number-1]=1;
Just a TIP:
If your set is for example {b,c,e} and want to have somewhere stored relation elemnt <-> index like b<==>0, c<==>1, e<==>2 you can store that elements in List and then use method indexOf().
I mean something like this
List<String> list=new ArrayList<String>();
list.add("b");
list.add("c");
list.add("e");
System.out.println(list.indexOf("c"));//return 1
System.out.println(list.indexOf("e"));//return 2
System.out.println(list.indexOf("b"));//return 0
Now you just have to figure out how to use it to create your array.
Related
so I am currently writing a program that reads in inputs from a file. (I am a beginner in java and don't understand a lot yet, so if you guys can work with me being slow that would be great.)
The file consists of a whole bunch of information regarding country data based on sales of products. The two pieces of the file that I care about are the Country names and the profit numbers. What I'm stuck with is how do I take specific portions of the file and read them into an array and then tally up the total profits? Currently I have read in the header of the file, found the indexes of the Country and profit of the header ( I assumed that finding the index of the headers will translate to finding numbers and names for profit and country later on). The file for example has multiple countries and they repeat multiple times through the file in a random order. Ex
Any help will be useful thanks!
my code right now is:
public static void main(String[]args)throws IOException{
Scanner in = new Scanner(new File("sample-csv-file-for-testing-fixed.csv"));
PrintWriter pw = new PrintWriter(new File("Output.csv"));
// gets first line of file
String firstline = in.nextLine();
firstline.trim();
String data = firstline.replaceAll(" ","");
String[] header = data.split(",") ;
// find index of Country and Profit and store them into variables
String country = "Country";
String profit = "Profit";
int index1 =0 , index2=0;
for(int i = 0;i<header.length;i++){
if(header[i].equals(country)){
index1 = i;
}
}
for(int i = 0;i<header.length;i++){
if(header[i].equals(profit)){
index2 = i;
}
}
System.out.println(index1+" "+index2);
while( in.hasNextLine()){
String line = in.nextLine();
String nextline = line.replaceAll(" ","");
String[] values = nextline.split(",");
for(int i = 0;i< values.length;i++){
System.out.print(values[i]+ " ");
}
}
// Read in line of file into string, separate the string into an array
// keep track of country names
// find a way to get rid of all other numbers except profit
// sum the total profit for each line for each country
// create a output file and print out the table
}
If I don't understand bad, you want something like this:
public static final String COUNTRY_HEADER = "country";
public static final String PROFIT_HEADER = "profit";
public static void main(String[] args) throws URISyntaxException, IOException {
final Scanner in = new Scanner(new File("src/main/resources/group-by.txt"));
final String firstLine = in.nextLine();
final String[] headers = firstLine.split(" ");
int countryIndex = -1;
int profitIndex = -1;
for (int i = 0; i < headers.length; i++) {
if (headers[i].equalsIgnoreCase(COUNTRY_HEADER)) {
countryIndex = i;
} else if (headers[i].equalsIgnoreCase(PROFIT_HEADER)) {
profitIndex = i;
}
}
final Map<String, Long> profitsByCountry = new HashMap<>();
while (in.hasNextLine()) {
final String line = in.nextLine();
final String[] values = line.split(" ");
profitsByCountry.merge(values[countryIndex], Long.valueOf(values[profitIndex]), Long::sum);
}
profitsByCountry.forEach((key, value) -> System.out.printf("Country: %s, Profit: %d%n", key, value));
// Do more stuff
}
Basically, once you have located the index of the columns you are looking for, you just need to go throw the rest of the lines in the file and accumulate their values.
Note: The data example you have offered has one mistake, there is an extra 'blah' in the last line for 'USA'
A File Stream based solution. Finding the index of the header uses the same logic as #Dave and #fjvierm.
public class FileStreaming {
public static void main(String[] args) {
try (BufferedReader br = Files.newBufferedReader(Paths.get("filestreamdata.txt"))) {
int[] idx = getIndex(br.readLine());
Map<String, Integer> result = br.lines()
.map(l -> l.split(" +"))
.map(ss -> new AbstractMap.SimpleEntry<>(ss[idx[0]], Integer.parseInt(ss[idx[1]])))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey,
AbstractMap.SimpleEntry::getValue,
Integer::sum));
result.forEach((key, value) -> System.out.printf("%s %d\n", key, value));
} catch (IOException e) {
e.printStackTrace();
}
}
private static int[] getIndex(String line) {
String[] splits = line.split(" +");
int[] result = new int[2];
for (int i = 0; i < splits.length; i++) {
if (splits[i].equals("country")) {
result[0] = i;
}
if (splits[i].equals("profit")) {
result[1] = i;
}
}
return result;
}
}
The below code might help.
It assumes: the header is always the first line; the header record begins with "Segment"; and the profit values are always in the same field position as the “Profit” header.
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import java.util.*;
import java.util.stream.*;
public class SumTheProfit {
public static void main(String[] args) throws IOException {
String fileName = "test.csv";
String firstColumnHeader = "Segment";
String profitColumnHeader = "Profit";
// put header record into an array
Path filePath = Paths.get(fileName);
String[] firstLine = Files.lines(filePath)
.map(s -> s.replaceAll(" ", ""))
.map(s -> s.split(","))
.findFirst()
.get();
// get the index of "Profit" from the header
int profitIndex = java.util.Arrays.asList(firstLine).indexOf(profitColumnHeader);
List<String> list = new ArrayList<>();
// filter out header record & collect each profit (index 5) into a list
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
list = stream
.filter(line -> !line.startsWith(firstColumnHeader))
.map(line -> line.split("\\s*(,|\\s)\\s*")[profitIndex])
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
//sum each profit value in the list
Integer sum = list.stream().mapToInt(num -> Integer.parseInt(num)).sum();
System.out.println(sum);
}
}
This takes a declarative approach using the Java Streams API, as that's easier to read in comparison to an imperative for loop approach that hides application logic inside boilerplate code.
Currently I have a method that asks user for an input string but only outputs the first 16 characters! The method is supposed to take in any length of string then output the characters in 4x4 blocks after it does the following: first row remains the same. Shift the second row one position to the left, then shifts the third row two positions to the left. Finally, shift the fourth row three positions to the left. As of now it will only output the first 4x4 block
Also I am not sure how I can change the method so it doesnt ask for user input
I would like it to use a given string like:
String text = shiftRows("WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO");
"WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO" is the given encrypted string I would like to use. but without asking for user input..I keep getting errors and incorrect outputs..please show how I might fix this
code I am using:
public class shiftRows {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String[] input= new String[4];
String[] output= new String[4];
System.out.println("Enter a String");
String inputStr = sc.next();
for (int i = 0, n = 0; i < 4; i++, n+=4) {
input[i] = inputStr.substring(0+n, 4+n);
}
// -
output[0] = input[0];
for(int i=1; i<4; i++)
{
output[i] = Shift(input[i],i);
}
for(int i=0; i<4; i++)
{
System.out.println(output[i]);
}
}
public static String Shift(String str, int shiftNum)
{
char[] out = new char[4];
if(shiftNum==1)
{
out[0]=str.charAt(1);
out[1]=str.charAt(2);
out[2]=str.charAt(3);
out[3]=str.charAt(0);
}
if(shiftNum==2)
{
out[0]=str.charAt(2);
out[1]=str.charAt(3);
out[2]=str.charAt(0);
out[3]=str.charAt(1);
}
if(shiftNum==3)
{
out[0]=str.charAt(3);
out[1]=str.charAt(0);
out[2]=str.charAt(1);
out[3]=str.charAt(2);
}
return new String(out);
}
}
Here's a good way to do it :
import java.util.Scanner;
public class shiftRows {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String inputStr = "WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO";
for (int i = 0 ; i < inputStr.length() ; i++){
System.out.print(inputStr.charAt(i));
if ((i + 1)%4 == 0) System.out.println();
}
}
}
If you want to stock it into a String, just concatenate at each loop and add a "\n" each time the if test is valid.
So I have a text file containing ints, doubles, strings that I need to read into a 2D array. there Array should have 6 columns but the rows are not known until you read the entire file. I'm guessing it is some 700 rows This is what I have so far. If I eliminate the array it prints fine but with the array I keep getting errors.
I have searched many questions like this but they usually only work with ints/doubles. Also please don't recommend arrayList as that has not been taught in our course.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class TitanicApp {
public static void main(String[] args) throws FileNotFoundException {
String[][] array=null;
int i=0, j=0;
String fileLine;
String s;
Scanner scannerIn=null;
BufferedReader inputStream=null;
try{
inputStream = new BufferedReader(new FileReader("titanic.txt"));
scannerIn = new Scanner(inputStream);
while ((fileLine = inputStream.readLine()) != null){
for (j=0;j<6;j++){
array [i][j]=scannerIn.next();
System.out.println(array[i][j]);
i++;
}
}
}
catch (IOException ex){
ex.printStackTrace();
}
}
Sample text in file :
1 1 Allen, Miss. Elisabeth Walton female 29 211.3375
1 1 Allison, Master. Hudson Trevor male 0.9167 151.5500
And the output should be :
[ [1, 1, Allen, Miss. Elisabeth Walton, female, 29, 211.3375]
[1, 1, Allison, Master. Hudson Trevor, male, 0.9167, 151.5500]
]
I have a txt file containing the above info (and more lines) and I need to put it into a 2D array. I had to remove more than half of it since there was a limit.
So you want to do it using array only. You can consider below example as reference -
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TitanicApp {
int size = 10;
int colCount = 6;
String[][] array = null;
public static void main(String[] args) {
TitanicApp app = new TitanicApp();
app.startExec();
}
public void startExec() {
array = new String[size][colCount];
String fileLine;
int i=0;
try
{
BufferedReader inputStream = new BufferedReader(new FileReader("C:/titanic.txt"));
while ((fileLine = inputStream.readLine()) != null) {
addTo2DArray(fileLine.split("\\t"), ++i);
}
inputStream.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
// Now you have the desired array : array;
}
public void addTo2DArray(String[] tmpArray, int minCapacity) {
if((minCapacity > size)) {
size = (size * 3)/2 + 1;
String[][] newArray = new String[size][colCount];
for(int i=0; i<array.length; i++) {
for(int j=0; j<array[i].length; j++) {
newArray[i][j]=array[i][j];
}
}
array = newArray;
}
array[minCapacity-1] = tmpArray;
}
}
Another Solution :
String content = new Scanner(new File("/titanic.txt")).useDelimiter("\\Z").next();
String[] rows = content.split("\n");
String[][] finalArray = new String[rows.length][];
for(int i=0; i<rows.length; i++)
{
finalArray[i] = rows[i].split("\\t");
}
//Your desired array is : finalArray;
From what it looks like, you are incrementing both array locations, (i and j), at the same time. If you want the input to go in sequential order in the array increment j until array.size and then increment i. An example would be a nested for loop.
for(int i = 0; i < array.size; i++){
for(int j = 0; j < array.size; j++){
array[i][j] = scanner.next();
System.out.println(array[i][j]);
}
}
or in your case, stop incrementing the values until i and j get to 6 instead of array.size
I think you need declare a size for your String[][], otherwise you will get a NullPointerException. ArrayLists are the only way to dynamically generate the list as you move on as far as my knowledge goes.
I have two csv both with a primary key, im trying to comapre both keys so that i can combine the related csvs to one with the correct keys, however for now i just wanted to compare what was in collumns one. My mind is a little blank i hope by the code you can sort of figure out the direction im going. im unable to get my arrays to actually take in the strings . Java.lang.arrayindexoutofboundsexception
import java.io.;
import java.util.;
public class UDC {
public void search(String [][] wat, String [][] ud){
}
public static void main (String [] args) throws IOException
{
String [] [] cols = {};
String [] [] cols1={};
int row =0;
int row1 =0;
int j = 0;
/*Scanner s = new Scanner(new File("Watford Update File.csv"));
Scanner c = new Scanner(new File("udc.csv"));
while (s.hasNextLine()){
String line = s.nextLine();
cols =line.split(",");
System.out.println(cols[0]);*/
Scanner s = new Scanner(new File("file1.csv"));
Scanner w = new Scanner (new File("file.csv"));
while (w.hasNextLine())
{
String line1 = w.nextLine();
System.out.println(cols);
//cols[row]=line1.split(",");
row ++;
if(!w.hasNextLine()){
while (s.hasNextLine()){
String line2 = s.nextLine();
//cols1[row1]=line2.split(",");
//put while loop in diffrent method but break
if(cols[j].equals(cols1[row1]))
{
j++;
row1++;
System.out.print(cols[j]);
System.out.print(" ");
System.out.print(cols1[row1]);
System.out.println();
}else{
row1++;
}
}
}
}
}
}
Instead of using arrays for cols and cols1, you should use List<String[]>. Also, your code is very confusing because you have the comparison loop(s?) intertwined with the reading loops. It would be better to simply read in the data first and then do your comparisons.
public static void main(String [] args)
{
List<String[]> cols;
List<String[]> cols1;
try {
cols = readFile("udc.csv");
cols1 = readFile("Watford Update File.csv");
} catch (IOException e) {
e.printStackTrace();
return;
}
// loop through array lists to do your comparisons
// For example, to compare the first column of rows i and j:
// cols.get(i)[0].equals(cols1.get(j)[0])
}
private static List<String[]> readFile(String fileName) throws IOException
{
List<String[]> values = new ArrayList<String[]>();
Scanner s = new Scanner(new File("udc.csv"));
while (s.hasNextLine()) {
String line = s.nextLine();
values.add(line.split(","));
}
return values;
}
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]);
}
}