I want to add data to a dataset to display some values on a graph. On some files, the first line is a description of the columns (like "Timestamp" or something else). I need my code to test if the first line contains integer or float values and if not to skip this line and add data to dataset from 2nd line.
This is my code:
for (int i = 0; i < listOfLists.size(); i++) {
for (int j = 1; j < listOfLists.get(i).size(); j++) {
if (listOfLists.get(i).get(0).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(0).matches("\\d+(?:\\.\\d+)?")) {
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
} else if(listOfLists.get(i).get(1).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(1).matches("\\d+(?:\\.\\d+)?")){
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
The problem is that I get an error when he's trying to represent String on the plot of the bar chart
List of lists is a list of columns. Each column of the file is added into a list and each list into the listOfLists.
I tried to use on the else if block: listOfLists.get(i).remove(0) but it didn't worked. (in next loops it keeped removing the first line of the remaining list.
Thanks in advance!
You can check in the outer loop, before inner loop:
if (i == 0 && listOfLists.get(i).get(0).matches(/\\d+(?:[\\.,]\\d+)?)/) == false) {
continue; // skip first line
}
BTW: You should not call remove method while iterating list because you will get ConcurrentModificationException.
It could be something like this:
for (int i = 0; i < listOfLists.size(); i++) {
for (int j = 0; j < listOfLists.get(i).size(); j++) {
if (j==0){ // Only test if it is a string in position [0]
boolean isNumber = listOfLists.get(i).get(0).matches("\\d+(?:\\,\\d+)?") || listOfLists.get(i).get(0).matches("\\d+(?:\\.\\d+)?");
if (!isNumber) continue; // If it is not a number, skip it
}
// Add to database, because it is a number
datasetBar.addValue(Float.parseFloat(listOfLists.get(i).get(j).replace(",",".")),columnsLabel[i].getText(), ""+listOfLists.get(0).get(j));
Hope it will help anyone to understand.
for(int i = 0; i < n; i++){ /* i = 0 means position of i is 0 which is 1st line */
if(i != 0 ){ /* and as our purpose is skipping first line so I will only continue when i is not equal 0 like this we can skip first line in this if block */
continue;
}
}
Related
Given a String, I want to create a frequency distribution of characters in the String. That is, for each distinct character in the string, I want to count how many times it occurs.
Output is a String that consists of zero or more occurrences of the pattern xd, where x is a character from the source String, and d is the number of occurrences of x within the String. Each x in the output should occur once.
The challenge is to do this without using an array or Collection.
Examples:
Source: "aasdddr" Result: "a2s1d3r1"
Source: "aabacc" Result: "a3b1c2"
Source: "aasdddraabcdaa" Result: "a6s1d4r1b1c1"
I tried this way:
String str = "aasdddr", result = "";
int counter = 0;
for(int i = 0; i < str.length(); i++){
result += "" + str.charAt(i);
for(int j = 1; j < str.length(); j++){
if(str.charAt(i) == str.charAt(j)){
counter++;
}
}
result += counter;
}
System.out.println(result);
My output is a1a2s3d6d9d12r13
Finally, I found the solution. But I think any question has more than one solution.
First, we should declare an empty string to keep the result. We use a nested loop because the outer loop will keep a character fixed during each iteration of the inner loop. Also, we should declare a count variable inside the outer loop. Because in each match, it will be increased by one and after controlling each character in the inner loop, it will be zero for the next check. Finally, after the inner loop, we should put a condition to check whether we have that character inside the result string. If there isn't any character like that, then it will be added to the result string. After that, its frequency (count) will be added. Outside of the loop, we can print it.
public class FrequenciesOfChar {
public static void main(String[] args) {
String str = "aabcccd"; // be sure that you don't have any digit in your string
String result = ""; // this will hold new string
for (int i = 0; i < str.length(); i++) { // this will hold a character till be checked by inner loop
int count = 0; // put here so that it can be zero after each cycle for new character
for (int j = 0; j < str.length(); j++) { // this will change
if(str.charAt(i) == str.charAt(j)){ // this will check whether there is a same character
count++; // if there is a same character, count will increase
}
}
if( !(result.contains(""+str.charAt(i))) ){ // this checks if result doesn't contain the checked character
result += ""+str.charAt(i); // first if result doesn't contain the checked character, character will be added
result += count; // then the character's frequency will be added
}
}
System.out.println(result);
}
}
Run Result:
aabcccd - a2b1c3d1
First, counter needs to be reset inside the for loop. Each time you encounter a character in the source String, you want to restart the counter. Otherwise, as you have seen, the value of the counter is strictly increasing.
Now, think about what happens if a character occurs in more than one place in the source String, as in the "aasdddraabcdaa" example. A sequence of 1 or more a appears in 3 places. Because, at the time you get to the 2nd occurrence of a, a has been previously counted, you want to skip over it.
Because the source String cannot contain digits, the result String can be used to check if a particular character value has already been processed. So, after fixing the problem with counter, the code can be fixed by adding these two lines:
if (result.indexOf (source.charAt(i)) >= 0) {
continue; }
Here is the complete result:
package stackoverflowmisc;
public class StackOverflowMisc {
public static String freqDist(String source) {
String result = "";
int counter ;
for (int i = 0; i < source.length(); i++) {
if (result.indexOf (source.charAt(i)) >= 0) { continue; }
counter = 1;
result += source.charAt(i);
for (int j = 1; j < source.length(); j++) {
if (source.charAt(i) == source.charAt(j)) {
counter++;
}
}
result += counter;
}
return result;
}
public static void main(String[] args) {
String [] test = {"aasdddr", "aabacc", "aasdddraabcdaa"};
for (int i = 0; i < test.length; ++i) {
System.out.println (test[i] + " - " + freqDist (test[i]));
}
System.out.println ("End of Program");
}
}
Run results:
aasdddr - a2s2d4r2
aabacc - a3b2c3
aasdddraabcdaa - a6s2d5r2b2c2
End of Program
In one of the Q&A comments, you said the source string can contain only letters. How would the program work if it were allowed to contain digits? You can't use the result String, because the processing inserts digits there. Again, this is an easy fix: Add a 3rd String to record which values have already been found:
public static String freqDist2(String source) {
String result = "", found = "";
int counter ;
for (int i = 0; i < source.length(); i++) {
if (found.indexOf (source.charAt(i)) >= 0) { continue; }
counter = 1;
result += source.charAt(i);
found += source.charAt(i);
for (int j = 1; j < source.length(); j++) {
if (source.charAt(i) == source.charAt(j)) {
counter++;
}
}
result += counter;
}
return result;
}
Another possibility is to delete the corresponding characters from the source String as they are counted. If you are not allowed to modify the Source String, make a copy and use the copy.
Comment: I don't know if this is what your professor or whomever had in mind by placing the "No array" restriction, because a String is essentially built on a char array.
I have a 2d string array for displaying a seating plan.
String seating[][] = {{"XX", "02", "03","04","XX","06","07","08","09"},
{"10", "11", "12","13","XX","15","16","17","18"},
{"19", "20", "21","22","23","24","25","26","27"}};
What I am looking to do is search though the array for an available space, not already marked by 'XX', and then assign 'XX' to that space to show it as taken.
I know you can use a nested for loop to search though the array and display element inside the array however, I am struggling to understand how I can insert a new element to mark the spot as taken. I am quite new to programming so any help would be greatly appreciated. Thanks.
Note that you are not adding a value to the 2D array here, (arrays' lengths are fixed anyway) you are just setting the value of an element of the 2D array.
As you know, this is how you loop through a 2D array:
for (int i = 0 ; i < seating.length ; i++) {
for (int j = 0 ; j < seating[i].length ; j++) {
}
}
Inside the loop, seating[i][j] is the element that we are checking. We want to check if this is not occupied:
if (!seating[i][j].equals("XX"))
If it is not occupied, we set it to occupied:
seating[i][j] = "XX";
Don't forget to stop the loop after you found a seat with a break;! Since we want to break out of the outer loop, you need to mark the outer loop with a label.
Full code:
outer: for (int i = 0 ; i < seating.length ; i++) {
for (int j = 0 ; j < seating[i].length ; j++) {
if (!seating[i][j].equals("XX")) {
seating[i][j] = "XX";
break outer;
}
}
}
You could also add a boolean variable to check for whether a seat is successfully occupied:
boolean seatFound = false;
outer: for (int i = 0 ; i < seating.length ; i++) {
for (int j = 0 ; j < seating[i].length ; j++) {
if (!seating[i][j].equals("XX")) {
seating[i][j] = "XX";
seatFound = true;
break outer;
}
}
}
if (seatFound) {
// a seat was successfully occupied!
} else {
// the seats were already all full!
}
I am reading in a file in which each row has a column no, row number, detail. The file is sorted on column then row. I want to place the detail in a csv file in the correct row and column. So I am testing for change in row number and then add in line breaks ("\n").
The issue is that the System.out.println on each side of the for loop is being displayed in the log; however, the loop its self is not triggered (i.e., the line break is not added and the System.out.println is not appearing in the log.
The code is:
System.out.println("New row - " + Integer.parseInt(report.getReportDetailRow())+ " greater than current row - " + currentRow);
currentCol = 0;
//Add line breaks
int j = Integer.parseInt(report.getReportDetailRow());
for(int i = currentRow; i > j; i++){
System.out.println("Append line break");
fileContent.append("\n");
}
System.out.println("After append");
currentRow = Integer.parseInt(report.getReportDetailRow());
if (currentCol == Integer.parseInt(report.getReportDetailColumn())){
fileContent.append(report.getReportDetailDetails() + ",");
currentCol++;
}else{
//Add columns
for(int i = currentCol; i == Integer.parseInt(report.getReportDetailColumn()); i++){
fileContent.append(",");
}
fileContent.append(report.getReportDetailDetails() + ",");
currentCol = Integer.parseInt(report.getReportDetailColumn());
}
Please note that I have use "i > j" instead of "i == j" to try to force a result.
In your statement for iterating through the rows, you have
for(int i = currentRow; i > j; i++)
If j is the number of current rows, then you need to change your condition to i < j to go through them all.
for(int i = currentRow; i > j; i++) {
System.out.println("Append line break");
fileContent.append("\n");
}
The loop above would either result in an infinite loop or never get triggered(your case)
Infinite if i is already greater than j. It would never terminate with i++ for every iteration
Never execute if i is less than j, since the condition states i>j.
You might want to change the conditional statement inside the loop to correct this to either i==j or i<j
for(int i = currentRow; i == j; i++) // in which case replacing this with an `if(i==j)` would do the needful
or
for(int i = currentRow; i < j; i++) // to iterare from initial i upto j
I have a 2D array and it's like a maze.
So I loop through the first row to see if there is a zero (This zero is the opening) and then I go down to see if there is another zero below that zero.
The problem is that after the first 2 rows I don't know how I can write code to check left,right or down of that zero and move there and continue until I cannot do so any longer.
import java.util.Scanner;
public class AssignmentTwo
{
//int[rows][columns]
int[][] gasCavern = {{1,1,1,1,1,0,1},
{1,0,0,1,1,0,1},
{1,1,1,0,0,0,1},
{1,1,0,0,1,1,1},
{1,0,1,0,1,0,1},
{1,0,1,0,0,0,1},
{0,0,0,1,1,1,0},
{1,1,1,0,0,0,1}};
int counter = 0;
boolean checked = false;
// forLoop that deals with the first 2 rows.
// First check 1st row for a zero.
// Then check down and increment counter which ultimately shows area.
for(int column = 0; column < gasCavern[0].length; column++)
{
//Checking for opening in 1st row
if(gasCavern[0][column]== 0)
{
counter++;
gasCavern[0][column] = 2;
if(gasCavern[1][column]==0)
{
counter++;
}
}
}
for(int i=1; i<gasCavern.length; i++)
{
for(int j=0; j < gasCavern.length; j++)
{
if(gasCavern[i][j])
{
//Looking left
if(gasCavern[i][j-1]==2)
{
gasCavern[i][j-1]=2;
counter++;
}
//Looking Right
if(gasCavern[i][j+1]==2)
{
gasCavern[i][j+1]=2;
counter++;
}
//Looking up
if(gasCavern[i+1][j]==2)
{
gasCavern[i+1][j]=2;
counter++;
}
//Looking down
if(gasCavern[i-1][j]==2)
{
gasCavern[i-1][j]==2
counter++;
}
}
}
}
public boolean checkedForZeros()
{
//If returning false,go through while loop again
}
}
This is the code I have so far. In case I wasn't clear this is what I want to happen:
http://imgur.com/YOr86xs
I think with a bit more thought you would have got it!
Think about it, all you have to do is check the adjacent elements in the row you are looking at, which are just the columns in each side. Therefore:
[column+1]
Would check the element to the right, and:
[column-1]
Would check the element to the left.
Just be sure you don't accidentally go out of bounds.
EDIT: Let us know how you get on, if you are still struggling, I will provide more code, but try first.
This should work:
for (int x = 0; x < gasCavern.length; x++) {
for (int y = 0; y < gasCavern[x].length; y++) {
int num = gasCavern[x][y];
if (num == 0) {
// if it is a zero
} else {
// if it's not a zero (a one)
}
}
}
I want to loop infinitely using a for loop if a number equals 0, and loop until that number number if the number is greater than 0. Here's the code to help visual what I'm getting at.
for (int i = 0; i < this.getNumRounds(); i++) {
// 30 some lines of code
}
or
for ( ; ; ) {
// 30 some lines of code
}
if getNumRounds() is greater than 0, do the first loop, if it equals 0, do the second. I would prefer to do this without copying and pasting my 30 some lines of code twice and using an if statement seeing as the code is redundant, though I could use a function to take out that redundancy, but I'm looking to see if there's another option.
Use the powerful ternary operator:
for (int i = 0; this.getNumRounds() == 0 ? true : i < this.getNumRounds(); i++) {
// 30 some lines of code
}
As noted in the comments by yshavit, there is a shorter, cleaner way of expressing this:
for (int i = 0; this.getNumRounds() == 0 || i < this.getNumRounds(); i++) {
// 30 some lines of code
}
Have you thought about using a while loop instead?
int i = 0;
while(i < this.getNumRounds() || this.getNumRounds() == 0) {
//some 30 lines code
i++
}
So you want something like this:
int num = //whatever your number equals
if (num == 0) {
boolean running = true;
while (running) {
doLoop();
}
} else {
for (int i = 0; i < num; i++) {
doLoop();
}
}
private void doLoop() {
//some 30 lines of code
}
This code puts the contents of the loop in a separate method and checks if the number is equal to 0. If it is, the program runs the doLoop() method forever. Otherwise, it runs until i equals the number.
While it would be better to just create a method and use an if-statement you could add an if statement inside the for-loop to decrease i every iteration. It would look like:
for (int i = 0; i <= this.getNumRounds(); i++) {
if(this.getNumRounds() == 0){
i--;
}
// 30 some lines of code
}
Notice I changed i < this.getNumRounds() to i <= this.getNumRounds. This way if the number of rounds is zero then the loop will be called.
You could do the following.
for (int i = 0; i < this.getNumRounds() || i == 0; ++i) {
do {
// 30 lines of code
} while (this.getNumRounds() == 0);
}
If getNumRounds is non-trivial to compute, consider pulling it out of the loop and calling it only once.