I am doing a social security program where you take apart a SS #, remove the hyphens (-), and parse the 3 parts into integers and add up.
Here is the main runner:
import static java.lang.System.*;
public class SocialRunner
{
public static void main( String args[] )
{
Social social = new Social("1-1-1");
//add test cases
//social.Social("1-1-1");
//social.chopAndAdd();
//boolean check = stringlivesmatter.checkEquality();
out.println(social);
}
}
And here is the main program:
import static java.lang.System.*;
public class Social
{
private String socialNum;
private String ssNum1, ssNum2, ssNum3, sub;
private int sum;
public Social()
{
}
public Social(String soc)
{
socialNum = soc;
}
public void setWord(String w)
{
/*String ssNum1 = socialNum.substring(0,socialNum.indexOf("-"));
String ssNum2 = socialNum.substring(socialNum.indexOf("-")+1,socialNum.indexOf("-"));
String ssNum3 = socialNum.substring(socialNum.indexOf("-")+1,socialNum.indexOf("-"));
*/
}
public void chopAndAdd()
{
sub = socialNum;
ssNum1 = socialNum.substring(0,socialNum.indexOf("-"));
ssNum2 = socialNum.substring(socialNum.indexOf("-")+1,socialNum.lastIndexOf("-"));
ssNum3 = socialNum.substring(socialNum.lastIndexOf("-")+1,0);
sum = Integer.parseInt(ssNum1) + Integer.parseInt(ssNum2) + Integer.parseInt(ssNum3);
}
public String toString()
{
sum = Integer.parseInt(ssNum1) + Integer.parseInt(ssNum2) + Integer.parseInt(ssNum3);
/*
String ssNum1 = socialNum.substring(0,socialNum.indexOf("-"));
String ssNum2 = socialNum.substring(socialNum.indexOf("-")+1,socialNum.indexOf("-"));
String ssNum3 = socialNum.substring(socialNum.indexOf("-")+1,socialNum.indexOf("-"));
sum = Integer.parseInt(ssNum1) + Integer.parseInt(ssNum2) + Integer.parseInt(ssNum3);
*/
return "SS# " + socialNum + " has a total of " + sum + "\n";
}
}
With the way the two programs above are written, I am given a runtime error:
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at Social.toString(Social.java:46)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at SocialRunner.main(SocialRunner.java:20)
If I comment/delete:
sum = Integer.parseInt(ssNum1) + Integer.parseInt(ssNum2) + Integer.parseInt(ssNum3);
from
public String toString()
I get:
SS# 1-1-1 has a total of 0
How can I avoid a runtime or logic error?
You only need to remove the dashes to get your number.
public void chopAndAdd()
{
String con = socialNum.replaceAll("-", "");
sum = Integer.parseInt(ssNum1) ;
}
You probably may need to modify this as well
public String toString()
{
this.chopAndAdd();
return "SS# " + socialNum + " has a total of " + sum + "\n";
}
and
public static void main( String args[] )
{
Social social = new Social("1-1-1");
social.chopAndAdd();
out.println(social.toString(););
}
Take your time go through and analyse very well to your understanding
Change your constructor in Social as follows so that the ssNum variables are actually set.
public Social(String soc)
{
socialNum = soc;
String[] chunks = soc.split("-");
ssNum1 = chunks[0];
ssNum2 = chunks[1];
ssNum3 = chunks[2];
}
Using String.split will break up the ssn into a String[3], each element of which will contain the numbers excluding what you split on, in this case hyphens.
e.g. [123, 12, 1234]
Then all you need to do is parse them and sum them up.
public static void main(String[] args)
{
String socialString = "123-12-1234";
System.out.println(chopAndAdd(socialString));
}
public static int chopAndAdd(String s)
{
String[] chunks = s.split("-");
int first = Integer.parseInt(chunks[0]);
int second = Integer.parseInt(chunks[1]);
int third = Integer.parseInt(chunks[2]);
return first + second + third;
}
Related
I get some result from an external command (semi-api) and want to parse the result.
I'm only interested in the last few lines of the result.
How can get the last x lines of a string in Java?
Here's a simple solution:
public static List<String> getLastLines(String string, int numLines) {
List<String> lines = Arrays.asList(string.split("\n"));
return new ArrayList<>(lines.subList(Math.max(0, lines.size() - numLines), lines.size()));
}
A solution that gives the result without parsing the whole string:
/**
* Created by alik on 3/31/17.
*/
public class Main {
// TODO: Support other EndOfLines, like "\r\n".
// One way is to just replace all "\r\n" with "\n" and then run the #getLastLines method.
public static List<String> getLastLines(String string, int numLines) {
List<String> lines = new ArrayList<>();
int currentEndOfLine = string.length();
if (string.endsWith("\n")) {
currentEndOfLine = currentEndOfLine - "\n".length();
}
for (int i = 0; i < numLines; ++i) {
int lastEndOfLine = currentEndOfLine;
currentEndOfLine = string.lastIndexOf("\n", lastEndOfLine - 1);
String lastLine = string.substring(currentEndOfLine + 1, lastEndOfLine);
lines.add(0, lastLine);
}
return lines;
}
#Test
public void test1() {
String text = "111\n" +
"222\n" +
"333\n" +
"444\n" +
"555\n" +
"666\n" +
"777\n";
List<String> lastLines = getLastLines(text, 4);
Assert.assertEquals("777", lastLines.get(lastLines.size() - 1));
Assert.assertEquals(4, lastLines.size());
}
#Test
public void test2() {
String text = "111\n" +
"222\n" +
"333\n" +
"444\n" +
"555\n" +
"666\n" +
"777";
List<String> lastLines = getLastLines(text, 4);
Assert.assertEquals("777", lastLines.get(lastLines.size() - 1));
Assert.assertEquals(4, lastLines.size());
}
}
* Link to github gist
Algorithm
Split input text with line break character and save as a list lines
If number of lines required, linesRequired is less than size of lines, ie, lineCount
Then return sublist of lines starting from lineCount - linesRequired to lineCount.
Otherwise, throw exception or return all lines based on the requrement.
Sample Implementation
private static final String SEPARATOR = "\n";
public static List<String> getLastLines(String string, int numLines) {
List<String> lines = Arrays.asList(string.split(SEPARATOR));
int lineCount = lines.size();
return lineCount > numLines ? lines.subList(lineCount - numLines, lineCount) : lines;
}
Here is another possible solution:
public class LastNLines {
public static List<String> getLastNLines(String inputString, int n) {
if(n < 0) {
return new ArrayList<>();
}
String[] tmp = inputString.split("(\\n|\\r)+");
if(n < tmp.length) {
return Arrays.asList(Arrays.copyOfRange(tmp, tmp.length - n, tmp.length));
}
return Arrays.asList(tmp);
}
public static void main(String[] args) {
String myExample =
" \n\r\r\n\nsome_text_1 " +
"\n" +
"some_text_2\n\n" +
"\n" +
" some_text_3\n\r " +
"\n" +
"some_text_4\n" +
"\n" +
"some_text_5\n\n\n";
List<String> result = LastNLines.getLastNLines(myExample, 2);
System.out.println(result.toString());
}
}
This one splits by multiple new lines at once, so a text like this \n\n\n\n\n will contain no Strings after splitting and the result will be empty.
Java 8 Streams (memory friendly) answer.
Code:
public class Main
{
public static void main( String[] args )
{
String rawData = "John\n\nDavid\nGeorge\nFrank\nTom";
Pattern pattern = Pattern.compile("\\n");
System.out.println( lastN( pattern.splitAsStream( rawData ),4));
System.out.println( lastN( pattern.splitAsStream( rawData ),40));
}
public static <T> List<T> lastN( Stream<T> stream, int n )
{
Deque<T> result = new ArrayDeque<>( n );
stream.forEachOrdered( x -> {
if ( result.size() == n )
{
result.pop();
}
result.add( x );
} );
return new ArrayList<>( result );
}
}
I am trying to read in this input:
processcount 2 # Read 2 processes
runfor 15 # Run for 15 time units
use rr # Can be fcfs, sjf, or rr
quantum 2 # Time quantum – only if using rr
process name P1 arrival 3 burst 5
process name P2 arrival 0 burst 9
end
My job is to only parse in the values and not the words, and to keep out the comments (#).
Here is the main file:
public class main {
static String[] token = new String[10];
static List<Schedule> p;
public static void schedule()
{
for(Schedule c: p)
{
System.out.println("ProcessInfo: " + c.getProcess().processName);
System.out.println("count: " + c.getProcessCount());
System.out.println("quant: " + c.getQuantum());
System.out.println("runtime: " + c.getRunTime());
System.out.println("Type: " + c.getType());
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
// sc = new Scanner(new File("processes.in"));
p = new ArrayList<>();
while(sc.hasNextLine() && !sc.equals("end"))
{
token = sc.nextLine().replace(" ","-").replace("#", "-").split("-");
System.out.println(token[0].toString());
if(!token[0].startsWith("#") || !sc.nextLine().startsWith("end"))
{
Schedule s = new Schedule();
int pCount=0, runfor=0, quantum=0, arrival=0, burst=0;
String type = null, pName = null;
if(token[0].startsWith("processcount"))
{
s.setProcessCount(Integer.parseInt(token[1]));
System.out.println(Integer.parseInt(token[1] +""));
}
else if(token[0].startsWith("runfor"))
{
s.setRunTime(Integer.valueOf(token[1].toString()));
System.out.println(Integer.parseInt(token[1]) +"");
}
else if(token[0].startsWith("use"))
{
s.setType(token[1].toString());
System.out.println(token[1] +"");
}
else if(token[0].startsWith("quantum"))
{
s.setQuantum(Integer.valueOf(token[1].toString()));
System.out.println(token[1] + "");
}
else if(token[0].startsWith("process"))
{
Processes pl = new Processes();
pl.setProcessName(token[2]);
System.out.println(token[2]+ "");
pl.setArrivalTime(Integer.valueOf(token[4].toString()));
System.out.println(""+ Integer.valueOf(token[4]));
pl.setBurstTime(Integer.valueOf(token[6].toString()));
System.out.println("" + token[6]);
s.setProcess(pl);
// add info
p.add(s);
}
else if(token[0].startsWith("end"))
{
schedule();
}
}
}
}
}
Here is the Schedule:
public class Schedule {
int processCount;
int runTime;
String type;
int quantum;
Processes process;
public int getProcessCount() {
return processCount;
}
public void setProcessCount(int processCount) {
this.processCount = processCount;
}
public int getRunTime() {
return runTime;
}
public void setRunTime(int runTime) {
this.runTime = runTime;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getQuantum() {
return quantum;
}
public void setQuantum(int quantum) {
this.quantum = quantum;
}
public Processes getProcess() {
return process;
}
public void setProcess(Processes p) {
process = p;
}
}
Here is the Process:
public class Processes {
String processName;
int arrivalTime;
int burstTime;
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public int getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(int arrivalTime) {
this.arrivalTime = arrivalTime;
}
public int getBurstTime() {
return burstTime;
}
public void setBurstTime(int burstTime) {
this.burstTime = burstTime;
}
}
Here is the output I am getting with my code:
ProcessInfo: P1
count: 0
quant: 0
runtime: 0
Type: null
ProcessInfo: P2
count: 0
quant: 0
runtime: 0
Type: null
why am I getting returned wrong results?
There's couple of issue here. You create a new schedule at each iteration of your while loop; you don't get all the relevant values of your current line before the new iteration plus you have couple of useless variables right after you create a new Schedule() which override the previously collected values.
Also, you use toString on a String element of your array which is meaningless. Personnaly I don't try not to use filters and you don't really need any for this. Always try to KISS(Keep It Simple Stupid)
Here's how I'll go about it without using filters.
public static void main (String args [])
{
// Will help us identify the key words
String current_token;
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
//Remove spaces at the beginning and end of the string
input = input.trim();
Schedule s = new Schedule();
// New source for the scanner
sc =new Scanner(input);
p = new ArrayList<>();
while(sc.hasNext())
{
current_token = sc.next();
if(current_token.equals("end"))
{schedule(); break;}
switch(current_token)
{
case "processcount":
s.setProcessCount(sc.nextInt());
System.out.println(s.getProcessCount()+ " ");
break;
case "runfor":
s.setRunTime(sc.nextInt());
System.out.println(s.getRuntime +" ");
case "use":
s.setType(sc.next());
System.out.println(s.getType() +" ");
break;
case "quantum":
s.setQuantum(sc.nextInt());
System.out.println(s.getQuantum + " ");
break;
case "process":
Processes pl = new Processes();
pl.setProcessName(sc.next());
System.out.println(pl.GetProcessName()+ " ");
pl.setArrivalTime(sc.nextInt());
System.out.println(" "+ pl.getArrivalTime());
pl.setBurstTime(sc.nextInt());
System.out.println(" " + pl.getBurstTime());
s.setProcess(pl);
// add info
p.add(s);
break;
default:
// the current_token is not what we are looking for
break;
}
}
}
You're having an issue because of the way you split the string. The way you have right now first replaces each space with a dash. For example, the string
"processcount 2 # a comment"
would become
"processcount-2---#-a-comment"
and then splitting that gives you an empty string between every pair of dashes, so you'll end up with
token = ["processcount", "2", "","", ... etc]
I suggest that you do this:
String str = (sc.nextLine().split("#"))[0]; //get the string before the pound sign
str = str.trim(); //remove the leading/trailing whitespace
token = str.split("\\s+"); //split the string by the whitespaces
public enum TrafficLight {
RED(20),
YELLOW(3),
GREEN(10);
int duration;
TrafficLight(int newDuraction) {
duration = newDuraction;
}
public int getDuraction() {
return duration;
}
in the test class it's like:
public class TrafficLightTest {
public static void main(String[] args) {
for (TrafficLight trafficLight : TrafficLight.values()) {
System.out.println(trafficLight.name() + ": duraction " + trafficLight.getDuraction());
}
}
}
and i would like for example: "GREEN: duraction 10 " the number 10 to be like "**********".
10 = "**********" (ten asterisks)
3 = "***" (three asterisks)
i hope you get the idea. Thanks :)
Just use a for loop for printing "*" the required number of times
System.out.print(trafficLight.name() + ": duraction " ); //change this to Print instead of println
for(int i=0;i<trafficLight.getDuraction();i++)
System.out.print("*");
System.out.println();
Hope that helps.
You could do something like :-
public class TrafficLightTest {
public static String getAsteric(int input){ // return * using the int input
StringBuilder sb = new StringBuilder();
for(int i =0 ; i< input; i++)
sb.append("*");
return sb.toString();
}
public static void main(String[] args) {
for (TrafficLight trafficLight : TrafficLight.values()) {
System.out.println(trafficLight.name() + ": duraction " + TrafficLightTest.getAsteric(trafficLight.getDuraction())); // prints * equal to int input
}
}
}
This program is supposed to chop up and add together social security numbers. I thought I wrote all of the code correctly, but when I ran the code it outputted the java.lang.NumberFormatException error. I am using Eclipse and it doesn't show which line of the code has the error so I don't know what to fix. Here are the two classes of code I am working with:
MAIN CLASS:
import static java.lang.System.*;
public class social
{
private String socialNum;
private int sum;
public social()
{
setWord("");
}
public social(String soc)
{
setWord(soc);
}
public void setWord(String w)
{
socialNum = w;
}
public void chopAndAdd()
{
String sub1 = socialNum.substring(0, socialNum.indexOf("-"));
String sub2 = socialNum.substring(socialNum.indexOf("-") + 1, socialNum.lastIndexOf("-"));
String sub3 = socialNum.substring(socialNum.indexOf("-") + 1);
int int1 = Integer.parseInt(sub1);
int int2 = Integer.parseInt(sub2);
int int3 = Integer.parseInt(sub3);
sum = int1 + int2 + int3;
}
public String toString()
{
return "SS# " + socialNum + " has a total of " + sum + "\n";
}
}
RUNNER CLASS:
import static java.lang.System.*;
public class socialrunner
{
public static void main( String args[] )
{
//add test cases
social test = new social("456-56-234");
test.chopAndAdd();
System.out.println(test);
test.setWord("1-1-1");
test.chopAndAdd();
System.out.println(test);
test.setWord("182-2-12");
test.chopAndAdd();
System.out.println(test);
test.setWord("0-0-0");
test.chopAndAdd();
System.out.println(test);
}
}
Thanks for any help~!
Error is due to the line
String sub3 = socialNum.substring(socialNum.indexOf("-") + 1);
The code
socialNum.substring(socialNum.indexOf("-") + 1)
returns 56-234, which is not an Integer. This causes the NumberFormatException when it tries parse this into an Int.
Change that line to,
String sub3 = socialNum.substring(socialNum.lastIndexOf("-") + 1);
It will remove the error.
The line
String sub3 = socialNum.substring(socialNum.indexOf("-") + 1);
makes the value of sub3 as "56-234" as the socialNum is "456-56-234".
Therefore Integer.parseInt method cannot parse a String with a "-" in it and thus throwing exception.
If you are receiving a NumberFormatException, you are trying to transform something that is not a number into a number.
Debug to see what you're getting on these lines:
int int1 = Integer.parseInt(sub1);
int int2 = Integer.parseInt(sub2);
int int3 = Integer.parseInt(sub3);
I'm having problems getting my program to read an input file from the same directory.
code is in Main, included the whole just incase i have done something outside of main that is causing this.
import java.io.*;
import java.util.*;
public class Final
{
public static int readData(BusinessDirectory [] array, Scanner input,Scanner inputFile)
{
int lastChar = 0;
int count =0;
int dirChoice = 0;
int area,
exchange,
number,
extension;
String name;
while(inputFile.hasNextLine() && count < array.length)
{
String Og = inputFile.nextLine();
lastChar = (Og.length()-1);
dirChoice = Integer.parseInt(Og.substring(0,1));
if(dirChoice == 1)
{
area = Integer.parseInt(Og.substring(2,5));
exchange = Integer.parseInt(Og.substring(6,9));
number = Integer.parseInt(Og.substring(10,14));
name = Og.substring(15,lastChar);
array[count].DirectorySet(area, exchange, number, name);
}
if(dirChoice == 2)
{
area = Integer.parseInt(Og.substring(2,5));
exchange = Integer.parseInt(Og.substring(6,9));
number = Integer.parseInt(Og.substring(10,14));
extension = Integer.parseInt(Og.substring(15,19));
name = Og.substring(20,lastChar);
array[count].BusinessDirectorySet(area, exchange, number, extension, name);
}
}
return count;
}
public static void main(String[]args)throws IOException
{
String infile;
int count=0;;
//Directory[]array = new Directory[25];
BusinessDirectory[]array = new BusinessDirectory[25];
Scanner in = new Scanner(System.in);
System.out.print("What is the input file: ");
infile = in.next();
try
{
File inputFile = new File(infile);
Scanner fin = new Scanner(inputFile);
readData(array, in, fin);
System.out.println(BusinessDirectory.getName());
// System.out.println("test");
//count = readData(array,in,inputFile);
}
catch(Exception e)
{
System.out.println("\"" + infile + "\" not found. Program will terminate.");
System.exit(0);
}
}
}
it always throws the Exception from the Catch.
("test.txt" not found. Program will terminate.)
e.printStackTrace();
gets me
What is the input file: test.txt
java.lang.NullPointerException
"test.txt" not found. Program will terminate.
at Final.readData(Final.java:36)
at Final.main(Final.java:69)
Error seems to be in my Directory Class
public class Directory
{
//data members
static int Area;
static int Exchange;
static int Number;
static String Name;
static int cause;
public Directory()
{
Area = 999;
Exchange = 999;
Number = 9999;
Name = "";
cause = 0;
}
public Directory(int area, int exchange, int number, String name)
{
DirectorySet(number, number, number, name);
}
public void DirectorySet(int area, int exchange, int number, String name)
{
try
{
if(area >= 200 && area <= 999 && area != 911)
{
if(exchange >= 200 && exchange <= 999 && exchange !=911)
{
if(number >= 0 && number <= 9999)
{
Area = area;
Exchange = exchange;
Number = number;
Name = name;
}else
{
cause = 1;
MyOwnException error = new MyOwnException();
MyOwnException.Message = error.setMessage(cause);
throw error;
}
}else if(exchange == 911 || area == 911)
{
cause = 4;
MyOwnException error = new MyOwnException();
MyOwnException.Message = error.setMessage(cause);
throw error;
}
cause = 2;
MyOwnException error = new MyOwnException();
MyOwnException.Message = error.setMessage(cause);
throw error;
}else
{
cause = 3;
MyOwnException error = new MyOwnException();
MyOwnException.Message = error.setMessage(cause);
throw error;
}
}
catch(MyOwnException error)
{
System.out.println(toString());
System.out.println(MyOwnException.Message);
//System.out.println(Directory.toString());
}
}
public void toString(int area, int exchange, int number, String name)
{
System.out.println(name + " (" + area + ") " + exchange + " -" + number);
}
public String toString()
{
return (Name + " (" + Area + ") " + Exchange + " -" + Number);
}
public static String getName()
{
return Name;
}
public static int getArea()
{
return Area;
}
public static int getExchange()
{
return Exchange;
}
public static int getNumber()
{
return Number;
}
public void setName(String name)
{
Name = name;
}
public void setArea(int area)
{
Area = area;
}
public void setExchange(int exchange)
{
Exchange = exchange;
}
public void setNumber(int number)
{
Number = number;
}
}
..
Final.readData(Final.java:37)
array[count].DirectorySet(area, exchange, number, name);
Final.main(Final.java:73)
readData(array, fin);
Your NullPointerException seems to be thrown at this line :
array[count].DirectorySet(area, exchange, number, name);
The problem is that you correctly created the array this way :
BusinessDirectory[]array = new BusinessDirectory[25];
But that creates only the space for 25 object pointers, that doesn't actually creates 25 objects.
You have to create each object one by one, in your case you should probably do this :
array[count] = new Directory(area, exchange, number, name);
instead of this :
array[count].DirectorySet(area, exchange, number, name);
Also you don't seem to increment count anywhere.
Try:
File inputFile = new File(infile);
System.out.println(inputFile.getAbsolutePath());
This will give you a hint about your working directory and you can fix your input (absolute or relative paths)
Also it is recommended that if you're not sure about the relative location and do not wish to use absolute paths, use the File.exists() API to make a decision within your code.