I have a csv file that is formatted as follows:
1,,3,4
3,4,,0
2,,4,2
I'm reading that file into a String variable called text. Then, doing this
String newText = text.replaceAll("","0");
In my output, it's replacing the no value elements with a 0 which is what I want, but it's also appending a 0 before and after the elements that do have a value.
010
0
030
040
030
040
0
000
020
0
040
020
Any helps is appreciated !
EDIT: Here is the rest of my code for clairification.
import java.lang.*;
public class DataMatrix {
private double[][] dMatrix;
public DataMatrix(String text) {
String[] line = text.split("\n");
// Creates an array for the CSV file
String[][] sMatrix = new String[line.length][];
for(int i=0; i < line.length; i++)
sMatrix[i] = line[i].split(",");
/*for(int j=0; j < sMatrix.length; j++) {
for(int x=0; x <= line.length; x++) {
if(sMatrix[j][x] !=*/
System.out.println("Original String: ");
for(int x=0; x < sMatrix.length; x++) {
for(int j=0; j <= line.length; j++) {
System.out.println(sMatrix[x][j]);
}
}
dMatrix = new double[sMatrix.length][];
System.out.println("Converted to double: ");
for(int x=0; x < sMatrix.length; x++) {
dMatrix[x] = new double[sMatrix[x].length];
for(int j=0; j <= sMatrix.length; j++) {
dMatrix[x][j] = Double.parseDouble(sMatrix[x][j]);
System.out.println(dMatrix[x][j]);
}
}
}
public void avgRowValue() {
double tempTotal = 0;
for(int x=0; x < dMatrix.length; x++) {
System.out.println("***********************************");
System.out.println("The average for row "+(x+1)+" is: ");
for(int i=0; i < dMatrix[x].length;i++) {
tempTotal += dMatrix[x][i];
double rowAvg = tempTotal / dMatrix[x].length;
System.out.println(rowAvg);
tempTotal = 0;
}
}
}
public void avgColValue() {
double tempTotal = 0;
for(int x=0; x < dMatrix[0].length; x++) {
System.out.println("**************************************");
System.out.println("The average for column "+(x+1)+" is: ");
for(int i=0; i <= dMatrix.length-1; i++)
tempTotal += dMatrix[i][x];
double colAvg = tempTotal / dMatrix.length;
System.out.println(colAvg);
tempTotal = 0;
}
}
public void overallAvgValue() {
double tempTotal = 0;
int count = 0;
for(int x=0; x < dMatrix.length; x++) {
for(int i=0; i <= dMatrix.length; i++) {
tempTotal += dMatrix[x][i];
count++;
}
}
double overallAvg = tempTotal / count;
System.out.println("The overall average for the data matrix is: "+overallAvg);
}
public void maxValue() {
double maxValue = 0;
for(int x=0; x < dMatrix.length; x++) {
for(int i=0; i <= dMatrix.length; i++) {
if(dMatrix[x][i] >= maxValue)
maxValue = dMatrix[x][i];
}
}
System.out.println("The max value for the data matrix is: "+maxValue);
}
public void minValue() {
double minValue = dMatrix[0][0];
for(int x=0; x < dMatrix.length; x++) {
for(int i=0; i <= dMatrix.length; i++) {
if(dMatrix[x][i] <= minValue)
minValue = dMatrix[x][i];
}
}
System.out.println("The min value for the data matrix is: "+minValue);
}
}
and my main:
import java.util.*;
public class Assignment1{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
//Make sure the user passed the command line argument - and nothing else
if (args.length != 1){
System.out.println("Assignment1 takes exactly one command-line argument.");
System.out.println("Usage: java Assignment1 some_file.csv");
System.exit(0);
}
String csvFileName = args[0];
//Instantiate my custom file reader
CSVReader fileReader = new CSVReader();
//Read the file into a string
String text = fileReader.readFile(csvFileName);
String newText = text.replaceAll("", "0");
//Create a new instance of DataMatrix that takes in String CSV file and converts to double array
DataMatrix matrix = new DataMatrix(newText);
boolean done = false;
while(done != true) {
System.out.println("**********************");
System.out.println("CSV Reader Menu: ");
System.out.println("1. Display the average values of each individual row.");
System.out.println("2. Display the averages value of each individual column.");
System.out.println("3. Display the average of the entire data matrix.");
System.out.println("4. Display the maximum value of the entire data matrix.");
System.out.println("5. Display the minimum value of the entire data matrix.");
System.out.println("0. Exit.");
int choice = input.nextInt();
switch(choice) {
case 1: matrix.avgRowValue();
break;
case 2: matrix.avgColValue();
break;
case 3: matrix.overallAvgValue();
break;
case 4: matrix.maxValue();
break;
case 5: matrix.minValue();
break;
case 0: done = true;
break;
default: System.out.println("Invalid input.");
break;
}
}//end of menu loop
}//end of main
}//end of class
With text.replaceAll("", "0") you are looking for all the places where there is a zero-length substring in the string. This is, for any string, between any two characters as well as at the beginning and at the end of the string.
"12345".replaceAll("", "_") // _1_2_3_4_5_
If you really want to use regex for this, you could use replaceAll("^$", "0"), where ^ and $ are the beginning and the end of the string, respectively. Alternatively, just check whether the string is empty:
String newText = text.isEmpty() ? "0" : text;
Example:
for (String s : "1,,23,4".split(",")) {
System.out.println(s.isEmpty() ? "0" : s); // prints 1, 0, 23, and 4
System.out.println(s.replaceAll("^$", "0"));// prints 1, 0, 23, and 4
}
If you want to insert those 0 into the original string, i.e. before using split, you could use a disjunction of different regexes for the start-of-string, mid-string, and end-of-string cases, using lookahead and lookbehind assertions, e.g. (?<=^|,) for "preceded by start-of-string or ,", and (?=,|$) for "followed by , or end-of-string":
String nums = ",1,,23,4,";
System.out.println(nums.replaceAll("(?<=^|,)(?=,|$)", "0"));
// output: 0,1,0,23,4,0
Or you could use capturing groups and group references in the replacement string to carry the , over into the replacement. Here, $10$2 means "1st group, then 0, then 2nd group":
System.out.println(nums.replaceAll("(^|,)(,|$)", "$10$2"));
i prefer to do this while reading from csv file , its cost is much less than doing it after reading csv file , so i make a csvreader and an array named Line , reading line by line from csv , and if the length of a string is bigger than 0 it written in this mode : 0thatstring0 , otherwise it written as 0
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
String [] Line;
while ((Line = reader.readNext()) != null) {
for(int i = 0 ; i < Line.length ; i++)
if(Line[i].length>0) System.out.println(Line[i]);
else System.out.println("0");
}
second method , i'm not offering it , is using split method and spliting each string with "," , do the replace method and it works
I suggest using a library such as OpenCSV to read that file, then replace the empty cells as you encounter them. It will be a lot more robust.
I understand that text contains the value of a single column, after you split the line based on commas. You want to change empty strings into "0".
The replaceAll() method takes a regex. An empty string is strange for a regex. What you want is text.replaceAll("^$", "0").
Related
I have a question about break the input, because my code is typing two times "-1" to stop the input, actually I want to type "-1" single time to stop the input and then to show the array output.
Below is my code:
import java.util.Scanner;
public class NewTMA {
public static float[][] clone(float[][] a) throws Exception {
float b[][] = new float[a.length][a[0].length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
b[i][j] = a[i][j];
}
}
return b;
}
public static void main(String args[]) {
Scanner sc = new Scanner (System.in);
System.out.println("enter row size");
int row = Integer.parseInt(sc.nextLine());
System.out.println("enter column size");
int column = Integer.parseInt(sc.nextLine());
System.out.println ("Type float numbers two-dimensional array of similar type and size with line break, end by -1:");
float[][] a = new float[row][column];
for (int i=0; i<row; i++) {
for (int j=0; j<column; j++) {
String line = sc.nextLine();
if ("-1".equals(line)) {
break;
}
a[i][j]=Float.parseFloat(line);
}
}
System.out.println("\n The result is:");
try {
float b[][] = clone(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.print(b[i][j] + " ");
}
System.out.println();
}
} catch (Exception e) {
System.out.println("Error!!!");
}
}
}
Below is my output:
run:
enter row size
3
enter column size
2
Type float numbers two-dimensional array of similar type and size with line breaks. end by -1:
1.4
2.4
-1
-1
The result is:
1.4 2.4
0.0 0.0
0.0 0.0
BUILD SUCCESSFUL (total time: 13 seconds)
Actually I just want to type "-1" a single time to stop the input,but I don't know why the output is showing "-1" twice to stop it. Hope someone can help me find which part I am doing wrong. Thanks.
break breaks out of the inner-most loop, so the outer loop iterates again and hits the input read again.
To break out of the outer loop, use a label:
outerLoop: // label the outer for loop
for (int i=0; i<row; i++){
for (int j=0; j<column; j++) {
String line = sc.nextLine();
if ("-1".equals(line)) {
break outerLoop; // break from the outer for loop
}
...
}
You can use any java allowable name for the label (I just called it “outerLoop” for clarity)
Another approach would be putting a flag as an indication if the argument is met:
for (int i=0; i<row; i++){
/* this is the flag */
boolean isInputNegative = false;
for (int j=0; j<column; j++){
String line = sc.nextLine();
if ("-1".equals(line)){
isInputNegative = true;
break;
}
a[i][j]=Float.parseFloat(line);
}
/* here is the checking part */
if (isInputNegative) {
break;
}
}
So, I'm writing a program that returns pyramids when you give a word as an input
for instance:
"Enter a word: "
Hello
Justification (L=left, R=Right)?
L
would print
H
ee
lll
llll
oooo
import java.util.Scanner;
public class Justification{
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
System.out.println("Enter a word: ");
String word=in.nextLine();
System.out.println("Justification (L=left, R=Right)?");
String Justification=in.nextLine();
if(Justification.equalsIgnoreCase("l")){
for (int i = 0; i < word.length(); i++) {
for (int j = 1; j <= i; j++) {
System.out.print(word.substring(i,i));
}
System.out.println();
}
}else if(Justification.equalsIgnoreCase("r")){
for (int i = word.length()-1; i >= 0; i--) {
for (int s = 0; s < i; s++) {
System.out.print(" ");
}
for (int j = word.length()-1; j >= i; j--) {
System.out.println(word.substring(i,i));
}
System.out.println("");
}
}else System.out.println("Bad input");
}}
You are using substring(begin,end) incorrectly. The character at the begin index is included while the character at the end index is not.
If the word is hello, and you call substring(2,4), it would be ll
String str = "hello".substring(2,4); //str is "ll"
One way to check if substring is used correctly is that endIndex-beginIndex=length of substring. In this case, 4-2=2, so the substring should contain 2 characters, which it does.
An easier way to print out the ith character is to use charAt(i) instead of substring(i,i+1);
System.out.println("hello".substring(0,1)); //prints h
System.out.println("hello".charAt(0)); //also prints h
I am trying to create a triangle pyramid of alternating "*" and "o" characters, with the number of rows being based on user input. The expected output I am trying to achieve, if the user inputs "6" for the number of rows, is:
*
*o*
*o*o*
*o*o*o*
*o*o*o*o*
*o*o*o*o*o*
The code I have written to achieve this is:
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
for (int j = 0; j < rows-i; j++){
System.out.print(star);
}
for (int k = 0; k <= i; k++){
System.out.print(circle);
}
System.out.println();
}
However, the output from my code does not match the pyramid above. The output of my code, with a user input of "6", is:
******o
*****oo
****ooo
***oooo
**ooooo
*oooooo
After spending the last three hours scouring both this website and others, I have still come up lost on how to alternate the characters, how to have the correct number of characters in each row, and how to format the pyramid as the expected output is. I don't know if my code is completely wrong, or if I am only missing a part to make it work correctly, but any advice or references is greatly appreciated.
You could approach it another, far simpler, way.
In pseudo code:
create a String of n spaces
add "*" to it
loop n times, each iteration of the loop:
print it
replace " *" with "*O*"
This recognises a simple way to create the first line, and a simple way to create the next line from the previous line. Each replacement will match only the last (leading) space and the first star, replacing the space with a star, the star with an O and adding a star.
Usually the best way to solve a hard problem is to look at it in a way that makes it a simple problem (or a collection of simple problems).
A couple of ways to create a String of n spaces:
A loop that adds ' ' each iteration
new String(new char[n]).replace('\0', ' ')
How to replace certain characters of a String with other characters:
str = str.replace(" *", "*O*");
This method will work fine:
public void printPyramid (int input) {
for (int row = 1; row <= input; row++) {
for (int whitespace = input - 1; whitespace >= row; whitespace--) {
System.out.print(" ");
}
System.out.print("*");
for (int circle = 1; circle < row; circle++) {
System.out.print("o*");
}
System.out.println();
}
}
*
*o*
*o*o*
*o*o*o*
*o*o*o*o*
*o*o*o*o*o*
*o*o*o*o*o*o*
*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
Welcome to Stack Overflow!
First, the "o"s and "*"s are not alternating because the for loops execute until completion. This means the stars and circles will print out separately. For this application you only need one for loop and two if statements based on whether the "i" in the for loop is odd or even. An easy way to do this is with the modulo function :
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
if ((i % 2) == 0)
{
System.out.print(circle);
}
else
{
system.out.print(star);
}
System.out.println();
}
See if that works.
Thanks!
Here is a solution, easy to understand and friendly for beginners.
(If you want to go more advanced, look at the solution from #Bohemian♦ )
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
// How many "o" do we need?
int count_circle = i;
// How many * do we need?
int count_star = count_circle + 1;
// Let's create the string with o and *
String output = "";
for(int j = 0; j < (count_circle + count_star); j++){
if(j % 2 == 0) // if it is odd
output = output + star;
else // if it is even
output = output + circle;
}
// Do we need spaces at the beginning?
String spaces = "";
for(int j = 0; j < rows - i - 1; j++){
spaces = spaces + " ";
}
// Final output
output = spaces + output;
System.out.println(output);
}
Try this.
Scanner in = new Scanner(System.in);
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; ++i) {
System.out.printf("%" + (rows - i) + "s", "*");
for (int j = 0; j < i; ++j)
System.out.print("o*");
System.out.println();
}
Ex:
If rows=3
*##
**#
***
class Main{
public static void main(String x[]){
Scanner scan=new Scanner(System.in);
int rows=scan.nextInt();
for(int i=1;i<rows;i++){
for (int j=0;j<i;j++)
{
System.out.print("*");
}
for (int j=rows;j>i;j--)
{
System.out.print("#");
}
System.out.println();
}
}
}
See if that works.
Thanks!
My program will output a graphical representation of some rows and columns. It asks the users to input the number of rows and columns they want to see the figure for. For example if the user chooses 4 rows and 3 columns, it should print a figure (let's say it's made up of character X) which has 4 rows and 3 columns.
The final output will look like this:
X X X
X X X
X X X
X X X
Now the problem is I can't set the logic in my for loop so that it makes the desired shape. I tried, but couldn't figure it out.
This what I have done so far:
package banktransport;
import java.util.*;
public class BankTransport {
static int NumOfRow;
static int numOfColum;
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
showRowCol(NumOfRow, numOfColum);
}
public static void showRowCol(int NumOfRow, int numOfColum) {
System.out.println("Enter row: ");
NumOfRow = input.nextInt();
System.out.println("Enter Col: ");
numOfColum = input.nextInt();
System.out.println("");
System.out.println("Visual Representation: ");
//print column and row
for (int i = 0; i < numOfColum; i++) {
System.out.print(" X ");
//System.out.println("");
//for(int j=1; j<(NumOfRow-1);j++){
// System.out.print(" Y ");
//}
}
System.out.println("");
}
}
Try a loop like this:
for ( int i = 0; i < numOfRow; i++ )
{
for ( int j = 0; j < numOfColum; j++ )
{
System.out.print(" X ");
}
System.out.println();
}
Try:
for (int i = 0; i < numOfRow; i++) {
StringBuilder line = new StringBuilder();
for (int j = 0; j < numOfColumn; j++) {
line.append("X ");
}
System.out.println(line.toString());
}
You can also use Apache Commons Lang StringUtils.repeat method (which would prevent you from having a trailing space at the end of the line):
for (int i = 0; i < numOfRow; i++) {
System.out.println(StringUtils.repeat("X", " ", numOfColumn));
}
This is a homework question so I would like help, not an answer.
I'm trying to create 2 triangles out of numbers based on a number entered by the user.
"Enter a number between 2-9: "3"
1
12
123
1
21
321
IE2:
"Enter a number between 2-9: "5"
1
12
123
1234
12345
1
21
321
4321
54321
I have been able to get the first triangle complete. But when I add my nested loop it messes up my first triangle with the numbers developed from the nested loop. It also puts all the numbers in a straight vertical line. I've tried variations for different nest loops and even tried messing with a StringBuilder, but was still unsuccessful.
Here's what I have in code so far:
import java.util.Scanner;
public class NestedLoops
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter a Number between 2-9: ");
int width = input.nextInt();
String r = "";
for (int i = 1; i <= width; i++)
{
r = r + i;
System.out.println(r);
}
}
}
Again, I'm looking for help/understanding and not just an answer.
There are two aspects the 2nd part of the question.
You need to generate strings with the numbers in the reverse order:
You could do this by adding the numbers at the other end.
You could do this by reversing the strings.
You need to arrange that there are spaces to the left.
You could do this by adding the required number of spaces to the left end of the string.
You could do this by using the System.out.format(...) with a template that right aligns the string in a field with the required number of characters. (OK, that's a bit too obscure ...)
Or, you can build the string in a character array or string builder rather than using string concatenation.
The "trick" is to figure out what strategy you are going to use ... before you start cutting code.
try
int width = 5;
// for all lines; number of lines = width
for (int line = 1; line <= width; line++) {
// print numbers from 1 to current line number
for (int n = 1; n <= line; n++) {
System.out.print(n);
}
// end of line
System.out.println();
}
// add empty line between triangles
System.out.println();
// for all lines; number of lines = width
for (int line = 1; line <= width; line++) {
// printing padding spaces, number of spaces = with - line number
int nSpaces = width - line;
for (int i = 0; i < nSpaces; i++) {
System.out.print(" ");
}
// print numbers from number of current line to 1
for (int n = line; n >= 1; n--) {
System.out.print(n);
}
// end of line
System.out.println();
}
Can you just add another loop after your first loop like
String r = "";
String space = "";
for (int i = width; i >= 1; i--)
{
r = r + i;
System.out.println(r);
}
Try it. not yet tested
You need to use a queue.
eg. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/LinkedList.html
Enque the numbers till you reach the max, and then start dequing them.
And while you dequeue, you need to apply the reverse
Queue<String> q = new LinkedList<String>();
for (int i = 1; i <= width; i++)
{
r = r + i;
q.add(r);
System.out.println(r);
}
while(!q.isEmpty()){
String j = q.remove();
//reverse j
System.out.println(reverse(j));
}
I leave the reversing part for you to do :)
public static void main(String[] args)
{
int n = 5;
for(int i=1; i<=n; i++)
{
for (int j=(n*2), k=n; j>1; j--)
{
if (k <= i)
{
System.out.print(k);
}
else
{
System.out.print('*');
}
k += (j)-1 > n ? -1 : 1;
}
System.out.println();
}
}
Just tried to implement in scala. Ignore if you don't like it..:-)
class Triangle extends App
{
val width = Console.readInt()
if (width < 2 || width > 9)
{
throw new RuntimeException()
}
var i, j = 1;
for (i <- 1 to width)
{
for (j <- 1 to i)
{
print(j)
}
print("\n")
}
for (i <- 1 to width)
{
for (dummy <- 1 to width-i)
{
print(" ")
}
for (j <- i to 1 by -1)
{
print(j)
}
print("\n")
}
}