I have a code that basically reads from a text file. There is a leading plus sign when it outputs because the answer is printed in a loop. How do I get rid of that singular leading plus sign? All I can think to do is to convert the ENTIRE THING to a string and then take out the first three indexes but that's way too complicated. Is there a simple way to just rearrange the logic and do it?
My code:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package importtextfiles;
/**
*
* #author Hana
*/
import java.io.*;
import java.util.*;
public class InputNumData {
public static void main(String args[]) throws IOException
{
Scanner sf = new Scanner(new File("C:\\Users\\Hana\\SkyDrive\\CompSci\\Programming\\importTextFiles\\meow.txt"));
int maxIndx = -1; //so the first index is 0
String text[] = new String[1000];
while(sf.hasNext()){
maxIndx++;
text[maxIndx] = sf.nextLine();
System.out.println(text[maxIndx]);
}
sf.close();
String answer = "";
int sum;
for(int j=0; j<=maxIndx; j++){
Scanner sc = new Scanner(text[j]);
sum = 0;
answer = "";
while(sc.hasNext()){
int i = sc.nextInt();
answer = answer + " + " + i;
sum = sum + i;
}
answer = answer + " = " + sum;
System.out.println(answer);
}
}
}
My output:
run:
12 10 3 5
18 1 5 92 6 8
2 9 3 22 4 11 7
+ 12 + 10 + 3 + 5 = 30
+ 18 + 1 + 5 + 92 + 6 + 8 = 130
+ 2 + 9 + 3 + 22 + 4 + 11 + 7 = 58
BUILD SUCCESSFUL (total time: 0 seconds)
meow.txt:
12 10 3 5
18 1 5 92 6 8
2 9 3 22 4 11 7
Just change this line to
answer = answer.isBlank() ? i : answer + " + " + i;
For more details on how it works refer this.
Take your while loop, and fix the first value:
//Set up first value
int i = sc.nextInt(); //might want to check for hasNext() here
answer = i;
sum = sum + i;
while(sc.hasNext())
{
i = sc.nextInt();
answer = answer + " + " + i;
sum = sum + i;
}
First thing is not to use concatenation in a loop. Something like:
String result = ""
for (...) {
result = result + "some additonal data";
}
Creates several intermediate string objects and that's bad practice. It should be replaced with:
StringBuilder sb = new StringBuilder();
for (...) {
sb.append( "some additional data" );
}
result = sb.toString();
Which allows you to add strings without creating a new string object until you have finished appending.
Now that we are using a StringBuilder, you can have several solutions to the initial plus problem. The first, which would also work with the non-recommended string concatenation, is to keep a flag that tells you if this is the "first operand". Change your while loop to:
StringBuilder sb = new StringBuilder();
boolean firstOperand = true;
while(sc.hasNext()){
int i = sc.nextInt();
if ( firstOperand ) {
firstOperand = false;
} else {
sb.append( " + " );
}
sb.append( i );
sum = sum + i;
}
answer = sb.toString();
Another way, which is possible with a StringBuilder is to remove the extra " + " after you finish the loop. In this case, it's better to add the " + " after each operand, so that the extra one will be at the end. It's more efficient to delete from the end of a StringBuilder than from its beginning:
StringBuilder sb = new StringBuilder();
while(sc.hasNext()){
int i = sc.nextInt();
sb.append( i ).append( " + " );
sum = sum + i;
}
if ( sb.length() > 0 ) {
sb.setLength( sb.length() - 3 );
}
answer = sb.toString();
Related
I wasn't able to figure this one out since I don't know how to calculate "inserting" an underscore. I included my attempt at solving this problem.
Given a string, do not let the same character repeat for n positions. If it does repeat, insert an underscore to push
it X positions down. The final output needed is just the total number of characters.
Example 1) Input "QQ",2 becomes "Q__Q", the return value is 4.
Example 2) Input "ABCA",2 becomes "ABCA" (no spaces needed), total characters is 4.
Example 3) Input "DEDEE", 1 becomes "DEDE_E", total chars is 6.
Example 4) Input "JKJK", 2 becomes "JK_JK", total characters is 5 (The toughest example).
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
// int shift = 0;
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
System.out.println(i + "=" + letter + " last saw " + hm.get(word.charAt(i)));
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
System.out.println(i + "-" + hm.get(letter) + "<=" + spaces);
if (i - hm.get(word.charAt(i)) <= spaces) {
// System.out.println("add " + (spaces + 1 - (i - hm.get(letter))));
// shift += (spaces + 1) - (i - hm.get(letter));
word = word.substring(0, i) + "_" + word.substring(i);
System.out.println(i + " word=" + word);
}
hm.put(letter, i); // update the hashmap with the last seen again
}
}
return word.length();
}
}
Your question is (mainly) about inserting underscores. A key insight that can help move forward is that the input and output strings are different, so it would be cleaner to treat them as such, using a StringBuilder for example. Additionally, it doesn't hurt at this stage to use temporary variables to capture concepts such as distance between characters. Leveraging these two ideas, you can have more self-explanatory code, for example:
public static String space(String input, int spaces) {
HashMap<Character, Integer> map = new HashMap<>();
StringBuilder result = new StringBuilder();
for( char symbol : input.toCharArray() ) {
int position = result.length();
int lastPosition = map.getOrDefault(symbol, position-spaces-1);
int distance = position - lastPosition -1;
for( int j = 0; j < Math.max( spaces - distance, 0) ; j++ ) {
result.append('_');
}
result.append(symbol);
map.put(symbol, result.length()-1);
}
return result.toString();
}
(and once this is mastered and digested, it's of course possible to in-line the temps)
The requirement doesn't ask you to display the constructed string so we need to only do calculations. The regex (.+)\1 will match any repetition of 1 or more chars and countPattern returns how many times that pattern was found.
public static void main(String[] args) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 6"); //in becomes JK__JK, ie. 4 + 2x'_'
}
private static int spacey(String word, int spaces) {
if(spaces<0){
throw new IllegalArgumentException("should be positive value");
}
if(word==null){
return 0;
}
if(spaces==0){
return word.length();
}
final Pattern repeatedCharRegex = Pattern.compile("(.+)\\1");
final int repetitions = countPattern(word, repeatedCharRegex);
return word.length() + repetitions*spaces;
}
public static int countPattern(String references, Pattern referencePattern) {
Matcher matcher = referencePattern.matcher(references);
int count = 0;
while (matcher.find()){
count++;
}
return count;
}
First of all you have an error in one of your test cases. Assuming you want to reproduce the cases in the quoted challenge, you need a 1 as second argument to the call to spacey here:
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
// ^ ^
The formula to calculate the number of underscores to insert is:
previousindex + n + 1 - i
...where previousindex is the index at which the current letter occurred before, and i is the current index.
You can repeat an underscore with the .repeat string method. Don't forget to update i afterwards, so it keeps pointing to the currently processed character (which moved forward).
So your code could work like this:
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
int underscores = hm.get(letter) + spaces + 1 - i;
if (underscores > 0) { // Need to add underscores
word = word.substring(0, i) + "_".repeat(underscores) + word.substring(i);
i += underscores; // update i so it still points to the current character
}
hm.put(letter, i);
}
}
return word.length();
}
}
This question already has answers here:
Java: sum of two integers being printed as concatenation of the two
(10 answers)
Closed 5 years ago.
Code:
class Foo
{
public static void main(String[] args)
{
int x[] = new int[5];
for(int i=0;i<5;i++)
x[i]=i*i;
for(int i=0;i<5;i++)
{
System.out.println("Value #" + i+1 + " = " + x[i]);
}
}
}
The Output:
tk#insomniac-tk:~$ java Foo
Value #01 = 0
Value #11 = 1
Value #21 = 4
Value #31 = 9
Value #41 = 16
So, what's going on here? Where am I messing up my java code? I mean why is it that in Java, the i+1 means literally i concat 1?
public class Foo
{
public static void main(String[] args)
{
int x[] = new int[5];
for(int i=0;i<5;i++)
x[i]=i*i;
for(int i=0;i<5;i++)
{
System.out.println("Value # " + (i+1) + " = " + x[i]);
}
}
}
try this
In Strings the + operator is used for concatenate, so because you did not specidy any parenthesis, your i and 1 are also concatentate, you need to use parenthesis to explicitly tell that they to be sum together :
for (int i = 0; i < 5; i++) {
System.out.println("Value #" + (i + 1) + " = " + x[i]);
}
To get :
Value #1 = 0
Value #2 = 1
Value #3 = 4
Value #4 = 9
Value #5 = 16
Next to that, another way using IntStream, which will do same :
IntStream.range(0, 5)
.mapToObj(i -> "Value #" + (i + 1) + " = " + (i * i))
.forEach(System.out::println);
The + means something like concat, if you want the expression to be evaluated put it into brackets
(i + 1) not i + 1
This line:
System.out.println("Value #" + i+1 + " = " + x[i]);
And in particular
"Value #" + i+1 + " = " + x[i]
Is syntactic sugar for the following code:
new StringBuffer().append("Value #")
.append(i)
.append(1)
.append(" = ")
.append(x[i])
.toString();
What you want is this:
"Value #" + (i+1) + " = " + x[i]
Which would translate to
new StringBuffer().append("Value #")
.append(i+1)
.append(" = ")
.append(x[i])
.toString();
Because in this case, Java append i to your String, then 1 to your String.
To evaluate the value first (and produce the result you are expecting here), you have to inform Java that you want to evaluate the value before it is appended, using parenthesis:
System.out.println("Value #" + (i+1) + " = " + x[i]);
Output
Value #1 = 0
Value #2 = 1
Value #3 = 4
Value #4 = 9
Value #5 = 16
The key reason the Java and C++ programs differ is because the operators used are different:
System.out.println("Value #" + i+1 + " = " + x[i]); // Java
cout << "Value # " << i + 1 << " = " << x[i] << endl; // C++
The + operator has a higher precedence and hence the addition is done before the overloaded << operator.
In the Java version it is all +s and so they are all evaluated left to right.
problem is in system.out.println("");,where all integers will concatinate into string when added using(+) with a string variable .Try different code for different operations with integer and string variables.
You cannot simply add an integer into a string. You must convert an integer to a string with Integer.toString(int),then add the returned value to the string.
I wrote a program for my Computer Science class where it reads a file and imports the data and then just adds the numbers but it seems to be adding an extra addition sign.
import java.io.*; //necessary for File and IOException
import java.util.*; //necessary for Scanner
public class Tester
{
public static void main( String args[] ) throws IOException
{
Scanner sf = new Scanner(new File("/Volumes/DVLUP Flash/Numbers.txt"));
int maxIndx = -1; //-1 so when we increment below, the first index is 0
String text[] = new String[1000]; //To be safe, declare more than we
while(sf.hasNext( ))
{
maxIndx++;
text[maxIndx] = sf.nextLine( );
//System.out.println(text[maxIndx]); //Remove rem for testing
}
sf.close();
for(int j =0; j <= maxIndx; j++)
{
Scanner sc = new Scanner(text[j]);
}
String answer = ""; //We will accumulate the answer string here.
int sum; //accumulates sum of integers
for(int j = 0; j <= maxIndx; j++)
{
Scanner sc = new Scanner(text[j]);
sum = 0;
answer = "";
while(sc.hasNext())
{
int i = sc.nextInt();
answer = answer + i + " + ";
sum = sum + i;
}
//sc.next();
answer = answer + " = " + sum;
System.out.println(answer);
}
}
}
The output is
12 + 10 + 3 + 5 + = 30
18 + 1 + 5 + 92 + 6 + 8 + = 130
2 + 9 + 3 + 22 + 4 + 11 + 7 + = 58
There's an extra after the last number, how do I fix that?
After the last iteration you are having an "extra" plus sign because that´s the way you are printing it. You are ending the String with a + as it can be seen in your while loop.
to change it either add the + before the value as
if(sc.hasNext()) {
int i = sc.nextInt();
answer = i + "";
sum += i;
while(sc.hasNext())
{
i = sc.nextInt();
answer = answer + " + " + i;
sum = sum + i;
}
}
Or if you use Java 8 you could use the StringJoiner as
StringJoiner joiner = new StringJoiner(" + ");
while(sc.hasNext())
{
i = sc.nextInt();
// This automaticly includes a " + " between the values.
joiner.add(String.valueOf(i));
sum = sum + i;
}
After
while(sc.hasNext())
{
int i = sc.nextInt();
answer = answer + i + " + ";
sum = sum + i;
}
put
answer = answer.substring(0, answer.length()-1);
One option would be to conditionally prepend a plus sign before appending each number in any case other than the first number:
answer = "";
while(sc.hasNext()) {
int i = sc.nextInt();
if (answer.length() > 0) {
answer += " + ";
}
answer = answer + i;
sum = sum + i;
}
I am having an incredibly difficult time trying to figure out why I am getting this error.
When I use a driver file to test the program it fails horribly.
Here's my code:
import java.util.Scanner;
import java.lang.Math.*;
public class Histogram
{
private int[] arrayData;
private int[] arrayRange;
private final int LOW = 1;
private final int HIGH = 100;
public Histogram()
{
int[] arrayData = new int[11];
}
public void getInput()
{
int[] arrayRange = new int[11];
for(int count = 1; count < arrayRange.length; count++)
{
arrayRange[count] = count * 10;
}
Scanner input = new Scanner(System.in);
System.out.println("Enter numbers from 1 to 100, Type -999 to quit.");
int nextNumb = input.nextInt();
while(nextNumb != -999)
{
if(nextNumb >= LOW && nextNumb <= HIGH)
{
for(int i = 0; i <= arrayRange.length; i++)
{
if(nextNumb > arrayRange[i] && nextNumb <= arrayRange[i+1])
arrayData[i]++;
}
nextNumb = input.nextInt();
}
else arrayData[10]++;
nextNumb = input.nextInt();
}
}
public String starPrint(double count)
{
String star = "";
count = (Math.round(count) / 5);
for(int i = 1; i <= count; i++)
{
star = star + "*";
}
return star;
}
public String toString()
{
String results = " Range | Histogram" + "\n";
results = results + "1 - 10 | " + starPrint(arrayData[0]) + "\n";
results = results + "11 - 20 | " + starPrint(arrayData[1]) + "\n";
results = results + "21 - 30 | " + starPrint(arrayData[2]) + "\n";
results = results + "31 - 40 | " + starPrint(arrayData[3]) + "\n";
results = results + "41 - 50 | " + starPrint(arrayData[4]) + "\n";
results = results + "51 - 60 | " + starPrint(arrayData[5]) + "\n";
results = results + "61 - 70 | " + starPrint(arrayData[6]) + "\n";
results = results + "71 - 80 | " + starPrint(arrayData[7]) + "\n";
results = results + "81 - 90 | " + starPrint(arrayData[8]) + "\n";
results = results + "91 - 100 | " + starPrint(arrayData[9]) + "\n";
results = results + "Outliers: " + starPrint(arrayData[10]) + "\n";
return results;
}
}
I believe that the problem is in my getInput method
right here to be precise:
if(nextNumb > arrayRange[i] && nextNumb <= arrayRange[i+1])
arrayData[i]++;
I have no idea what's wrong with it though I am a beginner programmer and couldn't find a solution to this particular problem.
Thanks for any help you're able to give!
public Histogram()
{
int[] arrayData = new int[11];
}
You're shadowing your arrayData field in the constructor. This is creating a local variable with the same name as your class's arrayData field, initializing it, then immediately discarding it. When you try to use the field later in your code, it's null. Get rid of the int[] part.
Note that your next exception will be an ArrayIndexOutOfBoundsException ... you should look at your loop ;)
this: for(int i = 0; i <= arrayRange.length; i++)
wont work since you are trying to access arrayRange[i] and arrayRange[i+1]
which dont exists for i = arrayRange.length-1 and further
so change it to:
for(int i = 0; i < arrayRange.length-1; i++)
I'm working on a program to calculate heat index, and am supposed to make heavy use of foreach loops. However, when I print to the terminal, it doesn't come out right. I've already spent two days on this, but I still cannot find out why it's still doing this. Thanks for any help/advice!
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class HeatIndex {
public static void main(String[] args) throws IOException {
Scanner keyWestHumidScan = new Scanner(new File("KeyWestHumid.txt"));
Scanner keyWestTempScan = new Scanner(new File("KeyWestTemp.txt"));
int counter1 = 0;
int counter2 = 0;
double[] keyWestHumid = new double[12];
double[] keyWestTemp = new double[12];
String header1 = " Heat index: Key West, Florida ";
String header2 = "\n Months \n ";
String[] months = {" Jan ", "Feb ", "Mar ", "Apr ", "May ", "Jun ", "Jul ", "Aug ", "Sep ", "Oct ", "Nov ", "Dec ", "Avg \n"};
String header3 = "*****************************************************************************************";
String temp = "Temp (F) ";
String humid = "Hudimitiy (%) ";
String heatIndexHeader = "HI (F) ";
//read keyWestHumid into array
while (keyWestHumidScan.hasNext()) {
String data1_parse = keyWestHumidScan.next();
double data1 = Double.parseDouble(data1_parse);
keyWestHumid[counter1] = data1;
counter1++;
}
//read keyWestTemp into array
while (keyWestTempScan.hasNext()) {
String data2_parse = keyWestTempScan.next();
double data2 = Double.parseDouble(data2_parse);
keyWestTemp[counter2] = data2;
counter2++;
}
System.out.println(header1);
System.out.print(header2);
for (String headData : months) {
System.out.print(headData);
}
System.out.println(header3);
System.out.print(temp);
for (double data : keyWestTemp) {
System.out.print(keyWestTemp + " ");
}
System.out.println();
System.out.print(humid);
for (double data : keyWestHumid) {
System.out.print(keyWestHumid + " ");
}
System.out.println();
System.out.print(heatIndexHeader);
counter1 = 0;
counter2 = 0;
for (int counter3 = 0; counter3 <= 12; counter3++) {
double heatIndex = (-42.379 + (2.04901523 * keyWestTemp[counter1]) + (10.14333127 * keyWestHumid[counter2]) - (0.22475541 * keyWestTemp[counter1] * keyWestHumid[counter2]) - (0.00683783 * (keyWestTemp[counter1] * keyWestTemp[counter1])));
heatIndex = heatIndex + (-0.05481717 * (keyWestHumid[counter2] * keyWestHumid[counter2]) + (0.00122874 * (keyWestTemp[counter1] * keyWestTemp[counter1] * keyWestHumid[counter2])) + 0.00085282 * keyWestTemp[counter1] * (keyWestHumid[counter2] * keyWestHumid[counter2]) - (0.00000199 * (keyWestTemp[counter1] * keyWestTemp[counter1]) * (keyWestHumid[counter2] * keyWestHumid[counter2])));
counter1++;
counter2++;
counter3++;
System.out.print(heatIndex + " ");
}
}
}
You are printing out the collection of objects, and not the individual objects themselves. For instance: for (double data : keyWestTemp) { System.out.print(keyWestTemp + " ");
}
Should actually be: for (double data : keyWestTemp) {
System.out.print(data + " ");
}
To start, your code is pretty hard to read. Make sure you are following good code style (indent 4 spaces inside a for loop block, for example). Read through this: http://www.oracle.com/technetwork/java/codeconv-138413.html
From glancing through your code, could the porblem be here:
for(double data:keyWestTemp) {
System.out.print(keyWestTemp + " ");
}
and here:
for(double data:keyWestHumid) {
System.out.print(keyWestHumid + " ");
}
I think you want to be using data in the print line, instead of keyWestHumid/Temp. data is the object, keyWestHumid/Temp is your whole array.
You should really be using an IDE such as Eclipse or Netbeans, it will make your life much easier. Right away Eclipse tells you that data isn't used in these loops, which is a problem.
Use System.out.printf to format your text to be displayed on the console.
System.out.printf("%10s%10s", "Number", "String");
System.out.println("");
System.out.printf("%10d", 10);
System.out.printf("%10s", "Hi there");